Skip to content

Commit

Permalink
Add FCNPC_OnWeaponStateChange callback
Browse files Browse the repository at this point in the history
Updated README
  • Loading branch information
ziggi committed Dec 17, 2016
1 parent f2b1c92 commit cc2805f
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 78 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ forward FCNPC_OnFinishPlayback(npcid);
forward FCNPC_OnTakeDamage(npcid, damagerid, weaponid, bodypart, Float:health_loss);
forward FCNPC_OnGiveDamage(npcid, issuerid, weaponid, bodypart, Float:health_loss);
forward FCNPC_OnVehicleTakeDamage(npcid, damagerid, vehicleid, weaponid, Float:x, Float:y, Float:z);
forward FCNPC_OnWeaponShot(npcid, weaponid, hittype, hitid, Float:x, Float:y, Float:z);
forward FCNPC_OnWeaponStateChange(npcid, weapon_state);
forward FCNPC_OnFinishNodePoint(npcid, point);
forward FCNPC_OnChangeNode(npcid, nodeid);
Expand Down Expand Up @@ -197,6 +199,7 @@ native FCNPC_IsAimingAtPlayer(npcid, playerid);
native FCNPC_GetAimingPlayer(npcid);
native FCNPC_IsShooting(npcid);
native FCNPC_IsReloading(npcid);
native FCNPC_TriggerWeaponShot(npcid, weaponid, hittype, hitid, Float:x, Float:y, Float:z, bool:ishit = true);
native FCNPC_EnterVehicle(npcid, vehicleid, seatid, type = MOVE_TYPE_WALK);
native FCNPC_ExitVehicle(npcid);
Expand Down
1 change: 1 addition & 0 deletions pawn/FCNPC.inc.in
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ forward FCNPC_OnTakeDamage(npcid, damagerid, weaponid, bodypart, Float:health_lo
forward FCNPC_OnGiveDamage(npcid, issuerid, weaponid, bodypart, Float:health_loss);
forward FCNPC_OnVehicleTakeDamage(npcid, damagerid, vehicleid, weaponid, Float:x, Float:y, Float:z);
forward FCNPC_OnWeaponShot(npcid, weaponid, hittype, hitid, Float:x, Float:y, Float:z);
forward FCNPC_OnWeaponStateChange(npcid, weapon_state);

forward FCNPC_OnFinishNodePoint(npcid, point);
forward FCNPC_OnChangeNode(npcid, nodeid);
Expand Down
15 changes: 15 additions & 0 deletions src/CCallbackManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,21 @@ int CCallbackManager::OnWeaponShot(WORD wPlayerId, WORD wHitId, BYTE byteHitType
return cReturn;
}

void CCallbackManager::OnWeaponStateChange(WORD wPlayerId, int iWeaponState)
{
int iIndex;
for (auto &amx : m_vAMX) {
// Get the function index
if (!amx_FindPublic(amx, "FCNPC_OnWeaponStateChange", &iIndex)) {
// Push the parameters
amx_Push(amx, iWeaponState);
amx_Push(amx, wPlayerId);
// Execute the callback
amx_Exec(amx, NULL, iIndex);
}
}
}

int CCallbackManager::OnVehicleTakeDamage(WORD wPlayerId, WORD wDamagerId, WORD wVehicleId, BYTE byteWeaponId, CVector vecHit)
{
cell cReturn = 1;
Expand Down
1 change: 1 addition & 0 deletions src/CCallbackManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class CCallbackManager
static int OnTakeDamage(WORD wPlayerId, WORD wDamagerId, BYTE byteWeaponId, int iBodyPart, float fHealthLoss);
static void OnGiveDamage(WORD wPlayerId, WORD wIssuerId, BYTE byteWeaponId, int iBodyPart, float fHealthLoss);
static int OnWeaponShot(WORD wPlayerId, WORD wHitId, BYTE byteHitType, BYTE byteWeaponId, CVector vecPoint);
static void OnWeaponStateChange(WORD wPlayerId, int iWeaponState);
static int OnVehicleTakeDamage(WORD wPlayerId, WORD wDamagerId, WORD wVehicleId, BYTE byteWeaponId, CVector vecHit);
static void OnFinishPlayback(WORD wPlayerId);
static int OnChangeNode(WORD wPlayerId, WORD wNodeId);
Expand Down
172 changes: 94 additions & 78 deletions src/CPlayerData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,91 +426,97 @@ void CPlayerData::UpdateAim()
} else {
m_pPlayer->aimSyncData.byteCameraMode = 53;
}

// Set the weapon state
switch (byteWeaponId) {
case 0:
case WEAPON_BRASSKNUCKLE:
case WEAPON_GOLFCLUB:
case WEAPON_NITESTICK:
case WEAPON_KNIFE:
case WEAPON_BAT:
case WEAPON_SHOVEL:
case WEAPON_POOLSTICK:
case WEAPON_KATANA:
case WEAPON_CHAINSAW:
case WEAPON_DILDO:
case WEAPON_DILDO2:
case WEAPON_VIBRATOR:
case WEAPON_VIBRATOR2:
case WEAPON_FLOWER:
case WEAPON_CANE:
case WEAPON_BOMB:
case WEAPON_CAMERA:
case WEAPON_NIGHTVISION:
case WEAPON_INFRARED:
case WEAPON_PARACHUTE:
SetWeaponState(WEAPONSTATE_NO_BULLETS);
break;

case WEAPON_GRENADE:
case WEAPON_TEARGAS:
case WEAPON_MOLTOV:
case WEAPON_SHOTGUN:
case WEAPON_SAWEDOFF:
case WEAPON_SHOTGSPA:
case WEAPON_RIFLE:
case WEAPON_SNIPER:
case WEAPON_ROCKETLAUNCHER:
case WEAPON_HEATSEEKER:
case WEAPON_SATCHEL:
SetWeaponState(WEAPONSTATE_LAST_BULLET);
break;

case WEAPON_COLT45:
case WEAPON_SILENCED:
case WEAPON_DEAGLE:
case WEAPON_UZI:
case WEAPON_MP5:
case WEAPON_AK47:
case WEAPON_M4:
case WEAPON_TEC9:
case WEAPON_FLAMETHROWER:
case WEAPON_MINIGUN:
case WEAPON_SPRAYCAN:
case WEAPON_FIREEXTINGUISHER:
if (m_bReloading) {
SetWeaponState(WEAPONSTATE_RELOADING);
} else if (m_wAmmo == 1) {
SetWeaponState(WEAPONSTATE_LAST_BULLET);
} else if (m_wAmmo == 0) {
SetWeaponState(WEAPONSTATE_NO_BULLETS);
} else {
SetWeaponState(WEAPONSTATE_MORE_BULLETS);
}
break;

default:
SetWeaponState(WEAPONSTATE_NO_BULLETS);
break;
}
} else {
// Set the camera mode and weapon state
m_pPlayer->aimSyncData.byteCameraMode = 0;
SetWeaponState(WEAPONSTATE_NO_BULLETS);
// Convert the player angle to radians
float fAngle = CMath::DegreeToRadians(GetAngle());
// Calculate the camera target
CVector vecTarget(m_pPlayer->aimSyncData.vecPosition.fX - sin(fAngle) * 0.2f,
m_pPlayer->aimSyncData.vecPosition.fY + cos(fAngle) * 0.2f, m_pPlayer->aimSyncData.vecPosition.fZ);
m_pPlayer->aimSyncData.vecPosition.fY + cos(fAngle) * 0.2f,
m_pPlayer->aimSyncData.vecPosition.fZ);

