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 THROW
{
  i32 side;    // ReadOnly - 0=left, 1=right
  i32 abort;   // default=0 - non-zero to abort action
  i32 facing;  // ReadOnly - N,E,S,W
  i32 range;   // WriteOnly
  i32 damage;  // WriteOnly
  i32 decayRate// WriteOnly
};



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;
  THROW          throw;
};

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 )
AttackX
AttackY
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
14 - 0
15 - 0
16 - 0
17 - 0
18 - 0
19 - 0
20 - 0
21 - 0
22 - 0
23 - 0

Here is how things happen: