#charset "us-ascii"
#include <adv3.h>
#include <en_us.h>
#include <charset.h>
#include "AHA.h"

/*
 *   Our game credits and version information.  This object isn't required 
 *   by the system, but our GameInfo initialization above needs this for 
 *   some of its information.
 *
 *   IMPORTANT - You should customize some of the text below, as marked: the 
 *   name of your game, your byline, and so on.  
 */
versionInfo: GameID
    IFID = 'cd03d4a8-f39b-ae69-693d-5fddc65f6dd8'
    name = 'All Hope Abandon'
    byline = 'by Eric Eve'
    htmlByline = 'by <a href="mailto:eric.eve@hmc.ox.ac.uk">
        ERIC EVE</a>'
    version = '4'
    authorEmail = 'ERIC EVE <eric.eve@hmc.ox.ac.uk>'
    desc = 'Your day got off to a good enough start when you met that blonde in
        the breakfast queue, but it\'s all downhill from there: you may be
        wishing you could escape a particularly dire lecture,  but not by the
        one way the lecture has just declared impossible. For suddenly, you are
        lurched into limbo, apparently to experience the after-life at first
        hand. What will you find there: heaven, hell, or the blonde you met at
        breakfast?'
    htmlDesc = 'Your day got off to a good enough start when you met that
        blonde in the breakfast queue, but it\'s all downhill from there: you
        may be wishing you could escape a particularly dire lecture,  but not
        by the one way the lecture has just declared impossible. For suddenly,
        you are lurched into limbo, apparently to experience the after-life at
        first hand. What will you find there: heaven, hell, or the blonde you
        met at breakfast?'
    
    cYear = '2005--2012' // copyright year (used by license.t)
    
    showCredit()
    {
        /* show our credits */
        "TADS 3 language and library by Michael J.\ Roberts.\b
        Cquotes library extension by Stephen Granade.\b
        Pasttense and Autosave library extensions by Michel Nizette.\b
        License text by Roger Firth.\b
        Beta testing by Nikos Chantziaras, Ian Haberkorn, Michel Nizette,
        Chris Odhner, Aaron Reed, John <q>Doppler</q> Schiff and Andreas Sewe
        -- a great team who have contributed magnificently to the development
        of this game. ";
        
        /* 
         *   The game credits are displayed first, but the library will 
         *   display additional credits for library modules.  It's a good 
         *   idea to show a blank line after the game credits to separate 
         *   them visually from the (usually one-liner) library credits that 
         *   follow.  
         */
        "\b";
    }
    showAbout()
    {
        "<i>All Hope Abandon</i>, my second released work of IF, is a game in
        which not everything is as it may seem at first sight, particularly
        when it comes to some of the stranger-looking puzzles.\b
        There are several ways of reaching a less than optimal ending in
        <i>All Hope Abandon</i>, but it is not otherwise meant to be possible
        to get the game into an unwinnable state (except in one endgame path in
        which the consequences of a particular decision may not become apparent
        for a few turns, but you can then use the RETRY command to return to
        the decision point).\b
        Scoring is provided as a rough indication of progress through the
        game, not as an objective in itself. There are two different paths
        through one part of the game, and this may result in your reaching the
        optimal ending with more or less than the official maximum (because,
        for example, you started on one path, but then followed the other). It
        is possible to complete the game with anything from 18 to 28 points;
        the notional maximum of 20 assumes a fairly economical traversal of the
        game, the highest score is achievable only by probing every possible
        path as far as possible before committing to one of them. \b        
        The protagonist of this story has specialist knowledge that most
        players will probably not share. He will normally deploy this where
        it's needed, but if you wish to share in some of it, you can use the
        THINK ABOUT command (e.g. THINK ABOUT EMPTY TOMB). Often this will only
        supply background information or an explanation of some allusion in the
        story text (which you may or may not find of interest), but on occasion
        it may help you make more sense of something, and if all else fails, it
        may be the most useful thing to do. There is, however, no need to THINK
        ABOUT every possible object and topic mentioned (that would quickly
        become tedious); instead use it where your curiosity is piqued or where
        you think it could prove useful. You can also simply use the command
        THINK (which will respond with more general thoughts pertaining to your
        current situation). Note that neither THINK ABOUT nor THINK is intended
        as a hint system, (for which use the <<hintCmd()>> command) but that
        either command may be abbreviated to TH.<.p>";
        
        if(gAction && gActionIs(About))  
            "For help on playing the game type <<aHref('HELP', 'HELP', 'Get help
                on playing All Hope Abandon')>>. First time-players and players
            new to TADS 3 games are particularly recommended to consult the
            interface <<aHref('FEATURES', 'FEATURES','Explain game interface
                features')>> menu.";       
        
    }
    hintCmd()
    {
        if(gAction && gActionIs(About)) 
            "<<aHref('HINT', 'HINT', 'Give me a hint')>>";
        else
            "HINT";
    }
;


/*
 *   The "gameMain" object lets us set the initial player character and 
 *   control the game's startup procedure.  Every game must define this 
 *   object.  For convenience, we inherit from the library's GameMainDef 
 *   class, which defines suitable defaults for most of this object's 
 *   required methods and properties.  
 */
gameMain: GameMainDef
    /* the initial player character is 'me' */
    initialPlayerChar = me
    
    /* 
     *   Show our introductory message.  This is displayed just before the 
     *   game starts.  Most games will want to show a prologue here, setting 
     *   up the situation for the player, and show the title of the game.  
     */
    showIntro()
    {
        cquoteOutputFilter.aggressive = true; 
        gExitLister.enableReminderAlways = true;
        gExitLister.roomDescVerbose = true;
        
        cls();
        "The conference organizers must have been really scraping the barrel
        when they invited Professor Wortschlachter as a keynote speaker. Until
        you saw the conference programme you'd never heard of him, and from
        what the handout has to say about him you can see why. You're
        subjecting yourself to his lecture through a general sense of
        obligation (or, at least, fear of appearing less enthusiastic than the
        other delegates), but your expectations are not high. So far,
        Wortschlachter has triumphantly fallen short of them. \b";                  
    }
    
    setAboutBox()
    {
        "<ABOUTBOX>
        <CENTER>
        <<versionInfo.name.toUpper()>>\b
        <<versionInfo.byline>>\b
        Version <<versionInfo.version>>\b       
        </CENTER>
        </ABOUTBOX>";
    }
    
    /* 
     *   Show the "goodbye" message.  This is displayed on our way out, 
     *   after the user quits the game.  You don't have to display anything 
     *   here, but many games display something here to acknowledge that the 
     *   player is ending the session.  
     */
    showGoodbye()
    {
        "<.p>Thanks for playing!\b";
    }
    
    newGame()
    {
        local startOption;
        
        cquoteOutputFilter.aggressive = true;
        
        /* try restoring the global defaults */
        settingsManager.restoreSettings(); 
        
        startOption = startupOptions();
        
        if(!sessionHintStatus.hintsDisabled)
            helpMenu.contents += topHintMenu;
        
        if(startOption == 'r')
        {
            statusLine.showStatusLine();
            
            runGame(nil);
        }
        else if(startOption != 'q')
        {
            statusLine.showStatusLine();
            
            /* show the introduction */
            showIntro();
            
            /* run the game, showing the initial location's full description */
            runGame(true);
        } 
        /* show the end-of-game message */
        showGoodbye();
    }
    
    startupOptions()
    {
        
        if(!sessionObj.showStartupOptions)
            return nil;     
        
        sessionObj.showStartupOptions = nil;  
        local res;
        do
        {
            cls();
            "<b><<versionInfo.name>></b> <<versionInfo.byline>>; 
            version <<versionInfo.version>> (<<versionInfo.releaseDate>>)\b";
            
            "Press <b>I</b> for instructions (recommended for new players).\b
            Press <b>R</b> to restore an existing saved game.\b
            Press <b>Q</b> to quit.\b
            Press any other key to start a new game.\b"; 
            
            res = inputManager.getKey(nil, nil);
            switch(res)
            {
            case 'i': case 'I':
                helpMenu.display(); break;
                
            case 'r': case 'R':
                cls();
                if(RestoreAction.askAndRestore())
                    return 'r';
                else
                    "\bRestore failed -- beginning game from start.\b"; 
                return nil;
                
            case 'q': case 'Q':
                libMessages.confirmQuit();
                if (yesOrNo())
                    return 'q';
                break;             
                
                default: break;
            }
        } while(res is in ('i', 'I', 'r', 'R', 'q', 'Q'));
        return nil;
    } 
    
    maxScore = 28
    allVerbsAllowAll = nil
    usePastTense = nil
    symmetry = nil
;

transient sessionObj:object
    showStartupOptions = true;
;

modify hintManager
    disableHints()
    {
        inherited;
        helpMenu.contents -= topHintMenu;
    }
;

me: Person
    /* the initial location */
    location = lectureRoomChair
    posture = sitting    
    desc()
    {
        if(isIn(lectureRoom))
            "You're in your early thirties, but you firmly believe that you
            look younger. In your more honest moments, however, you have to
            admit that you're not exactly as fit as you might be. You are
            dressed quite formally for the occasion, in a dark jacket and
            tie.";
        else if(isIn(breakfastQueue))
            "You were decently dressed, more or less awake, and in clear need
            of several cups of tea. ";
        else if(isIn(hospital))
            "You are dressed in a pair of hospital pyjamas and feeling rather
            weak. You suspect you probably don't look too great either.";
        else
            "You look somewhat insubstantial. And to make things worse, 
            you have now taken on a deathly pallor. ";
    }
    dobjFor(SmileAt)
    {
        verify() { 
            if(gActor == self)
                illogicalSelf('That would {look|have looked} rather foolish. ');
        }
    }    
    dobjFor(ThrowAt)
    {
        verify() {
            if(gActor == self)
                illogicalSelf('You never did get the hang of throwing yourself
                    at things. ');
            else
                inherited;
        }
    }   
    iobjFor(ThrowAt)
    {
        verify()
        {
            if(gActor == self)
                illogicalSelf('Throwing things at yourself is totally pointless. ');
            else
                inherited;
        }
    }
    dobjFor(ThrowDir)
    {
        verify()
        {
            if(gActor == self)
                illogicalSelf('You never did get the hang of throwing yourself
                    anywhere. ');
        }
    }
    dobjFor(TalkTo)
    {
        verify() {
            if(gActor == self)
                illogicalSelf('{You\'re} not so far gone that {you/he}
                    {need|needed} to start doing that. ');
            else
                inherited;
        }
    }
    goToSleep()
    {
        switch(getOutermostRoom)
        {
        case lectureRoom:
            "As much as this would be preferable to listening to Professor
            Wortschlachter, other people would be sure to notice, which
            might not exactly enhance your academic reputation. "; break;
        case hospital:
            "You've only just woken up! "; break;
        case oblivionChamber:
        case footOfSlope:    
            if(posture != lying)   
                tryImplicitAction(LieDown);  
            "You do feel a bit sleepy, so you doze off for a while. When you
            eventually wake up again, you find that nothing has changed. ";
            break;
        case breakfastQueue:
            "It was a bit early in the day for that; you'd only just
            got up. "; break;
        default:
            "Sleep does not seem to be a possibility in these regions. ";
        }
    } 
    
    //   inventoryLister: actorInventoryLister {
    //     showInventoryWearingOnly(parent, wearing)
    //     {
    //         if(lexicalParent.isIn(breakfastQueue))
    //           "You were carrying nothing, and were wearing <<wearing>>. ";
    //         else 
    //           inherited(parent, wearing);
    //     }
    //   }
    breathe()
    {
        switch(getOutermostRoom)
        {
        case breakfastQueue:
        case hospital:
            inherited; break;
        case lectureRoom:
            if(gRevealed('pain'))
                "You are still breathing -- just. ";
            else
                inherited;
            break;
        default:
            "You appear to be breathing, but what that signifies is another
            matter. ";
        }
    }
    lastStatueLoc = nil
    feelDesc()
    {
        if(hospital.seen)
            "You can't feel anything missing, at least. ";
        else if(limbo.seen)
            "Although you look a pale reflection of yourself, you still feel
            fairly solid -- at least to yourself -- but you do feel unusually
            cold. ";
        else
            "You {feel|felt} as solid as ever. ";
    }
    cutNoEffectMsg = 'You recoil{|ed} from such an act of self-mutilation. '
;

+ conferenceProgramme: Readable 'gaudy yellow conference
    paper/handout/programme/leaflet' 
    'conference handout'
    "It's a handout for Professor Wortschlachter's lecture, printed on gaudy 
    yellow paper. <<readDesc>>"
    readDesc = "It reads:\b
        <FONT FACE=TADS-SANS> <CENTER><u>14th Annual PANTS
        Conference</u></CENTER>\b
        Our Special Guest Speaker, Herr Doktor Doktor Professor Karlheinz
        Wortschlachter is delivering today's keynote address on the exciting
        topic of <q>Rolling Away the Misconceived Stone: Structural Semiotic
        Signification in Mark 16:1-8</q>\b
        The organizers particularly request all Conference delegates to attend
        this afternoon\'s plenary session at which this internationally
        renowned scholar will reveal his latest thinking on this exciting and
        vital topic.\b
        Dr Wortschlachter is Professor of New Testament History and Exegesis at
        the Protestant Faculty of the University of Wirrstadt. He is the author
        of several important books, including the renowned <i>Deconstructing
        the Deconstruction of Structurally Symbolic Social-Scientific Semiotic
        Signification in Second Temple Judaeo-Christianity</i>. This is the
        first time we have been fortunate enough to have him address a meeting
        of the Pan-Atlantic New Testament Society.</FONT>\b"
    weight = 0
;

+ tie: PlayerClothing 'plain blue tie' 'tie'
    "{It\'s dobj/he\'s} just a plain blue tie with a thin red stripe. "
;

++ Component 'thin narrow red stripe/stripes/pattern' 'thin red stripe'
    "The only pattern on your tie {is|was} the occasional narrow red stripe. "
;

+ PlayerClothing 'dark blue jacket' 'dark jacket'
    "{It\'s dobj/he\'s} nothing special, just a plain dark blue jacket. "
;

+ badge: Wearable '(my) (your) plain white name badge/tag' 'name badge'
    "It<<tSel('&rsquo;s',' was')>> a plain white name badge that
    read<<tSel('s','')>>:
    \n<FONT FACE=TADS-TYPEWRITER>Dr William Fisher -- University of
    Oxford</FONT>"
    wornBy = gPlayerChar
    verifyDobjExamine() {}
    dobjFor(Doff)
    {
        check()
        {
            if(isIn(breakfastQueue))
                failCheck('You didn\'t want to mislay it, and you wanted to
                    keep your hands free to collect your breakfast. ');
        }
    }   
    formerlyWornBy = nil
    formerLocation = nil   
    theDisambigName = 'your name badge'
;


class PlayerClothing: Wearable
    wornBy = gPlayerChar
    dobjFor(Doff)
    {
        check()
        {
            if(past)
                failCheck('You\'d only just put it on; besides, this certainly
                    wasn\'t the place to start undressing. ');
            else
                failCheck('This is neither the time nor the place to start
                    undressing. ');
            
        }
    }
    past = (isIn(breakfastQueue))
    itTense()
    {
        "It"; if(past) " was"; else "&rsquo;s";
    }
;

//==============================================================================

/* 
 *   The Player Character's initial location -- the lecture theatre where 
 *   Professor Wortschlachter is delivering his terrible talk.
 */

lrNorthWall : RoomPart 'plain pine n north wall*walls*strips' 'north wall'
    "The wall behind the podium is largely a bare expanse of plain pine
    strips. "
;

lrWestWall: RoomPart 'plain pine w west wall*walls*strips' 'west wall'
    "Most of the west wall, over to your left, is taken up by the windows. "
;

lrEastWall: RoomPart 'plain pine e east wall*walls*strips' 'east wall'
    "The east wall, over to your right, is made up of a long stretch of
    vertical strips of pine. "
;

lrSouthWall: RoomPart 'plain pine south s wall*walls' 'south wall'
    "The south wall is out of sight behind you (and this isn't the time to
    turn and stare at it). You know without having to look, however, that
    it is the most desirable wall of the four, since it is through the
    south way that the main exit lies. "
;

lrFloor: Floor 'plain pale wooden pine surface/wood/ground/floor*strips' 'floor'
    "The floor is made of some hard-wearing wooden surface, which looks like
    strips of pine or some other pale wood. "
;


lectureRoom: Room 'Lecture Theatre'
    "Facing you is the podium, from which the <<rand('infernal', 'wretched',
        'ridiculous')>> Professor Wortschlachter is busily delivering his
    lecture. Facing the podium are row upon row of hard wooden chairs, about a
    dozen in front of you, and as many again behind. Over to your left a series
    of windows, partly obscured by blinds, look out on a relentlessly grey day,
    while the main exit is out of sight behind you. The walls have been covered
    with plain strips of pine that match the floor, but are otherwise
    undecorated except for the occasional fading poster. "
    
    south : FakeConnector {
        "<<lexicalParent.cannotGoThatWayMsg>> "
    } 
    roomParts = [lrFloor, lrNorthWall, lrSouthWall, lrEastWall, lrWestWall, defaultCeiling] 
    cannotGoThatWayMsg 
    {
        if(gRevealed('pain'))
            return 'You find you\'re unable to move. ';
        else return
            'As much as you might like to escape, you\'re sitting in the middle
            of a row, so you can\'t move in any direction without disturbing a
            whole lot of people. Besides, you don\'t want to be the only person
            here who appears less than fascinated by the lecture. ';
    } 
    cannotGoThatWay() { reportFailure(cannotGoThatWayMsg); }
    atmosphereList : EventList {
    [
        '<.p>Professor Wortschlachter peers down at his notes, grasps the top
        of the lectern, and announces, <q>As you all know, our pericope, Mark
        16.1-8 is one that <i>The Acts of Jesus</i> prints in heavy black type,
        indicating that the Jesus Seminar are quite clear that the account is
        utterly unhistorical. We can assume that a first-century Jesus Seminar
        would have voted the same way, at once recognizing the midrashic
        intertexture of this text and not for a moment mistaking it for a
        putative historical report.</q>\b
        You wonder briefly at this astonishing leap of logic, but
        Wortschlachter ploughs relentlessly on, leaving minimal time for
        critical assessment. ',        
        
        '<.p><q>Since we can assume that any literalist reading of the empty
        tomb story can be instantly deconstructed,</q> Professor Wortschlachter
        drones on, <q>we can progress to the correct identification of its
        <i>Sitz im Leben</i> in the proper <i>religionsgeschichtlichen</i>
        context.</q>\b
        <i>Bullshit!</i> you think, convinced even more than ever now that
        Wortschlachter is just throwing in a random mish-mash of technical
        language in order to disguise his total lack of methodological
        rigour. ',
        
        //        '<.p><q>Of course,</q> Wortschlachter continues, <q>this does not mean that we totally
        //         ignore the <i>Wirkungsgeschichte</i> of this text...</q>',
        
        '<.p><q>... but this must include, <i>inter alia</i> its thorough
        demythologization in line with the Bultmannian perspective.</q> the
        professor grinds on.<.p>
        At this point your attention starts to wander as you find your eyes
        attracted to the blonde woman sitting three rows ahead. ',
        
        
        '<.p><q>The opening of the tomb represents the opening of an orifice,
        and the final resistance to closure,</q> Wortschlachter surmises,
        <q>although, of course, the tomb stands at the interface of life and
        death, the young man in white shows the mythological transcending of
        this fundamental binary opposition, from which the women quite
        naturally flee in terror...</q><.p>                 
        You suddenly start to feel a bit queasy; perhaps it was something you
        ate. ',         
        
        new function() {        
            "<.p>Wortschlachter pauses to peer down at his notes, then
            continues, <q>At this        point in the narrative the implied
            reader can be relied upon to perceive the numinous dread occasioned
            by the crossing of boundaries; as boundary-crossing has been a
            <i>leitmotiv</i> throughout Mark\'s narrative, most dramatically
            conveyed in the sea-crossing stories, as for example when Jesus
            overcomes the binary opposition between land and sea by walking on
            the water. So now the ultimate boundary, that between life and
            death, is finally transcended; <i>a fortiori</i> the implied reader
            understands that all lesser purity boundaries between clean and
            unclean are henceforth abolished, as should be apparent from the Q
            parallel...</q>\b
            For a moment, your twinge passes, and you think, <i>Q Parallel! To
            what, for heaven\'s sake? To the Empty Tomb Story? To the Walking
            on the Sea? What does this idiot think he\'s talking about?</i>
            <.reveal q-parallel>";
            if(!breakfastQueue.seen)
                "Once again you find your eyes drawn to the blonde woman
                sitting three rows ahead, as you wonder what she's making of
                this drivel. ";
        },
        
        new function() {
            "<.p><q>The empty tomb is, of course, not about literal
            resurrection at all,</q> the lecturer informs you, <q>hence the
            reader is never confronted with the risen Jesus in the Markan
            narrative. On the contrary, we must assume that the Markan
            audience, conversant with the allegorical techniques of Philonic
            exegesis...</q>";
            if(!breakfastQueue.seen)
            {
                "<.p>The Professor finally forfeits your attention altogether
                at this point, for it's the woman you're now thinking about.
                Admittedly you've hardly spoken with her. ";
                blondeWoman1.breakfast();
            }
        },
        
        '<.p>Your twinge returns with a vengeance, a sharp pain under the arm
        and a tightening across the chest, as Wortschlachter rambles on, <q>...
        understood, of course, in its proper relation to contemporary
        proto-rabbinic <i>Targumim</i>...</q><.reveal pain>',
        
        '<.p>The pain in your chest grows worse. You can hardly breathe, let
        alone cry out. You\'re dimly aware of Wortschlachter continuing,
        <q>Both implied author and implied reader know very well that literal
        death is final, and that from the netherworld there is no
        return...<.reveal heart-attack></q>',
        
        new function { 
            "<q>...and that neither Heaven nor Hell is to be understood as the
            ultimate human destiny...</q> Wortschlachter's voice suddenly seems
            to recede into the distance as the lecture theatre grows strangely
            dim and blurry around you. As you fight for breath, the last thing
            you focus on is the long blonde hair of the woman three rows ahead.
            For some reason you suddenly recall her name: Felicity Hope. But
            this is the last thought you have before the auditorium fades from
            view altogether.\b
            <.reveal heart-attack>";
            
            inputManager.pauseForMore(true);
            
            foreach(local cur in gPlayerChar.contents)
                cur.moveInto(nil);
            
            cls();            
            
            gSetKnown(felicity);
            gPlayerChar.moveIntoForTravel(lectureRoom);
            gPlayerChar.makePosture(standing);
            nestedAction(TravelVia, limbo);
        }
    ]
    }
    thinkHere()
    {  
        if(gRevealed('pain'))
            "You think you're very unwell. ";
        else   
            "You think Professor Wortschlachter is talking total tosh, and
            pretentious tosh at that, but you feel you had best keep your
            thoughts to yourself. ";    
    }
    roomBeforeAction()
    {
        if(gActionIs(Yell))
        {
            if(gRevealed('pain'))
                "Right now you can hardly squeak, let alone shout. ";
            else
                "There are several things you feel like <<gVerbName>>ing at the
                pompous professor, but you dare not interrupt this august
                gathering with them; your reputation might never recover! ";
            exit;
        }
        
        if(gActionIn(TalkTo, TellAbout, AskAbout, AskFor) && gRevealed('pain'))
        {
            "It's as much as you can do to breathe right now; let alone talk! ";
            exit;
        }
        if(gActionIn(ThrowAt, ThrowDir))
        {
            if(gDobj != conferenceProgramme || gIobj not in (blondeWoman1, worts))
            {
                "You really do know better than to start throwing things around
                during a keynote lecture. It would do your scholarly reputation
                no good at all. ";
                exit;
            }
        }
        
        
        if(gActionIs(Stand) || gActionIs(Out))
            failCheck(cannotGoThatWayMsg);       
    }      
    eastLook { "You look along the row of seats, which seems to be occupied by
        delegates all the way to the wall. "; return showRoomPart; }
    westLook { "You glance westward along your row, in which every seat appears
        to be occupied all the way up to the aisle. "; return showRoomPart; }
    northLook = "That way lies the podium from which Professor Wortschlachter
        is busily delivering his lecture. Directly ahead of you to the north
        are several rows of seats occupied by other conference delegates like
        yourself -- well, mostly like yourself; your eyes keep getting drawn to
        the blonde women sitting three rows ahead. "     
    outLook  = lrDay.desc
    defaultLook(dir) { "There's not much to see to the <<dir.name>> apart from
        more chairs occupied by more delegates. "; }
;

+ SimpleOdor 'slightly stale soporific (body) warm mix/air/odours' 'stale air'
    "Slightly stale, warm air with a background hint of low-level body odours
    combine to make a soporific mix. Or perhaps it's just Wortschlachter's
    lecture that makes it feel that way. "
;

+ lectureRoomChair: Chair, CustomImmovable 'plain hard wooden urpright
    utilitarian chair' 
    'wooden chair'
    "It looks just like all the other chairs round it: plain, upright and
    utilitarian. "
    feelDesc = "It's posterior-numblingly hard. "
    actorInName = ('on ' + aThe + ' plain wooden chair')
    out = nil
    cannotGoThatWay() { location.cannotGoThatWay; }
    aThe = (gActionIs(Examine) && gDobj == self ? 'the' : 'a')
    exitDestination = nil
    cannotMoveActorOutOf()
    {       
        reportFailure(location.cannotGoThatWayMsg);
    }
    reachableObjects = [conferenceProgramme, badge]  
    allowedPostures = [sitting]
    cannotStandOnMsg = 'You\'d really make an exhibition of yourself if you did
        that in the middle of a lecture! '
    portLook = (location.westLook)
    starboardLook = (location.eastLook)
    foreLook = (location.northLook)  
    aftLook { replaceAction(Examine, lrSouthWall); }  
    restrictedReach = nil
;

+ Distant 'odd occasional fading institutional poster*posters' 'fading posters'
    "They\'re hard to make out clearly from here, but they have a faintly
    run-down institutional air about them: an announcement of last month's
    student union meeting, an advertisement for last year's Christmas concert,
    that sort of thing. "
    isPlural = true
    initNominalRoomPartLocation = lrEastWall
;

+ Decoration 'hard upright wooden strictly utilitarian roughly straight
    (seats)/row*rows*chairs' 
    'chairs'
    "Perhaps in anticipation of the soporific nature of this address, the
    conference organizers have provided row upon row of hard, upright wooden
    chairs on which it would be virtually impossible for anyone to slip off to
    sleep. At any rate the chairs certainly seem to be doing a good job of
    keeping this audience awake."
    feelDesc = "If the one you're sitting on is anything to go by, these chairs
        were purchased more for reasons of economy than of comfort. "
    isPlural = true
;

+ Distant 'raised podium/platform/stage' 'podium'
    "The podium is a raised platform or stage at the end of the lecture-hall.
    Right now it's fairly bare apart from the seat occupied by the session
    chairman, the seat recently vacated by Professor Wortschlachter, and the
    lectern behind which he's standing. A large clock hangs on the wall
    behind. "
;

+ Distant 'large round black clock' 'clock'
    "It's a large, round, old-fashioned clock with Roman numerals round the
    dial. It indicates that you're probably going to have to listen to
    Professor Wortschlachter for at least another forty minutes. "
    initNominalRoomPartLocation = lrNorthWall    
;

+ Distant 'blue seat/seats' 'seats'
    "The two seats on the podium are covered with some sort of blue fabric, but
    otherwise don't look much more comfortable than the chairs in the main body
    of the hall. "
    isPlural = true
;

+ Distant, Surface 'plain utilitarian pale wooden lectern' 'lectern'
    "The pale wooden lectern is of plain utilitarian design. Professor
    Wortschlachter is using it both to support his notes, and to grasp with
    both hands from time to time in what he presumably intends to be a gesture
    of dramatic emphasis. "
;

++ Distant '(lecture) sheaf/notes/papers' 'notes'
    "From the way he keeps referring to them you assume that the sheaf of
    papers sitting on the lectern are Professor Wortschlachter's lecture notes
    rather than, say, a shopping list he just happened to bring along; but,
    come to think of it, his lecture might have been a whole lot more
    interesting if it <i>were</i> his shopping list. "
    isPlural = true
;

+ Distant 'main exit*exits' 'main exit'
    "You can't see it from here, since it's directly behind you, and twisting
    round to look at it in the middle of the lecture would probably look rather
    odd. "
;

+ lrWindows: Distant 'windows/blinds' 'windows'
    "The windows line much of the wall to your left, but they are partly shaded
    by blinds, perhaps to remove the temptation to delegates to stare out at
    the grey day outside instead of attending to the speaker. "
    nothingThroughMsg = 'They\'re partly shaded by the blinds, 
        and from where you\'re sitting you can
        discern little through them beyond the greyness of the day outside. '    
    dobjFor(LookThrough) { verify() {} }
    isPlural = true  
;

+ lrDay: Vaporous 'relentlessly grey outside gray dull overcast
    day/greyness/grayness/outside' 
    'grey day'
    "You can't see much through the windows, since they're partly shaded by the
    blinds, but it looks like it's a dull, overcast day outside, giving an
    overwhelming impression of greyness. "
;

/* 
 *   This is one of the three objects used to represent Felicity at various 
 *   stages of the game; for the other two see the file Felicity.t. Since 
 *   there are few ways to interact with her while you're both sitting in 
 *   the lecture this version of Felicity doesn't need to be put in a 
 *   separate file.
 */


+ blondeWoman1: Person 'blonde woman*women' 'blonde woman'
    "From here all you can see is the back of her head, and her long blonde 
    hair falling over her shoulders. <<breakfast()>> "
    
    isHer = true
    specialDesc() {}
    uselessToAttackMsg = 'There\'s absolutely no reason why you\'d want to do
        that, but in any case you can\'t reach her. '
    cannotKissActorMsg = 'Even if kissing an attractive woman you hardly know
        in such a public place was remotely a good idea, she\'s too far away
        for it to be remotely possible. '  
    feelDesc = "She's three rows ahead of you; you can't possibly reach her
        from where you're stitting. " 
    hugResponse = "She's too far away -- quite apart from the fact that hugging
        a woman you hardly know in the middle of a crowded lecture is likely to
        attract unfavourable notice. "
    cannotEatMsg = 'That would be taking desire to absurd extremes. '
    breakfast()
    {
        if(breakfastQueue.seen)
            "You spoke with her briefly at breakfast, and she seemed nice
            enough, but you wonder if she really registered your existence and
            whether you'll ever speak with her again. ";
        else      
        {
            "But you're sure it's the woman you've noticed several times before
            at this conference. You did glance at her name badge, but you can't
            quite remember what it said; it was one of those quaint
            old-fashioned names like Charity Faith or Verity Love, except
            you\'re sure it's not either of those. You now wish you were better
            at remembering names, since you\'re forced to think of her simply
            as <q>that rather attractive blonde</q>. Until this morning you
            hadn't exchanged a single word with her, but then there was that
            brief encounter at breakfast...";
            
            inputManager.pauseForMore(true);
            blondeWoman.fuseID = new Fuse(blondeWoman, &endFlashback, 8);
            gPlayerChar.moveIntoForTravel(lectureRoom);
            gPlayerChar.makePosture(standing);
            badge.formerLocation = badge.location;
            badge.formerlyWornBy = badge.wornBy;
            foreach(local cur in gPlayerChar.contents)
            {
                if(isPortable(cur) && cur.wornBy == nil)
                    cur.moveInto(lakesideDepository);
            }
            badge.moveInto(gPlayerChar);
            badge.wornBy = gPlayerChar;
            setPastTense(true);
            nestedActorAction(gPlayerChar, TravelVia, breakfastQueue);       
            new Fuse(self, &killCommand, 0);
        }
    }
    killCommand()
    {
        if(gPlayerChar.pendingCommand.length > 0)
        {
            //        "<.p>(discarding";
            //        foreach(local pend in gPlayerChar.pendingCommand)
            //        {
            //          foreach(local tok in pend.tokens_)
            //            " <<getTokVal(tok)>>";
            //        }
            //        ")<.p>";
            gPlayerChar.pendingCommand.setLength(0); 
        }
    }
    throwTargetHitWith(projectile, path)
    {
        if(projectile == conferenceProgramme)
            "That might conceivably attract her attention, but it's unlikely to
            create a favourable impression. ";      
    }
    dobjFor(PrayTo) { verify() {logicalRank(110, 'latest version'); } }
    dobjFor(Attack) { verify() { illogical(uselessToAttackMsg); } }
;

++ HermitActorState
    noResponse =  "She's too far away; besides you won't impress her by
        shouting at her across the conference hall in the middle of an
        important lecture. "   
    isInitState = true
    smileResponse = "You <<gVerbName>> at the back of her head, but since she can't
        see you, it's a fairly futile gesture. "
    
;

++ Distant 'long straight shiny silky smooth silky-smooth golden (blonde) hair' 
    'blonde hair'
    "Her long golden blonde hair, though basically straight, has a slight,
    alluring wave to it. It looks shiny and silky-smooth, and falls neatly
    between her shoulder-blades. "
    tooDistantMsg = 'Her hair is too far away for you to touch in any case, but
        trying to play with the hair of a woman you hardly know in such a
        public place full of your academic peers would hardly serve to enhance
        your reputation. '
;


+ Person  'conference grad biblical retired audience/people/delegates/students/
    (professors)/scholars'    'audience'
    "The audience here, as at most gatherings of biblical scholars, is
    predominantly male, though ages range between twenty-something grad
    students and seventy-something retired professors, with the bulk in
    between. There are one or two women scattered among them, however, and you
    are particularly aware of the blonde sitting a few rows ahead. "
    isPlural = true
    specialDesc() {}
    dobjFor(Attack) { verify() { illogical(uselessToAttackMsg); } }
    uselessToAttackMsg = 'You have no desire to bring about such an ignominious
        end to your academic career, which is surely what the outcome of such
        senseless violence would be. '
    cannotKissActorMsg = 'The only members of the audience within kissing range
        are male, and you are not that way inclined; even if you were
        surrounded by delectable females, suddenly kissing them in mid-lecture
        would deliver your reputation a blow from which it would never
        recover. '
    
;

++ HermitActorState
    isInitState = true
    noResponse = "The rest of the audience appear intent on Wortschlachter's
        lecture; it seems best not to interrupt them right now. "
    hugResponse = "You are far too reserved to draw attention to yourself
        by hugging a group of strangers in so public a place. "
    
;  

+ worts: Person 'dr professor prof karlheinz wortschlachter/speaker/lecturer' 
    'Professor Wortschlachter'
    "Professor Wortschlachter is a tall, gaunt, angular-looking man with
    wire-rimmed spectacles, a shock of white hair, and a faintly manic
    manner. "
    isHim = true
    isProperName = true
    uselessToAttackMsg = 'As much as {you/he}\'d like to, he\'s too far away. '
    cannotKissActorMsg = 'Quite apart from the fact that you don\'t have the
        smallest inclination to do any such thing, he\'s too far away. '
    feelDesc = "You can't reach him from where you're sitting. "
    hugResponse = "Quite apart from the fact that's the last thing you feel
        like doing -- except perhaps for a vicious bear hug to squeeze all the
        hot air and wind out of him -- he's too far away. "    
    cannotEatMsg = 'There\'s nothing to suggest he\'d prove any more digestible
        than his lecture. '
    nothingBehindMsg = 'There\'s not much behind Professor Wortschlachter apart
        from the north wall of the auditorium, on which you can see a clock. '
    throwTargetHitWith(projectile, path)
    {
        if(projectile == conferenceProgramme)
            "In your imagination you fold your handout into a beautiful paper
            dart and execute a perfect throw, so that your projectile strikes
            Professor Wortschlachter squarely on the nose, stopping his
            ridiculous lecture in mid-burble. Regrettably, you dare not attempt
            anything of the sort in reality. ";      
    }
    dobjFor(Attack) { verify() { illogical(uselessToAttackMsg); } }
;

++ SimpleNoise 'lecture/droning/voice' 'lecture'
    "You\'re doing your best to listen to Wortschlachter -- after all, that's
    why you're here -- but he's not the most gripping lecturer you've ever
    heard. Indeed, it's only his pompous absurdity that rescues him from being
    the dullest. "
    
;

++ Distant 'ordinary wire-rimmed wire rimmed pair/spectacles' 
    'wire-rimmed spectacles'
    "You can't make out any details from here; they just look like a perfectly
    ordinary pair of wire-rimmed spectacles, perched upon Wortschlacter's nose
    in a spurious attempt to lend him an air of scholarly respectability. "
    owner = worts
    isPlural = true
;

++ HermitActorState
    specialDesc = "Professor Wortschlachter is standing on the podium,
        delivering his lecture. "
    isInitState = true
    noResponse =  "You can hardly interrupt the eminent professor in the middle
        of his lecture, even if you do suspect he's talking total twaddle. "  
;

+ chairman: Person 'young session chairman/scholar' 'chairman'
    "The young scholar chairing this section is doing his best to look
    appreciative of Professor Wortschlachter's wisdom, but appears to be having
    no small difficulty in stifling a yawn. "
    isHim = true
    uselessToAttackMsg = 'It\'s not his fault Wortschlachter is such an ass! '
    cannotKissActorMsg = 'That would make you look an ass. '
    hugResponse = "Fortunately, he's too far away for you to attempt anything
        so obviously embarrassing. "
    feelDesc = "You can't reach him from where your sitting. "   
    dobjFor(Attack) { verify() { illogical(uselessToAttackMsg); } }
    nothingBehingMsg = 'About the only thing you can see behind the chairman
        is the north wall of the auditorium. '
;  

++ HermitActorState
    specialDesc = nil
    isInitState = true
    noResponse = "He's too far away, and besides this isn't an appropriate moment
        to start a conversation with him. "
;

//=============================================================================

/* 
 *   This is one of the very few other real world locations in the game, so 
 *   it may as well be included in the same file. It's actually the location 
 *   where the game ends.
 */

hospital: Room 'Hospital' 'the hospital'
    "Your first impression of the ward is of a blur of bright lights and white
    walls. You can't see any other beds here, so you must have a ward to
    yourself -- perhaps that means you've been <i>very</i> ill. You're vaguely
    aware of some complicated equipment on one side of the bed and a bedside
    table on the other. "
    cannotGoThatWay() { "You're not strong enough to try going anywhere just
        yet. "; }
    thinkHere =  "You're a bit surprised, but profoundly grateful, to find
        yourself back among the living. "   
    roomBeforeAction()
    {
        if(gActionIs(Stand))
        {
            "You're too weak to stand. ";
            exit;
        }     
    }
    
    vocabWords = 'ward/hospital'
;

+ hospitalBed : Bed, Fixture 'bed' 'bed'
    "You can't see much of it, since you\'re lying on it, but it seems pretty
    much like an ordinary bed so far as you can tell. "
    out = nil
    cannotGoThatWay() { location.cannotGoThatWay; } 
    restrictedReach = nil 
    exitDestination = nil
    cannotMoveActorOutOf()
    {       
        reportFailure(notStrongEnoughMsg);
    }
    notStrongEnoughMsg = 'You\'re not strong enough to get up yet. '
    //  dobjFor(GetOffOf) remapTo(Out)
    //  dobjFor(GetOutOf) remapTo(Out)
    allowedPostures = [lying]
    cannotStandOnMsg = (notStrongEnoughMsg)
    cannotSitOnMsg = (notStrongEnoughMsg)
;


+ Decoration 'bedside table*tables' 'bedside table'
    "It sits besides your bed, perhaps waiting for you to use once you're
    in a fit state to need it. "
;

+ Decoration 'complex complicated medical
    equipment/machinery/dials/lights/switches' 
    'complex equipment'
    "It's some kind of medical machinery with dials and lights and switches,
    but you've no idea what it does. Presumably it's had some part in
    monitoring your recovery, but looking at it doesn't make you any
    wiser about your current medical condition. "
;

//==============================================================================

 /* 
  *   This is the third and final real-world location in the game, the place 
  *   where the flash-back to breakfast occurs (as it's a flashback, 
  *   everything here happens in the past tense).
  */

breakfastQueue : Room 'The Breakfast Queue'
    "The queue for cereal, toast, tea and coffee was quite short, so it would
    not be long before you would be able to sit down at one of the tables
    scattered about this large hall and eat your breakfast. "
    cannotGoThatWayMsg = 'You didn\'t want to lose your place in the queue. '
    cannotGoThatWay() { reportFailure(cannotGoThatWayMsg); }  
    thinkHere = "You were thinking how lucky you were to join the breakfast
        queue just behind this attractive blonde you'd already noticed several
        times before. "
    roomBeforeAction()
    {
        if(gActionIs(Jump))
            failCheck('What? Jump the queue? You\'d never do a thing like
                that! ');
        if(gActionIs(SitOn))
            failCheck('You weren\'t ready to sit down until you\'d collected
                your breakfast. ');
        if(gActionIs(LieOn))
            failCheck('You\'d just left your bed and you weren\'t about to lie
                down on the floor. ');   
        if(gActionIs(Wait))
            "Time passed... "; 
    }
    out: NoTravelMessage { "You had no desire to leave at that point. " }
    northLook = "The blonde woman was standing immediately to the north of you;
        a short distance behind her were the tables bearing the breakfast
        things you were both queueing for. "
    southLook = "The bulk of the hall lay to the south, filled with tables,
        chairs, and delegates eating their breakfast. "
    southwestLook = (southLook)
    southeastLook = (southLook)
;

+ Decoration 'cereal/toast/tea/coffee/food/drink/breakfast' 'food and drink'
    "A selection of stuff to eat and drink for breakfast was set out on the
    tables you\'d reach once you were head of the queue. "
    notImportantMsg = 'You were going to have to wait till you got to the front
        of the queue before you could collect anything to eat or drink. '
;

+ Decoration 'table/tables' 'tables'
    "Apart from the serving tables you were queuing to reach, a number of
    tables of various sizes -- or perhaps tables of uniform size clustered into
    groups of different sizes, with the table-cloths on them you couldn't be
    sure which -- were scattered around the room. Some were still empty, some
    had only one or two sitting at them, but several were already quite well
    populated. "
    isPlural = true
    notImportantMsg = 'You didn\'t intend to do anything to any of the tables
        other than sit at one of them once you\'d collected your breakfast. '   
;

+ Chair, Fixture
    theName = 'a chair'
;

+ Decoration 'free occupied unoccupied chair/seat/chairs/seats' 'chairs'
    "There were chairs round all the tables; a few were occupied but rather
    more were free. "
    notImportantMsg = 'Your priority was to get some food before worrying about
        your seating arrangements. '
    isPlural = true
;

+ Decoration 'people/scholars/delegates' 'people'
    "Not that many people had come down to breakfast yet; those that had looked
    like a fairly typical collection of New Testament scholars attending a
    conference; but at that blurry hour of the morning, before even your first
    cup of tea, any bunch of people would probably have looked to you much like
    a fairly typical collection of anything. "
    isPlural = true
    notImportantMsg = 'You weren\'t that interested in them at this point; it
        was the blonde woman who had your attention. '
;

+ Decoration '(breakfast) short queue' 'queue'
    "Fortunately the queue was quite short at that point, and you were near the
    front. "
    notImportantMsg = 'Apart from the woman directly in front of you, you
        didn\'t regard them as important. '
;

+ SimpleOdor 'warm freshly-brewed tea/toast/coffee/bacon/eggs' 'smells'
    "Warm toast, freshly-brewed tea and coffee, bacon and eggs frying somewhere
    in the distance: the smells were not obtrusive, but enough to make the
    prospect of breakfast feel just that much more urgent. "
    isPlural = true
;

+ SimpleNoise 'constant quiet restrained hum/conversation/clanking' 'sounds'
    "A restrained hum of conversation was punctuated by the constant quiet
    clanking of cutlery on china from the tables all around. "
    isPlural = true
;

+ CustomImmovable '(blonde) (her) woman\'s (name) badge/tag/nametag' 
    'blonde woman\'s name badge'
    "It had her name on it, but you can't recall what it said. "   
    cannotTakeMsg = 'It was pinned to her blouse, and you certainly weren\'t
        about to fiddle with it. '   
    //   owner = blondeWoman
;

//==============================================================================

 /* 
  *   We provide god and jesus objects to provide suitable responses (or 
  *   non-responses) should the player attempt to pray to them.
  */

god: MultiLoc, Decoration 'almighty god/almighty' 'God'
    "<<notImportantMsg>>"
    isProperName = true
    dobjFor(PrayTo) 
    {
        verify() { logicalRank(150, 'god'); }
        check() {}
        action()
        {
            "{The dobj/he} presumably hear{s/ed} your prayer, 
            but His answer {is|was} inscrutable. ";
        }
    }
    
    notImportantMsg = 'God is no doubt present everywhere, but He is also
        invisible and intangible. '
    initialLocationClass = Room
    isKnown = true
;

jesus: Person 'jesus christ' 'Jesus' 
    "You cannot see him. "
    dobjFor(PrayTo) 
    {
        verify() { logicalRank(140, 'god'); }
        check() {}
        action()
        {
            "{The dobj/he} presumably hear{s/ed} your prayer, but {you/he}
            {are} unaware of any reply. ";
        }
    }
    isProperName = true
    isKnown = true
;

