REO-EE/_module/nss/reo_mod_attack.nss
Jaysyn904 f82740bbbd Initial commit
Initial commit
2024-02-22 13:22:03 -05:00

164 lines
6.7 KiB
Plaintext

// Fires whenever a creature (NPC or PC) attacks another creature. If the creature is equipped with
// a firearm, a particular animation is set and then the combat rules are fired. Provided all requirements are met,
// the attacker plays the animation and may or may not hit his or her target.
// Uses NWNX2 Events plugin.
// Created by Quixsilver on Unknown Date
// Modified by Zunath on May 24th, 2011
#include "adv_include"
//#include "events_include" // Windows
#include "cbt_atk_inc"
#include "rwt_include"
#include "nwnx_events" // Linux
void main()
{
object oPC = OBJECT_SELF;
//object oTarget = GetNWNXEventTarget( );
object oTarget = GetEventTarget();
// Added this check because I think NPCs are lagging the server.
if(GetIsPC(oPC))
{
// Check for sanctuary if this attack is PC versus PC
if(GetIsPC(oTarget) && !GetIsDMPossessed(oTarget))
{
// Either the attacker or target has sanctuary - prevent combat from happening
if(RWT_GetDoesPlayerHaveSanctuary(oPC))
{
FloatingTextStringOnCreature(ColorTokenRed() + "You are under the effects of PVP sanctuary and cannot engage in PVP. To disable this feature permanently refer to the 'Disable PVP Sanctuary' option in your rest menu." + ColorTokenEnd(), oPC, FALSE);
AssignCommand(oPC, ClearAllActions());
return;
}
else if(RWT_GetDoesPlayerHaveSanctuary(oTarget))
{
FloatingTextStringOnCreature(ColorTokenRed() + "Your target is under the effects of PVP sanctuary and cannot engage in PVP combat." + ColorTokenEnd(), oPC, FALSE);
AssignCommand(oPC, ClearAllActions());
return;
}
}
// PC is too busy to make an attack right now
if(GetLocalInt(oPC, "RELOADING_GUN") || GetCurrentAction(oPC) == ACTION_SIT || GetLocalInt(oPC, "LOCKPICK_TEMPORARY_CURRENTLY_PICKING_LOCK"))
{
FloatingTextStringOnCreature(ColorTokenRed() + "You are too busy to attack right now.", oPC, FALSE);
AssignCommand(oPC, ClearAllActions());
return;
}
// PC is dead or dying
if(GetCurrentHitPoints(oPC) < 1)
{
AssignCommand(oPC, ClearAllActions());
return;
}
object oArea = GetArea(oPC);
// Area is designated as "No PVP"
if(GetIsPC(oTarget) && GetLocalInt(oArea, "NO_PVP") == TRUE)
{
AssignCommand(oPC, ClearAllActions());
FloatingTextStringOnCreature(ColorTokenRed() + "You cannot engage in PVP in this area." + ColorTokenEnd(), oPC, FALSE);
return;
}
// Stop trying to attack a DM, dumbass
if(GetIsDM(oTarget))
{
AssignCommand(oPC, ClearAllActions());
return;
}
int bLineOfSight;
// Determine which animation to use
object oRightHand = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
object oLeftHand = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC);
struct GunInfoStruct stGun1Info = GUN_GetGunInfo(oRightHand);
struct GunInfoStruct stGun2Info = GUN_GetGunInfo(oLeftHand);
int iNumberOfShots = 1;
int bUsingFirearm = FALSE;
// All firearms must be marked to use the custom combat system
if(stGun1Info.iGunType == GUN_TYPE_HANDGUN || stGun2Info.iGunType == GUN_TYPE_HANDGUN ||
stGun1Info.iGunType == GUN_TYPE_SMG || stGun2Info.iGunType == GUN_TYPE_SMG ||
stGun1Info.iGunType == GUN_TYPE_MAGNUM || stGun2Info.iGunType == GUN_TYPE_MAGNUM ||
stGun1Info.iGunType == GUN_TYPE_SHOTGUN ||stGun1Info.iGunType == GUN_TYPE_RIFLE ||
stGun1Info.iGunType == GUN_TYPE_ASSAULT_RIFLE)
{
// Disable sanctuary and other OnAreaEnter buffs
effect eEffect = GetFirstEffect(oPC);
while(GetIsEffectValid(eEffect))
{
int iEffectType = GetEffectType(eEffect);
if(iEffectType == EFFECT_TYPE_DAMAGE_REDUCTION || iEffectType == EFFECT_TYPE_SANCTUARY)
{
RemoveEffect(oPC, eEffect);
}
eEffect = GetNextEffect(oPC);
}
// Disable stealth mode
if(GetActionMode(oPC, ACTION_MODE_STEALTH))
{
SetActionMode(oPC, ACTION_MODE_STEALTH, FALSE);
}
bLineOfSight = LineOfSightObject(oPC, oTarget);
// No line of sight and we're using the custom combat system.
// Prevent from continuing.
if(!bLineOfSight || GetLocalInt(oPC, "TEMP_DISABLE_FIRING"))
{
AssignCommand(oPC,ClearAllActions(TRUE));
return;
}
SetAttackAllowed(oPC, TRUE);
bUsingFirearm = TRUE;
}
// Otherwise, the PC isn't using a firearm. Use the default combat system
else
{
SetLocalInt(oPC, CBT_OVR_SVAR_ATTACK_ANIMATION, CBT_OVR_ANIMATION_NONE);
SetAttackAllowed(oPC, FALSE);
SetNumberShotsToFire(oPC, 0);
}
if(bUsingFirearm)
{
BypassEvent();
// Mode is determined by the right hand weapon. Figure out how many shots to fire based on mode
if(GetLocalInt(oRightHand, "GUN_CUR_RATE_OF_FIRE") == 1)
{
iNumberOfShots = 3;
}
SetNumberShotsToFire(oPC, iNumberOfShots);
float fDelay = 0.0;
SetTarget(oPC, oTarget);
if (bUsingFirearm && GetDistanceBetween(oPC, oTarget) > 1.0)
{
if (GetAttackAllowed(oPC))
{
if (GetCommandable(oPC) && GetIsObjectValid(oTarget) && bLineOfSight)
{
AssignCommand(oPC,ClearAllActions(TRUE));
vector vDiff = GetPosition(oPC) - GetPosition(oTarget);
float vAngle = fabs(VectorToAngle(vDiff) - GetFacing(oPC) - 180);
if (vAngle > 1.0 && vAngle < 359.0)
{
TurnToFaceObject(oTarget, oPC);
fDelay = 0.75;
}
// Quick players can sometimes get more than one cycle of shots off each attack. This should stop that.
SetLocalInt(oPC, "TEMP_DISABLE_FIRING", TRUE);
DelayCommand(fDelay, AssignCommand(oPC, MainAttack(oPC, oTarget)));
DelayCommand(fDelay, DeleteLocalInt(oPC, "TEMP_DISABLE_FIRING"));
}
}
}
}
}
}