Skip to content

Instantly share code, notes, and snippets.

@niv

niv/on_attack.c Secret

Created November 16, 2015 15:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save niv/3852cc2086aeaae3573c to your computer and use it in GitHub Desktop.
Save niv/3852cc2086aeaae3573c to your computer and use it in GitHub Desktop.
/*
1 onhand
6 onhand
2 twohanded/left/right - full attack?
3 cwpn l
4 r
5 bite
if (type - 7) > 1 = 9,10,11?
bracers
*/
#define WEAPON_ATTACK_TYPE_ONHAND_ARMED 1
#define WEAPON_ATTACK_TYPE_ONHAND_UNARMED 7
#define WEAPON_ATTACK_TYPE_OFFHAND_ARMED 8
#define WEAPON_ATTACK_TYPE_OFFHAND_UNARMED 6
#define WEAPON_ATTACK_TYPE_OFFHAND_OTHER 2 // !creatureWeapons && isOffhand
#define WEPAON_ATTACK_TYPE_ARMED_ONHAND 1
#define WEPAON_ATTACK_TYPE_ARMED_OFFHAND 2
#define WEAPON_ATTACK_TYPE_CWEAPON_LEFT 3
#define WEAPON_ATTACK_TYPE_CWEAPON_RIGHT 4
#define WEAPON_ATTACK_TYPE_CWEAPON_BITE 5
/**
* Events in order:
* - ResolveAttackRoll
* You can tweak this to prevent attacks from hitting,
* or force specific attack types (even special attacks).
*
* - ResolveDamage
* This is AFTER damage calculation, but before effect
* creation (like damage/death effect).
* You can tweak damage values here.
* You can Stop() this event to prevent actual damage application
* if you want to run your own handler code (for example,
* for special attacks).
*
* You can modify all struct fields, except Target.
*/
struct CNWSCombatAttackData {
/* const */ object Target;
/* const */ int CurrentAttack;
/* const */ int AttackGroup;
// The attack roll. 1 to 20.
int ToHitRoll;
// The critical threat roll. 1 to 20.
int ThreatRoll;
// The to-hit modifier we used for this attack (+AB).
int ToHitMod;
// By how much we missed.
int MissedBy;
// Damage values, right?
int DamageBludgeoning;
int DamagePiercing;
int DamageSlashing;
int DamageMagical;
int DamageAcid;
int DamageCold;
int DamageDivine;
int DamageElectrical;
int DamageFire;
int DamageNegative;
int DamagePositive;
int DamageSonic;
int DamageBase;
// One of WEAPON_ATTACK_TYPE_
int WeaponAttackType;
// One of ATTACK_MODE_
int AttackMode;
int Concealment;
int RangedAttack;
int SneakAttack;
int DeathAttack;
int KillingBlow;
int CoupDeGrace;
int CriticalThreat;
int AttackDeflected;
// One of ATTACK_RESULT_
int AttackResult;
// Attack Types. 0 means regular; any value > 0 is
// the feat id (for example, FEAT_KNOCKDOWN)
int AttackType;
};
#define FIELDS(code) \
code("%hu",AttackGroup) \
code("%hhd",ToHitRoll) \
code("%hhd",ThreatRoll) \
code("%lu",ToHitMod) \
code("%hhd",MissedBy) \
code("%hu",DamageBludgeoning) \
code("%hu",DamagePiercing) \
code("%hu",DamageSlashing) \
code("%hu",DamageMagical) \
code("%hu",DamageAcid) \
code("%hu",DamageCold) \
code("%hu",DamageDivine) \
code("%hu",DamageElectrical) \
code("%hu",DamageFire) \
code("%hu",DamageNegative) \
code("%hu",DamagePositive) \
code("%hu",DamageSonic) \
code("%hu",DamageBase) \
code("%hhd",WeaponAttackType) \
code("%hhd",AttackMode) \
code("%hhd",Concealment) \
code("%lu",RangedAttack) \
code("%lu",SneakAttack) \
code("%lu",DeathAttack) \
code("%lu",KillingBlow) \
code("%lu",CoupDeGrace) \
code("%lu",CriticalThreat) \
code("%lu",AttackDeflected) \
code("%hhd",AttackResult) \
code("%hd",AttackType)
#define FIELD_COUNT 30
struct CNWSCombatAttackData CNWSCombatAttackData_Load(string from);
string CNWSCombatAttackData_Dump(struct CNWSCombatAttackData d);
struct CNWSCombatAttackData ResolveAttackRoll(
object attacker,
struct CNWSCombatAttackData d
);
struct CNWSCombatAttackData ResolveDamage(
object attacker,
struct CNWSCombatAttackData d
);
struct CNWSCombatAttackData ResolveAttackRoll(
object attacker,
struct CNWSCombatAttackData d
)
{
msg_info(
"ResolveAttackRoll:" +
" ToHitRoll: " + itoa(d.ToHitRoll) +
" ToHitMod: " + itoa(d.ToHitMod) +
" WeaponAttackType: " + itoa(d.WeaponAttackType) +
" AttackType: " + itoa(d.AttackType) +
" AttackResult: " + itoa(d.AttackResult) +
""
);
// d.ToHitRoll = 1;
// d.MissedBy = 1;
// d.AttackResult = 0;
// d.AttackType = 1241;
return d;
/* if (is_creature(target) && GetHasFeat(FEAT_DECEPTIVE_WEAKNESS, target))
BroadcastAttackOfOpportunity(target, attacker);
return ATTACKROLL_OVERRIDE_STOP;*/
}
struct CNWSCombatAttackData ResolveDamage(
object attacker,
struct CNWSCombatAttackData d
)
{
msg_info(
"ResolveDamage: " +
" ToHitRoll: " + itoa(d.ToHitRoll) +
// " DamageBludgeoning: " + itoa(d.DamageBludgeoning) +
// " DamagePiercing: " + itoa(d.DamagePiercing) +
" DamageBase: " + itoa(d.DamageBase) +
" WeaponAttackType: " + itoa(d.WeaponAttackType) +
" AttackType: " + itoa(d.AttackType) +
" AttackResult: " + itoa(d.AttackResult) +
""
);
// d.DamagePiercing = 50;
// d.DamageBase = 50;
// msg_info("ResolveDamage: " + itoa(d.DamageBase));
return d;
}
struct CNWSCombatAttackData CNWSCombatAttackData_Load(string from)
{
struct CNWSCombatAttackData ret;
ret.Target = IntToObject(atoi(strtok(from, " ")));
ret.CurrentAttack = atoi(strtok(" "));
#define FIELDS_ITERATOR_SET(fmt,elem) ret.elem = atoi(strtok(" "));
FIELDS(FIELDS_ITERATOR_SET)
return ret;
}
string CNWSCombatAttackData_Dump(struct CNWSCombatAttackData d)
{
string ret;
// ret += "0 "; // const Target
// ret += "0 "; // const CurrentAttack
#define FIELDS_ITERATOR_GET(fmt,elem) ret += itoa(d.elem) + " ";
FIELDS(FIELDS_ITERATOR_GET)
return ret;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment