prev | toc | next
 

3.3 Program Calls

Most Argo programs involve relatively little inter-program communication beyond frequent calls to lib-argo. In some cases, though, Argo programs call each other, handing off a task to be handled. An example would be when a player uses the +cast command to cast a spell in the standard set, such as Invisibility. In this case, several programs would be involved:

  1. The +cast command is linked to asys-magic, which will perform various initialization tasks: make sure the character knows the spell, find the target, make sure the target is valid, make sure the mage has needed components and materials, etc. It would record any data that will be needed later, by other programs involved in handling the spell, in a directory on the player used to record data for the events system (@a/eloop/). This would include information about what the user's current action is: the player's @a/eloop/act property would be set to #castinvisibility. It would then call the event manager.
  2. The event manager will start an event loop for the player if needed. At the player's turn to act, it will perform recoveries (for stun, fatigue, etc.), run some checks (does the user still have the weapons and armor he's supposed to? have events in the room been paused?, etc.), and clean up some props that hold data that is only applicable for one turn. The event manager also calls asys-sysscan in this phase, which checks properties on room #0 for reflists holding the dbrefs of objects that outstanding high-priority checks.
  3. The system scanner checks props on room #0, obtaining the dbrefs of objects that have outstanding high priority checks as a result of events... creatures that have been summoned by a spell and will only remain a certain number turns, exits that have been locked or unlocked by a skill or spell and will need to be reset to their normal locks after a certain number turns or seconds, etc. When these checks complete, asys-syscan exits, and control returns to the event manager.
  4. The event manager will then retrieve the contents of the prop indicating the user's current action (@a/eloop/act), and check the global @a/calls/ directory to see if there is a program that should handle this particular action. With a standard Argo installation, room #0's @a/calls/castinvisibility property is set to the dbref of asys-stdspells... The event manager will call asys-stdspells to handle this particular spell casting event.
  5. Asys-spells does some checks of its own (is the target still valid? has the user been attacked this turn, requiring a Presence roll?, etc.), uses up materials needed by the spell, rolls for success and defence, and applies the appropriate results (in this case, setting props and/or flags to indicate that the target is now invisible, and other props so that Argo will be able to make the target visible again when the spell wears off). Asys-stdspells would then exit, and control would return to the event manager.
  6. Asys-eventmgr will sleep for one turn, then check the contents of the user's @a/eloop/ directory and act upon it.

Many of these places in the code where Argo determines on the fly whether it needs to call another program are basic to the system, and are hard coded in. However, there are also six places — or six types of events — that check for program calls in contexts where new, non-standard Argo programs are likely to be invoked:

  1. Once per turn, before a player acts, asys-eventmgr checks to see if there is a program to handle additional recoveries and upkeep tasks, beyond those required by the standard Argo programs.
  2. Once per turn, asys-event manager checks to see if there is a program call for the action specified in the user's @a/eloop/act property, as discussed above.
  3. When a user attacks with a weapon, asys-combat checks to determine if there is a program to calculate successful attacks for the type of weapon the user currently has readied, which is stored in the user's @a/eloop/weapon property.
  4. When a user attacks without a weapon (i.e., the user has no @a/eloop/weapon property), asys-combat checks to determine if there is a program to calculate successful unarmed attacks.
  5. When a player is successfully attacked, asys-combat checks to determine if there is a program to handle defence for the current type of weapon.

A few notes (which will make more sense after the example programs have been discussed on following pages):

The weapon `type' mentioned above refers to the damage type of the weapon, such as `conventional', `cellular', or `resistant', not the class.

The format for the global @a/calls/ property indicating which program to call in response to a particular event is as follows:

A program to be called by asys-eventmgr to handle additional or customized per-turn recovery and upkeep tasks is indicated by the property @a/calls/turnupkeep; the program is called with "#turnupkeep" on the stack.

A program to be called by asys-eventmgr when the current action is a skill with coded effects is indicated by the property @a/calls/usexxx, where `xxx' is the name of the skill. For example, if asys-thieves has the dbref #1234, then room #0 will have a setting of @a/calls/uselockpicking:#1234, indicating that program #1234 is to be called when the Lockpicking skill is used. The program will be called with the string "#uselockpicking" on the stack, allowing asys-thieves to determine what function should be invoked.

A program to be called by asys-eventmgr when the current action is a spell with coded effects is indicated by the property @a/calls/castxxx, where `xxx' is the name of the spell. If the spell were Invisibility, the program would be called with "#castinvisibility" on the stack.

A program to be called by asys-eventmgr when the current action is a psiab with coded effects is indicated by the property @a/calls/focusxxx, where `xxx' is the name of the psiab. If the psiab were Obscure, the program would be called with "#focusobscure" on the stack.

A program to be called by asys-combat when determining success with a particular type of weapon attack is indicated by the property @a/calls/calcxxxattack, where `xxx' is the damage type of the current readied weapon. A MUCK that deals with vampires and werewolves who deal and are susceptible to `resistant' damage might well have a global @a/calls/calcresistantattack property, indicating the program to be called when attacks of this type are made.

A program to be called by asys-combat when determining success with an unarmed attack is indicated by the property @a/calls/calcbareattack; the program would be called with "#calcbareattack" on the stack (asys-combat has its own, `native' way of handling unarmed combat, as discussed in the Player Guide... this would be for use on a MUCK where the rather generic unarmed combat system has been replaced with another, more specifically suited to the needs of the world).

A program to be called by asys-combat when determining defence against a particular type of weapon attack is indicated by the property @a/calls/calcxxxdefence, where `xxx' is the damage type of the current readied weapon. A MUCK that dealt with vampires and werewolves who deal and are susceptible to `resistant' damage might well have a global @a/calls/calcresistantdefence property, indicating the program to be called when attacks of this type are made.

A program to be called by asys-combat when determining defence against unarmed attacks is indicated by the property @a/calls/calcbaredefence; the program will be called with "#calcbaredefence" on the stack.

prev | toc | top | next