Monster Attack Filter
The Monster Attack Filter capability allows you to modify the standard actions when a monster is about to attack the party. You do this by writing a DSA that modifies the parameters that are used to carry out the attack.
The parameters are computed in the standard way. Then the DSA is activated. The DSA will fetch a copy of the parameters, modify them as desired, then send the parameters back to the runtime engine to be acted upon. When the parameters are fetched, they are placed in an array. The parameters are numbered from 0 through 19 in that array. The following paragraphs describe each of the parameters, its index in the array and how it is computed in the standard way. After the description of the parameters we will discuss how the parameters are used.
The Parameters
[0] Monster ID. This is the "Indirect Pointer Index" of the monster group that is attacking the party. It is a unique identifier among all objects in the dungeon. It can only be reused if the group of monsters is killed. Then it can be reused for any type of object that is created during gameplay.
[1] Monster Type. Giggler, Screamer, etc. See Monster Types.
[2] Monster Index. The index of the particular monster within the group of monsters that is carrying out the attack. 0-3.
[3] Monster Level. This is the dungeon level of the monster.
[4] Monster X. This is the X-coordinate of the monster.
[5] Monster Y. This is the Y-coordinate of the monster.
[6] Monster Position. This is the position of the monster within the cell. 0=NW, 1=NE, 2= SE, 3= SW.
[7] Missile Origin Position. The position within the cell at which any missile will be launched. This is not the same as the Monster Position because if the monster is standing in the rear of the group (relative to the party) then the missile would hit his own companion in front. So the Missile Origin Position is moved to the front of the group (relative to the party).
[8] Missile Range. This is computed by the following sequence of operations:
Range = Monster Descriptor Byte8[4] / 4 + 1
Range = Range + Random(Range)
Range = Range + Random(Range)
[9] Missile Damage. This is set to Monster Descriptor Byte8[4].
[10] Missile Friction. This is the amount subtracted from Missile Range and Missile Damage each time the missile moves.
Standard value is 8;
[11] Direction to Party. The direction from the monster group to the party. 0=North, 1=East, 2=South, 3=West.
[12] Distance to Party. This is what I call Orthogonal Distance. As the taxi drives. Not as the crow flies.
[13] Missile Type. An integer specifying whether Firball, PoisonCloud, etc. See Missile Types.
This is computed from the Monster Type as follows:
Vexirk or Lord Chaos - Random (Fireball 50%) (Dispell, Lightning, Zo, Poisoncloud each 12.5%)
Slime Devil - Poison
Flying Eye - Random (Lightning 87.5%) (Zo 12.5%)
Zytaz - Random (Fireball, Poisoncloud each 50%)
Demon or Dragon - Fireball
Anything else - No Missile
[14] Monster Should Launch Missile - Non-zero if the monster should attack with a missile spell.
Compute with the following sequential steps:
Set to 0.
Set to 1 if Distance To Party is greater than 1.
Set to 1 with 50% probability.
Set to 0 if bits 12-15 of word 14 of the Monster Descriptor are less than 2.
[15] Monster Should Steal - Non-zero if the monster should try to steal an item from the party.
Set to 1 if the monster is a Giggler.
[16] Index of hero to damage. 0 to 3.
This index is computed in one of two ways depending on the Monster Descriptor word 2 bit 4.
If word 2 bit 4 is non-zero then the index is the index of a random, live character.
If word 2 bit 4 is zero then this is the index of the hero closest to the monster. Closest means closest front-to-back (relative to the monster). If two heros are equally close front-to-back then choose the one of the two closest left-to-right.
[17] The ordinal of the Attacking Sound. Zero means silence.
[18] Disable Time - Set to -1 to mean unused. Perhaps someday we can do this.
[19] Unused. Set to -1.
The Attack - or - How the Parameters are used.
The sound of the attack is queued. Then we chose the Type-of-Attack and carry it out. There are three different Types-of-Attack: 1) Missile, 2) Theft, 3) Physical attack. We will describe how the Type-of-Attack is selected and then how each type is carried out.
Selecting the Type-of-Attack
First we look to see if the monster should launch a missile (parameter Monster Should Launch Missile is non-zero). If so, the monster attempts to launch the missile and we are done. Note that if the Monster Should Launch Missile then the parameter named Monster Should Steal is ignored. Note that if the Monster Should Launch Missile but the Missile Type is NONE then nothing is launched and the attack totally fizzles (you can completely abort an attack this way).
Second we look to see if the monster should steal an item from the party (parameter Monster Should Steal is non-zero). If so, the monster attempts to steal an item and, whether or not it is successful, the attack is complete.
Lastly, the monster attempts to inflict physical damage.
Launching a Missile
If the Missile Type is NONE (or illegal) then no missile is launched and the attack is complete. Otherwise we launch the missile specified by parameter Missile Type from the location indicated by parameters Monster X, monster Y at Missile Origin Position. The missile will trave in the direction indicated by parameter Direction to Party. Its range and damage will be set to parameters Missile Range and Missile Damage and its friction will be set to the parameter Missile Friction.
Stealing an Item
The monster will attempt to steal an item from the hero designated by the paramter Index of Hero to Damage. The theft may or may not be successful but in either case the attack is complete. Someday we may use one of the unused parameters to specify which item or kind of item should be stolen.
Inflicting Physical Damage
The standard mechanisms are used to cause damage to the hero specified by Index of Hero to Damage. The attack may or may not be successful. In any case, the attack is complete.