------------------------------------------------------------------------- -- notify.ala (version 1.0) -- by stephen.griffiths@xtra.co.nz, June 1999 -- -- example ALAN program showing a way to notify the player of -- score changes ------------------------------------------------------------------------- -- Use the 'proposed standard library' version 0.2 for standard verbs etc $INCLUDE 'std.i' ------------------------- Notification Stuff ---------------------------- ACTOR hero HAS oldscore 0. --records previous score so 'checkscore' event -- can compare with the current score IS notify_on. --set by 'notify' verb, records whether -- player wants to see score messages or not IS NOT seen_notify. --records whether player has seen the notify verb -- instructions yet END ACTOR. ---- -- This event is run each turn to check if the game score is greater than -- the last recorded score (which is stored in the Hero's 'oldscore' -- attribute). If the score is greater then the 'Score has gone up...' -- text is displayed (as long as the player hasn't disabled it by using the -- 'notify' verb - which sets 'notify_on' to off -- - ie;hero 'IS NOT notify_on'.) -- NOTE: The ALAN scoring system records the game score in a thing called -- score. It isn't called score OF anything; its just 'score'. -- NOTE: This event assumes score can only increase, if score can go -- down then would need to modify this code a bit. EVENT checkscore IF oldscore OF hero < score THEN IF hero IS notify_on THEN -- ie: the player wants to see -- score msgs "$i(Your score has gone up by" SAY (score - oldscore OF hero). "points." -- this msg only displayed the first time player is notified -- of a score change IF hero IS NOT seen_notify THEN MAKE hero seen_notify. "You can use the NOTIFY command to disable score change messages like this one." END IF. "$$)" END IF. SET oldscore OF hero TO score. END IF. -- run the 'checkscore' event again next turn SCHEDULE checkscore AT hero AFTER 1. END EVENT. ---- -- 'notify' verb allows the players to disable the score change -- messages. (Some players find such messages annoying.) -- the verb toggles the hero's 'notify_on' attribute on and off. That -- attribute is checked by the 'checkscore' event to determine whether -- to display the score msg or not. SYNTAX notify = notify. VERB notify DOES IF hero IS notify_on THEN MAKE hero NOT notify_on. "Score notification is now disabled. (You can turn it back on using the NOTIFY command again.)" ELSE MAKE hero notify_on. "Score notification is now enabled. (You can turn it off using the NOTIFY command again.)" END IF. END VERB. ---------------------------The "Game" Stuff ---------------------------- LOCATION threshold NAME 'On' the threshold EXIT north TO winmessage CHECK door IS NOT closed ELSE "The door isn't open." END EXIT. END LOCATION. LOCATION winmessage NAME 'Congratulations ...' DESCRIPTION "$i .... you've won the game!$p" SCORE. QUIT. END LOCATION. ---- -- a new verb so the player can 'look under mat' SYNTAX look_under = 'look' under (obj) * WHERE obj ISA OBJECT OR ACTOR ELSE "You can't look under that." VERB look_under DOES "You can't look under that." END VERB. -- so the player can 'lift mat' SYNONYMS lift = search. ---- OBJECT door AT threshold IS NOT takeable. IS closable. IS closed. IS lockable. IS locked. DESCRIPTION "There is a" IF door IS closed THEN "closed" ELSE "open" END IF. "door to the north." -- most of the code for these verbs is in the standard library -- there's just a few extra bits needed here for this particular -- game. eg: checking if door is locked in the open verb and the -- awarding of points for some actions VERB Open CHECK door IS NOT locked ELSE "The door seems to be locked." DOES SCORE 3. END VERB. VERB unlock CHECK doorkey IN Inventory ELSE "You'll need a key to unlock it." DOES -- this event also run if player uses the unlock_with verb -- I can't combine the two verbs ('VERB unlock, unlock_with') -- because the two verbs have incompatible SYNTAX's (see -- lock.i in the standard library files for their syntaxes.) -- see the comments with the events later in this source code -- for reasons why I used an event rather than just repeated -- the required text in each verb. SCHEDULE door_unlocked AT hero AFTER 0. END VERB. VERB unlock_with CHECK door IS closed ELSE "The door is open!" AND key = doorkey ELSE "The $2 doesn't seem to be the right thing to unlock this door." DOES -- (also scheduled by unlock verb, see comments there) SCHEDULE door_unlocked AT hero AFTER 0. END VERB. END OBJECT. OBJECT mat AT threshold VERB take, pick_up1, pick_up2 DOES IF doorkey IS NOT found THEN -- (event also used in 'search' verb below, see -- comments in 'unlock' verb above about this technique.) SCHEDULE find_key AT hero AFTER 0. END IF. END VERB. VERB search, look_under DOES ONLY IF doorkey IS NOT found THEN -- (event also used in 'take' verb above, see comments -- in 'unlock' verb further above about this technique.) SCHEDULE find_key AT hero AFTER 0. ELSE "You find nothing unusual." END IF. END VERB. VERB examine, look_at DOES ONLY "Its a pretty ordinary mat" IF doorkey IS NOT found THEN "with a slight lump where something seems to be lying beneath it" END IF. "$$." END VERB. END OBJECT. OBJECT doorkey NAME key IS NOT found. VERB take, pick_up1, pick_up2 DOES SCORE 2. END VERB. END OBJECT. ---- -- These two events are scheduled by verbs in the door object. These events -- are run in the same turn as the player uses the verbs (ie: 'AFTER 0') -- There are three reasons for using these events rather than just having the -- code in the verbs: -- - The code would need to be repeated in two or more verbs so using -- events saves the programmer a little repetitive typing -- - If the 'SCORE' statements in these verbs were repeated in two -- or more verbs then ALAN would add the total value of those -- repeated 'SCORE's to the game's maximum points which would -- then make the game's maximum points figure unattainable by -- the player -- - It gives me a chance to demonstrate that the 'checkscore' event -- must be SCHEDULE'd to run again (AFTER 0 turns) by any events -- that change the score but weren't SCHEDULE'd earlier in the -- game than the current turn's 'checkscore' event. This is -- because the 'checkscore' event that is run every turn (by the -- checkscore event SCHEDULE'ing itself each turn to run AFTER 1) -- will be executed before these extra events are (because ALAN -- executes events in the order in which they were scheduled.) So -- these events SCHEDULE an extra execution of 'checkevent' which -- will be run on the current turn ('AFTER 0') in order to catch -- the score changes and notify the player about them on the -- current turn. -- A little further explanation of that third point .... -- The ALAN order of execution on each player turn is: -- - execute the player command -- - check any defined 'RULES' -- - execute each actor's current script -- - (checking the RULES again after each script) -- - execute each event scheduled for this turn (in the -- order they were scheduled) -- - end of turn (wait for next player input) -- So in this example where executing the player's command -- schedules an event to executed on the current turn the order is: -- - execute player command - eg 'unlock door'- -- (which schedules event 'door_unlocked' to happen -- 'after 0' turns, ie: this turn.) -- - check the rules (aren't any) -- - execute scripts (aren't any) -- - check rules again (no scripts so no need) -- - execute events -- - 'checkscore' (scheduled to run 'after 1' by the -- previous turn) -- - "nope, score not changed" -- - schedules 'checkscore' to run *next* turn -- -- - 'door_unlocked' (scheduled on this turn by 'unlock' -- verb) -- - increases the score -- - schedules 'checkscore' to run again on -- *this* turn -- -- - 'checkscore' (just scheduled by 'door_unlocked') -- - "hmmm score's gone up! display msg!" -- - schedule 'checkscore' to run *next* turn -- (already scheduled by previous 'checkscore' -- but no problem - Alan doesn't run it twice -- next turn or anything.) -- - end of turn EVENT find_key "Lifting the mat reveals a key." MAKE doorkey found. LOCATE doorkey HERE. SCORE 2. SCHEDULE checkscore AT hero AFTER 0. END EVENT. EVENT door_unlocked SCORE 3. SCHEDULE checkscore AT hero AFTER 0. END EVENT. --------------------------- Start Section ---------------------------- START AT threshold. "'Notify' - ALAN game showing how to program score change messages $iby stephen.griffiths@xtra.co.nz" "$pBrief summary $i- use an attribute to record the current score. $i- run an event each turn to check if player's score now changed from the recorded score. (And display a message if its changed.) $i- note need to ensure the 'check score' event is run after any other events that might affect the score. (An event changing player score is probably a rare occurence but there's examples in this demo game.) $i- provide a way for the player to turn off the score messages if they want (eg: a 'notify' verb like in this demo.) $i- Look at the source code for more details." "$p--------------------------------------------------------------- $nNow let's play the game ..... You need to get through this door." SCHEDULE checkscore AT hero AFTER 0.