// Calculate the camera front vector
m_pPlayer->aimSyncData.vecFront = vecTarget - m_pPlayer->aimSyncData.vecPosition;
}

// Update the weapon state
UpdateWeaponState();
// Set the aim sync flag
m_pPlayer->bHasAimSync = true;
}

void CPlayerData::UpdateWeaponState()
{
BYTE byteWeaponId = m_pPlayer->syncData.byteWeapon;
switch (byteWeaponId) {
case 0:
case WEAPON_BRASSKNUCKLE:
case WEAPON_GOLFCLUB:
case WEAPON_NITESTICK:
case WEAPON_KNIFE:
case WEAPON_BAT:
case WEAPON_SHOVEL:
case WEAPON_POOLSTICK:
case WEAPON_KATANA:
case WEAPON_CHAINSAW:
case WEAPON_DILDO:
case WEAPON_DILDO2:
case WEAPON_VIBRATOR:
case WEAPON_VIBRATOR2:
case WEAPON_FLOWER:
case WEAPON_CANE:
case WEAPON_BOMB:
case WEAPON_CAMERA:
case WEAPON_NIGHTVISION:
case WEAPON_INFRARED:
case WEAPON_PARACHUTE:
SetWeaponState(WEAPONSTATE_NO_BULLETS);
break;

case WEAPON_GRENADE:
case WEAPON_TEARGAS:
case WEAPON_MOLTOV:
case WEAPON_SHOTGUN:
case WEAPON_SAWEDOFF:
case WEAPON_SHOTGSPA:
case WEAPON_RIFLE:
case WEAPON_SNIPER:
case WEAPON_ROCKETLAUNCHER:
case WEAPON_HEATSEEKER:
case WEAPON_SATCHEL:
SetWeaponState(WEAPONSTATE_LAST_BULLET);
break;

case WEAPON_COLT45:
case WEAPON_SILENCED:
case WEAPON_DEAGLE:
case WEAPON_UZI:
case WEAPON_MP5:
case WEAPON_AK47:
case WEAPON_M4:
case WEAPON_TEC9:
case WEAPON_FLAMETHROWER:
case WEAPON_MINIGUN:
case WEAPON_SPRAYCAN:
case WEAPON_FIREEXTINGUISHER:
if (m_bReloading) {
SetWeaponState(WEAPONSTATE_RELOADING);
} else if (m_wAmmo == 1) {
SetWeaponState(WEAPONSTATE_LAST_BULLET);
} else if (m_wAmmo == 0) {
SetWeaponState(WEAPONSTATE_NO_BULLETS);
} else {
SetWeaponState(WEAPONSTATE_MORE_BULLETS);
}
break;

default:
SetWeaponState(WEAPONSTATE_NO_BULLETS);
break;
}
}

