Chapter V describes the scene PC_Unconscious as an example of a scene's internal complexity. As a longer example, the following is the original Inform code for this scene.
!! Scene: PC_Unconscious !! !! The PC succumbs to injuries that prove non-fatal. !! !! > MEvent(attacker: PC_Unconscious[?], PC, rescuer?, ?) !! !! The PC will recover consciousness in various states depending !! on who knocked her unconscious in the first place. The _detail_ !! will indicate the nature the event: +1 is an active rescuing, 0 is !! neutral (no rescue possible), -1 is an imprisonment, and -2 is a !! betrayal (left behind). The LOOK event contained within this event will !! give the awakening location. !! !! Pre: !! * An Attack on PC !! * PC is incapacitated at 0 health. !! * (But usually invoked directly as an interruption by <DT_PC_Falls_Inactive>) !! !! Play: !! First, heals PC back to 2 health and advances the <DemeterTime> by one. !! !! If attacker was a passenger NPC: !! That NPC disarms the PC (if armed). !! !! If PC was in the gondola or observation deck, the PC will then wake on !! the locked observation deck. !! !! Otherwise, depends on surrounding NPCs. If at least one has a positive !! _average(morality, affinity(PC))_, this "rescuer" will have dragged the !! PC back to obs deck. However, if no one cares enough about the PC, !! she'll wake up where she fell (probably locked out: any GoParty will !! advance silently until it has returned). !! !! If attacker was Revenant: !! If no NPCs around, this becomes <PC_Dies>. Otherwise, the revenant !! gets another offscreen <Revenant_Acts>. If there is still an NPC !! standing, then will check affinity/morality and proceed accordingly, !! as described above. If a rescuer is found, PC will wake in gondola in !! their bunk. Rescuer will be there to narrate what happened. !! !! Import 4; Imperative 9. !! MMiddleScene PC_Unconscious with import 4, imperative 9, cause nothing, canPlay [; if (DCharacter__PC.health == 0 && DCharacter__PC has incapacitated) { self.cause = MEventHistory.find(0, nothing, nothing, DV_ATTACK, DCharacter__PC); if (self.cause) { return MList__new(self.cause); } } ], !! Method: getRescuer(victim, bystanders) !! !! Looks through the list of <DNPC> _bystanders_ for the NPC with !! the highest _average(morality, affinity(victim))_. Returns !! said NPC, or nothing if no one has an average > 0. !! getRescuer [ victim bystanders i len npc moral aff highest highestNPC; highest = 0; !needs to be at least higher than this highestNPC = nothing; len = bystanders.size(); for (i = 0 : i < len : i++) { npc = bystanders.get(i); moral = npc.morality.getValue(); aff = (npc.affinities-->victim.affIndex).getValue(); aff = (moral + aff) / 2; if (aff > highest) { highest = aff; highestNPC = npc; } } return highestNPC; ], !PLAY play [event witnesses i sub npc wakeIn disarmedOf hooks deckers; event.actress = self.cause.actress; event.dirObj = DCharacter__PC; witnesses = DNPC__GetActive(); if (event.actress == Revenant) { if (witnesses.size()) { npc = witnesses.get(random(witnesses.size()) - 1); !revenant gets another action while everyone else tries to respond event.add(Revenant_Attacks.playAt(event.loc, true, npc)); !play silently if (npc.health <= 0) { !that npc just fell too witnesses.remove(witnesses.indexOf(npc)); } } if (witnesses.size()) { !still someone standing that might save you event.secondObj = self.getRescuer(DCharacter__PC, witnesses); }else { !left alone with Revenant: PC_Dies MList.destroy(witnesses); sub = MEvent__new(DCharacter__PC, PC_Dies, nothing, nothing, self.cause, event.loc); hooks = Ending_Hooks.getHooks(); sub.predicate.play(sub); if (hooks) { !manual/lazy/play-time reinc sub.reincorporates.join(hooks); !destroys hooks } event.add(sub); event.detail = 0; return; } if (event.secondObj) { !will be dragged back to safety. Even if already in gondola. wakeIn = YourBottomBunk; event.detail = 1; }else { !will be left behind wakeIn = event.loc; event.detail = -2; } }else { !attacked by an NPC !remove any weapons from player (but can't remove from objectloop) disarmedOf = MList.create(); objectloop (i in player) { if (i ofclass DWeapon) { disarmedOf.add(i); } } for (i = 0 : i < disarmedOf.size() : i++) { move disarmedOf.get(i) to event.actress; event.add(MEvent__new(event.actress, DA_Manipulate, DV_TAKE, disarmedOf.get(i), DCharacter__PC, event.loc)); } event.secondObj = self.getRescuer(DCharacter__PC, witnesses); if (event.secondObj || event.loc ofclass DGondolaLocation) { !"rescuer" or gondola NPC will drag you to obs_deck wakeIn = Observation_Deck; event.detail = -1; }else { !will be left behind wakeIn = event.loc; event.detail = -2; } } !remove any revenant (whether fell to NPC or revenant) remove revenant; !Fast-forward any go_party if (MTriggerManager.hasState(DST_GoParty) && DNPC__SelectActive(DST_GoParty.detail)) { !still someone active to lead GoParty !PC just dropped if (DST_GoParty.detail.contains(DCharacter__PC)){ event.add(MEvent__new(nothing, DA_ChangeState, nothing, DST_GoParty, DV_DROP, event.loc, DCharacter__PC)); DST_GoParty.detail.remove(DST_GoParty.detail.indexOf(DCharacter__PC)); } !make sure we can get in (no betrayal possible w/ unconscious PC) give hatch_to_Gondola ~locked; sub = MEvent__new(nothing, GoParty_Offscreen, nothing, nothing, nothing, event.loc); GoParty_Offscreen.reacts = nothing; GoParty_Offscreen.play(sub, true); event.add(sub); } !heal/revive and advance time print "Then everything goes black.^"; new_line; new_line; DCharacter__PC.damage(-1); !prints waking message DemeterTime++; if (DemeterTime > 2) { DemeterTime = -1; } !In the meantime, regardless of where PC is going to wake up, ! move any NPCs in from deck if (door_to_Observation_Deck hasnt locked || DNPC__GetActiveNPCs(DGondolaLocation, true)) { !can get in, or someone to let them in deckers = MDramaManager.getPresent(true, Observation_Deck); for (i = 0 : i < deckers.size() : i++) { !Even if no one around to help, uncons. NPC wake long enough to ! drag themselves in move deckers.get(i) to deckers.get(i).getPassengerRoom(); } MList.destroy(deckers); } !now, finally narrate waking PlayerTo(wakeIn); !will produce a look at new location if (wakeIn == Observation_Deck) { !regardless of whether dragged, left after NPC attack, or fell to rev: give door_to_Observation_Deck ~open; if (door_to_Observation_Deck has lockable) { give door_to_Observation_Deck locked; } if (event.loc ~= Observation_Deck) { !was dragged here new_line; print "Aside from your other injuries, your clothes are rumpled and pulled askew, your wrists are bruised, and your shoulders are sore. In short, it feels like you were dragged out here, though not very gently.^"; } if (disarmedOf.size()) { if (event.loc ~= Observation_Deck) { new_line; print "It also "; }else { new_line; print "It "; } print "seems that someone has relieved you of "; if (disarmedOf.size() > 1) { print "all your potential weapons.^"; }else { print "your ", (name) disarmedOf.get(0), ".^"; } } } new_line; print "You are not sure how much time passed while you were unconscious"; if (~~(wakeIn == Ladderway || wakeIn == WC || wakeIn ofclass DZeppelinLocation)) { print ", but a glance at the sky "; if (wakeIn == Observation_Deck) { print "all around you"; }else { print "through the window here"; } print " shows that it is now "; switch (DemeterTime) { 0: print "night"; 1: print "dawn"; 2: print "late morning"; -1: print "sunset"; } } print ".^"; if (wakeIn == YourBottomBunk) { event.add(MEvent__new(DCharacter__PC, DA_Travel, DV_GO, Your_Room, event.secondObj, event.loc)); move event.secondObj to Your_Room; new_line; print (name) event.secondObj, " leans over you.^"; event.secondObj.speakTo(DCharacter__PC); print "You're awake! I was worried there for a while...~^"; !a brief manual report (too hard to use GoParty_Reports properly here, ! since the GoParty fast forward happens within this scene). event.secondObj.speakTo(DCharacter__PC); print "After you fell, that thing also attacked "; npc = event.get(0).dirObj; if (npc == event.secondObj) { print "me"; }else { event.secondObj.printAddressFor(npc); } print " while I tried to drag you clear."; if (npc == event.secondObj) { print "~^"; print (name) npc, " shows you ", (my) npc, " wounds.^"; npc.speakTo(DCharacter__PC); print "Then, I don't know why, but it suddenly turned and took off! We were both lucky, I guess.~^"; }else { print " I yelled, and for some reason, that suddenly scared the thing off. "; if (npc.health <= 0) { print "But... it wasn't enough to save ", (name) npc, "! "; if (npc.health == 0) { !expired npc.damage(1, true); event.get(0).verb = DV_KILL; } print (CI) npc, "'s dead!~^"; }else { event.secondObj.printAddressFor(npc); print " was injured, but ", (I) npc, " is still alive.~^"; } } } !Otherwise, will wake where fell, which is pretty self explanatory MList.destroy(witnesses); if (disarmedOf) { MList.destroy(disarmedOf); } ], ;
Argax Project : Dissertation :
A Rough Draft Node http://www2.hawaii.edu/~ztomasze/argax |
Last Edited: 14 Apr 2011 ©2011 by Z. Tomaszewski. |