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

/* snake.t*/

snake : Person 'green purple magnificent large tail/snake/serpent/specimen' 
    'snake' @eden
    "It's a magnificent specimen, about twelve feet long, with green and purple
    markings. "
    posture = lying
    dobjFor(Take)
    {
        verify() { }
        check() { }
        action() {
            "You gingerly pick the snake up by its tail, and find that it turns
            into a coil of rope into your hands. ";
            moveInto(nil);
            rope.moveInto(gActor);
            gActor.setHasSeen(rope);
        }
    }
    uselessToAttackMsg = 'You have no reason to do that. '
    cannotEatMsg = 'You never had much appetite for snakes. '
    hugResponse = "It may or may not be a friendly snake, but it\'s certainly
        not a cuddly one. "
    cannotKissActorMsg = 'You have no intention of giving that snake any
        opportunity to put its tongue in your mouth! '
    postureDesc() { }
    isHim = true
    isIt = true
;

+ snakeMarkings : Component 'green purple diamond markings/pattern' 
    'green and purple markings'
    "The green and purple markings form a diamond pattern for the whole length
    of the snake. "
;

+ snakeSleeping: HermitActorState
    specialDesc = "A large snake lies curled under the central tree. "
    stateDesc = "It\'s lying curled under the tree. "
    noResponse = "The snake appears to be sound asleep. "
    isInitState = true
    beforeAction()
    { 
        if(gActionIs(Take) && gDobj==apple)
        {
            reportFailure('');
            "<.p>The snake suddenly wakes up and raises his head to look at you
            curiously. <q>I wouldn't take that, I really wouldn't,</q> he warns
            you, <q>It\'s only a Golden Delicious and even <i>I</i> wouldn't
            want anyone to fall for a Golden Delicious!</q>";
            getActor.setCurState(snakeTalking);
            getActor.noteConversation(gPlayerChar);
            exit;
        }
        if(gActionIs(Take) && gDobj==getActor)
        {
            "You hesitate to grab the snake; after all that's the sort of thing
            that makes a snake angry and bite people, and this snake looks like
            it could pack one mean bite. On the basis that discretion is the
            better part of valour you decide it would be better to find out the
            nature of this snake before meddling with it. ";
            exit;
        }
    }
;

+ snakeTalking: InConversationState
    specialDesc = "The snake is lying on the ground looking up at you. "
    stateDesc = "It's lying on the ground looking up at you. "
    beforeAction()
    {
        if(gActionIs(Take) && gDobj==apple)
        {
            reportFailure('');
            "<q>I thought I warned you about that apple!</q> the snake hisses
            urgently, <q>It won't do you any good, really it won't! If you
            value your sanity, leave it alone!</q><.p>";
            exit;
        }
    }
    nextState = snakeResting
;

++ snakeResting: ConversationReadyState
    specialDesc = "The snake is lying <<desc>>. "
    stateDesc = "It's lying coiled up <<desc>>. "
    desc = (isIn(eden) ? 'under the tree' : 'on the ground')
    attentionSpan = 10
;

+++ HelloTopic
    "<q>Hello, there!</q> you say.\b
    <q>Sssso, it'sss you again!</q> hisses the snake. "
;

+++ ByeTopic
    "<q>Cheerio, then!</q> you say.\b
    <q>Goodbye,</q> replies the snake, lowering its head
    onto its coils. "
;

+++ ImpByeTopic
    "The snake shuts its eyes and coils itself up tightly. "
;

++ AskTopic, StopEventList, SuggestedAskTopic @snake
    [
        '<q>Who are you, if you don\'t mind my asking?</q> you ask.\b
        <q>Not at all, it\'s polite of you to enquire,</q> the snake replies,
        <q>So many people jump to conclusions about snakes -- especially snakes
        guarding apple trees in paradisal gardens.</q>',
        
        '<q>So, are you <i>that</i> snake?</q> you ask.\b
        <q>By <i>that</i> snake I take it you mean the serpent who deceived
        Eve,</q> the snake replies, <q>but <i>that</i> was a cunning serpent,
        and I\'m just your friendly neighbourhood snake. After all, I
        <i>stopped</i> you from taking the fruit, didn\'t I?</q><.convnode
        stop-apple>',
        
        '<q>What exactly is a friendly neighbourhood snake doing here?</q> you
        wonder.\b
        <q>Being friendly, of course,</q> the friendly neighbourhood snake
        replies. '   
    ]
    name = 'itself'
;

++ AskTopic, EventList, SuggestedAskTopic @apple
    [
        '<q>What\'s so terrible about that apple?</q> you want to know.\b
        <q>It\'s a Golden Delicious, need I say more?</q> the snake retorts.
        <.convnode golden-delicious> ',
        
        '<q>You stopped me taking the apple just because it\'s a Golden
        Delicious?</q> you ask.\b
        <q>Well, there is another reason,</q> the snake admits, <q>That
        apple\'s growing on <i>the</i> tree. You know -- that one. Adam and Eve
        and all that. It\'s a mighty <i>dangerous</i> apple, you know.</q>',
        
        '<q>So what\'s so dangerous about that apple?</q> you want to know.\b    
        <q>Don\'t you know <i>anything?</i></q> sighs the snake, <q>And you
        call yourself a biblical scholar! Look, that apple is the fruit of the
        tree <i>of the knowledge of good and evil</i>! Do you really think you
        could cope with such knowledge?</q> <.convnode good-evil>. ',
        
        '<q>So you think I should leave that apple alone,</q> you surmise.\b
        <q>Ah, hooray! I\'m getting through at last!</q> cries the snake. '
    ]
    name = 'the apple'
;

+++ AltListTopic
    "You\'ve more or less exhausted that topic: the snake has told you that the
    apple is dangerous, because it\'s the fruit of the tree of the knowledge of
    good and evil, and you won't be able to cope with that."
;

++ AskTellTopic, EventList, SuggestedAskTopic @appleTree
    [
        '<q>Were you guarding the tree?</q> you wonder, <q>or just sleeping
        under it?</q>\b
        <q>Both,</q> the snake tells you. ',
            
        '<q>Is there anything special about the tree at the centre of the
        garden, then?</q> you enquire.\b
        <q>Well, apart from its central position, it grows a rather dangerous
        sort of fruit,</q> the snake replies. ' 
    ]
    name = 'the tree'
;

+++ AltListTopic
    "There's not much more to say on that topic. "
;


++ AskTellTopic, StopEventList, SuggestedTellTopic @felicity
    [
        '<q>There\'s a friend of mine trapped in a swamp nearby, and I need to
        get her out!</q> you tell him.\b
        <q>How very distressing!</q> the snake observes, <q>So why are you
        standing here nattering to me instead of rescuing this fair
        damsel?</q><.convnode why-natter>',
        
        '<q>My friend is still in the swamp!</q> you remember.\b
        <q>So, what are you going to do about it?</q> the snake
        demands.<.convnode why-natter>'    
    ]
    isActive = (felicity.isIn(swamp) && swamp.seen)
    name = 'Felicity'
;

++ AskTellTopic, StopEventList, SuggestedAskTopic @tHell
    [
        '<q>Are we in hell?</q> you ask.\b
        <q>Not really -- hell\'s been demythologized, hadn\'t you heard?</q>
        the snake replies, <q>this place is what I\'d call the
        netherworld.</q>',
        
        '<q>So hell no longer exists?</q> you enquire,\b
        <q>I didn\'t say hell doesn\'t exist, I said it\'s been
        demythologized,</q> the snake corrects you, <q>perhaps I should say,
        <q>There\'s hell, Jim, but not as we know it!</q></q>.',
        
        '<q>So what <i>is</i> hell?</q> you ask.\b
        <q>Hell is what you create when you abandon hope.</q> the snake
        replies. '
    ]
    name = 'hell'
;

++ AskTopic, StopEventList @tNetherworld
    [
        '<q>What is this netherworld, exactly?</q> you wonder.\b
        <q>Well, you could say it\'s neither one thing nor the other,</q> the
        snake replies, <q>it\'s obviously not Life, but then it isn\'t exactly
        Death, either; just as it clearly isn\'t Heaven, but it\'s not
        Hell.</q>',
        
        '<q>Is there any way out of this netherworld?</q> you ask.\b
        <q>Several,</q> the snake informs you, <q>which you find is entirely up
        to you.</q>'     
    ]
;

++ AskTopic, StopEventList, SuggestedAskTopic @tHeaven
    [
        '<q>Is there a heaven?</q> you ask.\b
        <q>I suppose that depends what you mean by <q>heaven</q>,</q> the snake
        replies unhelpfully.',
        
        '<q>Can you get to heaven from here?</q> you ask.\b
        <q>I can\'t,</q> the snake informs you, <q>whether you can is another
        matter.</q>',
        
        '<q>How would one set about finding heaven?</q> you want to know.\b
        <q>I had heard that faith, hope and love had something to do with
        it,</q> the snake points out, <q>perhaps a bit of courage, truth and
        integrity wouldn\'t go amiss either.</q>'  
    ]  
    name = 'heaven'
;

++ AskAboutForTopic @tRope
    "<q>Do you know where I can find a rope?</q> you ask.\b
    <q>Will I do?</q> asks the snake.<.convnode snake-do>"
    isActive = (felicity.seen)
;