bool CPlayerData::IsSpawned()
{
return m_bSpawned;
Expand Down Expand Up @@ -823,15 +829,13 @@ void CPlayerData::Process()
SetKeys(m_pPlayer->wUDAnalog, m_pPlayer->wLRAnalog, KEY_AIM);
}
} else if (m_bShooting) {
if (m_wAmmo == 0) {
if (!m_bHasInfiniteAmmo) {
m_bShooting = false;
SetKeys(m_pPlayer->wUDAnalog, m_pPlayer->wLRAnalog, KEY_AIM);
} else {
m_wAmmo = 500;
}
if (m_bHasInfiniteAmmo) {
m_wAmmo = 500;
}
if (m_wAmmo > 0) {
if (m_wAmmo == 0) {
m_bShooting = false;
SetKeys(m_pPlayer->wUDAnalog, m_pPlayer->wLRAnalog, KEY_AIM);
} else {
// Get the shoot time
int iShootTime = GetWeaponShootTime(m_byteWeaponId);

Expand Down Expand Up @@ -1121,7 +1125,16 @@ WORD CPlayerData::GetWeaponSkill(DWORD dwSkill)

void CPlayerData::SetWeaponState(int iState)
{
if (iState == WEAPONSTATE_UNKNOWN) {
return;
}

int iOldState = m_pPlayer->aimSyncData.byteWeaponState;
m_pPlayer->aimSyncData.byteWeaponState = iState;

if (iOldState != iState) {
CCallbackManager::OnWeaponStateChange(m_wPlayerId, iState);
}
}

int CPlayerData::GetWeaponState()
Expand Down Expand Up @@ -1905,6 +1918,9 @@ void CPlayerData::SetVehicle(WORD wVehicleId, BYTE byteSeatId)
m_pPlayer->wVehicleId = wVehicleId;
m_pPlayer->byteSeatId = byteSeatId;
m_dwVehicleDeadTick = 0;
if (byteSeatId == 0) {
SetWeaponState(WEAPONSTATE_UNKNOWN);
}

if (wVehicleId == INVALID_VEHICLE_ID && m_pPlayer->wVehicleId != INVALID_VEHICLE_ID) {
CVehicle *pVehicle = GetVehicle();
Expand Down
1 change: 1 addition & 0 deletions src/CPlayerData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class CPlayerData
WORD GetWeaponSkill(DWORD dwSkill);
void SetWeaponState(int iState);
int GetWeaponState();
void UpdateWeaponState();

int GetWeaponType(BYTE byteWeaponId);
bool SetWeaponReloadTime(BYTE byteWeaponId, int iTime);
Expand Down

0 comments on commit cc2805f

Please sign in to comment.