Party Attack Filter
Using CSBuild, you can specify a DSA that will be called whenever the party invokes any of the attack options such as SHOOT, BASH, FLIP, etc. The parameters of the attack will be made available to the DSA and can be modified by the DSA. See the flowchart of the overall structure. The DSA will ( usually ) be activated three times:

1. PreAttack - The parameters that will be used to determine the results and effectiveness of the attack are recorded in the Filter Parameter area. An S0 message is sent to the Attack Filter DSA. The DSA can modify the attack type, abort the attack, change some parameters, etc. Unless the attack is aborted by the DSA ( by setting the attackType parameter to a negative number ) the following two steps will be executed.
2. Attack - A C0 message is sent to the DSA just prior to the attack. Again, the DSA can examine and modify various parameters. Many of the attack types have extra parameters that are defined only for that one attack type.
3. PostAttack - A T0 message is sent to the DSA - After the attack is completed, the DSA will be called again and given an opportunity to modify the character's disable time, decrease in stamina, and the experience gained by the attack. Also, at this time we will 'Activate' the monster that was attacked. Normally the monster would have to wait for a 'Movement Timer' to expire. But if the parameter 'activateMonster' is non-zero then the monster is give a chance to move immediately. Lord Chaos might attempt to escape from a Fusion attack, for example.

All of the variables used by the attack code are available to the DSA in the parameter area. Additionally, ten variables in the parameter area that are not used by the attack code will be set to zero before the first call to the DSA, will never be changed by the attack code, and are available to the DSA to 'remember' things between the calls to the DSA. It is guaranteed that each of the three calls will occur once even in cases like FLIP or CLIMBDOWN where no monster is involved and no damage is done (exception: If attack is aborted by the pre-attack filter then the second and third calls are omitted. ).
Official Parameter list ******** PRELIMINARY *********
enum ATTACKDATATYPE
{
ADT_WarCry = 1, See War Cry Etc.
ADT_Physical = 2,
ADT_Spell = 3,
ADT_HitDoor = 4,
ADT_Shoot = 5,
ADT_Flip = 6,
ADT_Shield = 7,
ADT_FluxCage = 8, See Party Attack Fluxcage
ADT_Fusion = 9,
ADT_Heal = 10,
ADT_Window = 11,
ADT_ClimbDown = 12,
ADT_FreezeLife = 13,
ADT_Light = 14,
ADT_Throw = 15,
ADT_Default = 16 //Block, Hit
};
struct SHIELD // dataType = ADT_Shield
{
// atk_SPELLSHIELD
// atk_FIRESHIELD
i32 mustHaveMana;
i32 strength;
};
struct FLIP // dataType = ADT_Flip
{
// atk_FLIP
i32 heads;
};
struct SHOOT //dataType = ADT_Shoot
{
// atk_SHOOT
i32 success;
i32 range;
i32 damage;
i32 decayRate;
};
struct HITDOOR //dataType = ADT_HitDoor
{
// atk_BASH:
// atk_HACK:
// atk_BERZERK:
// atk_KICK:
// atk_SWING:
// atk_CHOP:
i32 strength;
};
struct WARCRYETC //dataType = ADT_WarCry
// atk_CONFUSE:
// atk_WARCRY:
// atk_CALM:
// atk_BRANDISH:
// atk_BLOWHORN:
{
i32 mastery;
i32 skillIncrement;
i32 effectiveMastery;
i32 requiredMastery;
};
struct PHYSICALATTACK //dataType = ADT_Physical
{
// atk_BASH:
// atk_HACK:
// atk_BERZERK:
// atk_KICK:
// atk_SWING:
// atk_CHOP:
// atk_DISRUPT:
// atk_JAB:
// atk_PARRY:
// atk_STAB2:
// atk_STAB1:
// atk_STUN:
// atk_THRUST:
// atk_MELEE:
// atk_SLASH:
// atk_CLEAVE:
// atk_PUNCH:
i32 monsterDamage;
i32 staminaAdjust;
i32 skillAdjust;
i32 attackedMonsterOrdinal;
};
struct SPELLATTACK //dataType = ADT_Spell
{
// atk_LIGHTNING:
// atk_DISPELL:
// atk_FIREBALL:
// atk_SPIT:
// atk_INVOKE
i32 spellRange;
i32 spellType;
i32 decrementCharges; // if non-zero (default = 1)
};
struct HEAL
{
// atk_HEAL
i32 HPIncrement;
};
struct FREEZELIFE
{
i32 oldTime;
i32 deltaTime;
};
struct LIGHT
{
i32 deltaLight;
i32 decayRate;
i32 time;
};
union ATTDEP
{
WARCRYETC warcryetc;
PHYSICALATTACK physicalAttack;
SPELLATTACK spellAttack;
HITDOOR hitDoor;
SHOOT shoot;
FLIP flip;
SHIELD shield;
HEAL heal;
FREEZELIFE freezeLife;
LIGHT light;
};
struct ATTACKPARAMETERS
{
i32 charIdx;
i32 attackType;
i32 attackX;
i32 attackY;
i32 monsterUnderAttack; //0 if none
i32 monsterType; //or mon_undefined (=99) if none
i32 skillNumber;
i32 staminaCost;
i32 experienceGained;
i32 disableTime;
i32 neededMana;
i32 unused; //damageToMonster;
i32 decrementCharges;
i32 activateMonster;
i32 userInfo[10];
i32 dataType; // = ADT_*****
ATTDEP attdep;
};
The Parameters that are computed prior to the PreAttack call to the Filter
Character Index of atacking character
Attack Type ( See Attack Types )
ID of Monster Under Attack
Type of Monster Uner Attack ( See Monster Types )
Skill Number
Stamina Cost
Experience Gained (Many attacks modify this)
Disable Time (Many attacks modify this).
Needed Mana
Parameters that are computed prior to Attack call to the Filter
Damage to monster
Decrement Charges flag.
Parameters for use by DSA
11 - 0
12 - 0
13 - 0
14 - 0
15 - 0
16 - 0
17 - 0
18 - 0
19 - 0
20 - 0
Here is how things happen:

- Compute parameters 00 through 07. Fill Parameters 08 through 19 with zero.
- Call the PreAttack MPartyAttackFilter.
- Terminate the attack if the Attack Filter set the attackType parameter negative.
- The attacking code is executed, depending on Attack Type. See below for details of each Attack Type. During this time the Attack Filter is called.
- Call the PostAttack Filter.
- Adjust Character Stats and Activate Monster if parameter activateMonster is non-zero.