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:
- 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.
- 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.
- 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:
- Clear all parameters to zero.
- Compute parameters 0 through 10.
- 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.