++ AskTopic, EventList, SuggestedAskTopic @tSatan
    [
        '<q>What do you know about Satan?</q> you ask.\b
        <q>Why do you ask me?</q> the snake counters, <q>Why should I be an
        expert on Satan? In any case, I can assure you I am not!</q>',
        
        '<q>Surely you know something about Satan!</q> you insist.\b
        <q>Surely you do too -- so why ask me?</q> the snake replies, <q>It
        sounds suspiciously like discrimation against reptiles to me!</q>'
    ]  
    name = 'Satan'
;

+++ AltListTopic
    "You get the impression that the snake is highly reluctant to say anything
    about Satan. "
;

++ AskTellTopic, StopEventList, SuggestedAskTopic @eden
    [
        '<q>This garden looks like a nice place,</q> you remark.\b
        <q>That\'s probably because it is a nice place,</q> the snake
        replies. ',
        
        '<q>Is this garden your home?</q> you wonder.\b
        <q>It\'s as much a home as I can claim,</q> the snake tells you. ',
        
        '<q>Why is this garden here?</q> you ask.\b
        <q>Why not?</q> the snake retorts, <q>Why are you here? Why is anything
        here? Why could I never understand anything about metaphysics? Mind
        you,</q> it adds, <q>everything has to be somewhere, so I suppose it
        may as well be here as anywhere else.</q>'   
    ]
    name = 'the garden'
;

++ SemiDefaultAskTopic, ShuffledEventList
    eventList =
    [
        {: "<q>Can you tell me anything about <<gTopicText>>?</q> you ask.\b
            <q>No,</q> the snake replies, <q>or at least, I won\'t.</q>" },
        
        {: "<q>What are your views on <<gTopicText>>?</q> you enquire.\b
            <q>Not in the least worth hearing,</q> the snake assures you. " },
        
        {: "<q>What about <<gTopicText>>?</q> you ask.\b
            <q>What about it?</q> the snake retorts rhetorically. "},
        
        {: "<q>I\'d like to know more about <<gTopicText>>,</q> you say.\b
            <q>Wouldn\'t we all?</q> the snake ripostes. " } 
        
    ]
;

++ DefaultAskTopic, ShuffledEventList
    [
        'The snake hisses in reply; whether the hiss was intended as a reply, a
        refusal reply, or an expression of annoyance at your question you
        cannot tell. ',
        
        'In reply, the snake merely flicks his tongue at you. ',
        
        'The snake responds with an intense stare, daring you to interpret what
        he means by it. ',
        
        '<q>Ssssss!</q> says the snake, <q>Ssssss! Tsssss!</q>'   
    ]  
;


++ DefaultTellTopic
    "The snake listens politely to your account. "
;

++ DefaultGiveShowTopic
    "<q>Thanks all the same, but I really don\'t have any use for
    {it dobj/him}.</q> the snake tells you. "
;

++ DefaultAskForTopic
    "<q>I'm sorry, I can't help you there,</q> the snake replies. "
;

++ CommandTopic @TopicActionBase
    "It probably doesn't make much sense to ask it to do that. "
    isConversational = nil
;

++ DefaultTCommandTopic
    "<q>Is there any chance you could <<cmdPhrase>>?</q> you ask.\b
    <q>Maybe,</q> the snake replies, <q>or maybe not. But I don't think I
    shall.</q>";
;


+ ConvNode 'stop-apple'
;

++ YesTopic
    "<q>Yes, you did,</q> you admit.\b
    <q>Well, there you are, then,</q> says the snake. "; 
;

+ ConvNode 'golden-delicious'
;

++ YesTopic
    "<q>Yes, you do; what's so bad about Golden Delicious apples?</q> you
    demand.\b
    In reply, the snake merely rolls its eyes."
;

++ NoTopic
    "<q>No; point taken,</q> you agree. "
;

+ ConvNode 'why-natter'
;

++ SpecialTopic 'tell him you need a rope' 
    ['tell', 'him', 'it', 'you', 'i', 'need', 'a', 'rope']
    "<q>I think I'll need a rope to pull Felicity out of that swamp, and I
    don't know where to find one,</q> you reply.\b
    <q>Would I do?</q> the snake suggests.<.convnode snake-do>"
;

++ SpecialTopic 'admit perplexity' ['admit', 'perplexity']
    "<q>To tell you the truth, I'm stumped; I don't know how to get her out of
    the swamp,</q> you admit.\b
    <q>It sounds to me like you need something to pull her with,</q> the snake
    points out."
;

++ SpecialTopic 'say there\'s no hurry' 
    ['say', 'there\'s', 'there', 'is', 'no', 'hurry']
    "<q>There\'s no hurry,</q> you assure him, <q>she's not going
    anywhere.</q>\b
    <q>I wouldn't count on that,</q> the snake retorts, <q>Nasty things, swamps
    -- at least they are if you're human. A snake like me can slither around
    them quite happily, but you humans tend to sink. I'd call that going
    somewhere -- and somewhere not very nice. I'd hurry up and rescue her if I
    were you.</q>"
;

+ ConvNode 'snake-do'
;

++ NoTopic, SuggestedNoTopic
    "<q>But you\'re a snake, not a rope!</q> you protest.\b
    <q>And Moses' rod was a rod, not a serpent -- or so people thought till he
    dropped it.</q> the snake replies cryptically. "
;

++ YesTopic, SuggestedYesTopic
    "<q>Well, I suppose so, I mean, thanks for the offer, but how do I... ?</q>
    you blather.\b
    <q>Just pick me up,</q> the snake tells you. "
;

+ ConvNode 'good-evil'
;

++ YesTopic
    "<q>Yes, of course I can!</q> you declare stoutly.\b
    The snake rolls its eyes in despair, hissing <q>Oh the foolish arrogance of
    human beings!</q>"  
;

++ NoTopic
    "<q>No, maybe not,</q> you concede, <q>I suppose it might be a bit too
    much. I mean, look what it did to Adam and Eve!</q>\b
    <q>Pre<i>cisssse</i>ly,</q> hisses the snake sinisterly. "  
;

rope : Thing 'neat twisted green purple coil/rope/fibres' 'coil of rope'
    desc()
    {
        if(felicity.curState==felicityRope)
            "The four yards of green and purple rope are stretched straight out
            across the swamp, with Felicity tightly holding on to the far
            end. ";
        else
            "It's a neat coil of about four yards of rope made of twisted green
            and purple fibres. ";
    }
    dobjFor(Drop)
    {
        action()
        {
            inherited;
            if(felicity.curState != felicityRope)
            {
                "As the rope leaves your grasp it turns back into a snake. ";
                snake.moveInto(location);
                snake.setCurState(snakeTalking);
                "<q>Well, that was a ropey experience,</q> remarks the snake. ";
                rope.moveInto(nil);
            }
        }
    }
    dobjFor(Pull)
    {
        preCond = [objHeld]
        action()
        {
            if(felicity.curState == felicityRope)
                switch(++pulls)
            {
            case 1:
                "You pull as hard as you can, while Felicity holds on as tight
                as she can. The swamp seems determined to hang on to her, for
                at first she hardly budges, but you are just as determined to
                pull her free, so you tug with all your might, and she begins
                to be dragged towards you, lifting a few inches out of the
                swamp in the process.\b
                <q>Well done!</q> she calls encouragingly, <q>Keep trying and
                we'll be fine!</q><.p>";
                break;
            case 2:
                "You give the rope another tug, even though your hands are now
                becoming chaffed and sore. The way the swamp seems to be
                hanging on to Felicity you'd think it was almost deliberately
                trying to claim her, but you continue to pull nonetheless,
                until the sweat on your brow runs down into your eyes and you
                can taste its salt tang on your tongue.\b
                But your efforts are not entirely in vain, since when you are
                at last forced to pause for rest you can see that Felicity is
                noticeably nearer the shore.\b
                <q>One more go should do it!</q> she calls encouragingly,
                though you think you detect a note of desperation in that
                encouragement.<.p>";
                break;
            default:
                "You tug with all your might one more time, and finally manage
                to pull Felicity free of the sucking marsh. As she comes within
                reach you drop the rope and grab her hand. At once the rope
                changes back into a snake and slithers contentedly across the
                swamp, where it vanishes from sight. But you hardly spare a
                thought for the snake, since your attention is fully focused on
                Felicity; with both hands you tug on her arm to pull her free
                of the last foot of vile-smelling swamp. Then, suddenly, she
                <i>is</i> free: your final tug pulls her clear of the swamp and
                into you arms, where she clings to you tightly, her soft blonde
                hair against your cheek, as she pants, <q>Thank you;
                <i>thank</i> you.</q><.p>";
                unSnake.moveInto(location);
                moveInto(nil);
                felicity.moveIntoForTravel(swampside);
                felicity.setCurState(felicityFollowing);
                achievement.awardPointsOnce;
                new Fuse(self, &reset, 1);
                break;
            }
            else
                inherited;
        }
    }
    dobjFor(AttachTo) { verify() { } }
    dobjFor(FastenTo) { verify() { } }
    achievement: Achievement { +2 "rescuing Felicity from the swamp" }
    pulls = 0
    reset() { pulls = 0; }
;

grammar adjWord(gAndP) :
    'green' 'and' 'purple'
    : SpecialNounPhraseProd
    getMatchList = [snakeMarkings, rope, snake, unSnake]    
    getAdjustedTokens =
    ['green', &adjective, 'and', &adjective, 'purple', &adjective]
;

unSnake : Unthing
    vocabWords = (snake.vocabWords)
    name = (snake.name)
    notHereMsg = 'He\'s no longer here; he vanished into the swamp. '
;
