Skip to content
36 changes: 36 additions & 0 deletions Client/mods/deathmatch/logic/rpc/CWeaponRPCs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ void CWeaponRPCs::LoadFunctions()
{
AddHandler(GIVE_WEAPON, GiveWeapon, "GiveWeapon");
AddHandler(TAKE_WEAPON, TakeWeapon, "TakeWeapon");
AddHandler(TAKE_WEAPONS, TakeWeapons, "TakeWeapons");
AddHandler(TAKE_ALL_WEAPONS, TakeAllWeapons, "TakeAllWeapons");
AddHandler(SET_WEAPON_AMMO, SetWeaponAmmo, "SetWeaponAmmo");
AddHandler(SET_WEAPON_SLOT, SetWeaponSlot, "SetWeaponSlot");
Expand Down Expand Up @@ -185,6 +186,41 @@ void CWeaponRPCs::TakeWeapon(CClientEntity* pSource, NetBitStreamInterface& bitS
}
}

void CWeaponRPCs::TakeWeapons(CClientEntity* pSource, NetBitStreamInterface& bitStream)
{
std::uint32_t count = 0;
if (!bitStream.Read(count))
return;

CClientPed* ped = m_pPedManager->Get(pSource->GetID(), true);
if (!ped)
return;

for (std::uint32_t i = 0; i < count; i++)
{
unsigned char weaponID;
if (!bitStream.Read(weaponID))
return;

if (!CClientPickupManager::IsValidWeaponID(weaponID))
continue;

if (ped->IsLocalPlayer())
{
ped->RemoveWeapon(static_cast<eWeaponType>(weaponID));
}
else
{
CWeapon* playerWeapon = ped->GetWeapon(static_cast<eWeaponType>(weaponID));
if (playerWeapon)
{
playerWeapon->SetAmmoInClip(0);
playerWeapon->SetAmmoTotal(0);
}
}
}
}

void CWeaponRPCs::TakeAllWeapons(CClientEntity* pSource, NetBitStreamInterface& bitStream)
{
CClientPed* pPed = m_pPedManager->Get(pSource->GetID(), true);
Expand Down
1 change: 1 addition & 0 deletions Client/mods/deathmatch/logic/rpc/CWeaponRPCs.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class CWeaponRPCs : public CRPCFunctions

DECLARE_ELEMENT_RPC(GiveWeapon);
DECLARE_ELEMENT_RPC(TakeWeapon);
DECLARE_ELEMENT_RPC(TakeWeapons);
DECLARE_ELEMENT_RPC(TakeAllWeapons);
DECLARE_ELEMENT_RPC(GiveWeaponAmmo);
DECLARE_ELEMENT_RPC(TakeWeaponAmmo);
Expand Down
4 changes: 4 additions & 0 deletions Server/mods/deathmatch/logic/CGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1655,6 +1655,8 @@ void CGame::AddBuiltInEvents()
m_Events.AddEvent("onPlayerChangesProtectedData", "element, key, value", nullptr, false);
m_Events.AddEvent("onPlayerChangesWorldSpecialProperty", "property, enabled", nullptr, false);
m_Events.AddEvent("onPlayerTeleport", "previousX, previousY, previousZ, currentX, currentY, currentZ", nullptr, false);
m_Events.AddEvent("onPlayerWeaponGiven", "weaponID, weaponAmmo, weaponSlot", nullptr, false);
m_Events.AddEvent("onPlayerWeaponTaken", "weaponID, weaponAmmo, weaponSlot", nullptr, false);

// Ped events
m_Events.AddEvent("onPedVehicleEnter", "vehicle, seat, jacked", NULL, false);
Expand All @@ -1663,6 +1665,8 @@ void CGame::AddBuiltInEvents()
m_Events.AddEvent("onPedWeaponSwitch", "previous, current", NULL, false);
m_Events.AddEvent("onPedWeaponReload", "weapon, clip, ammo", nullptr, false);
m_Events.AddEvent("onPedDamage", "loss", NULL, false);
m_Events.AddEvent("onPedWeaponGiven", "weaponID, weaponAmmo, weaponSlot", nullptr, false);
m_Events.AddEvent("onPedWeaponTaken", "weaponID, weaponAmmo, weaponSlot", nullptr, false);

// Element events
m_Events.AddEvent("onElementColShapeHit", "colshape, matchingDimension", NULL, false);
Expand Down
1 change: 1 addition & 0 deletions Server/mods/deathmatch/logic/CPerfStat.RPCPacketUsage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ ADD_ENUM1(SET_VEHICLE_HEADLIGHT_COLOR)
ADD_ENUM1(SET_VEHICLE_DOOR_OPEN_RATIO)
ADD_ENUM1(GIVE_WEAPON)
ADD_ENUM1(TAKE_WEAPON)
ADD_ENUM1(TAKE_WEAPONS)
ADD_ENUM1(TAKE_ALL_WEAPONS)
ADD_ENUM1(SET_WEAPON_AMMO)
ADD_ENUM1(SET_WEAPON_SLOT)
Expand Down
63 changes: 56 additions & 7 deletions Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4807,6 +4807,15 @@ bool CStaticFunctionDefinitions::GiveWeapon(CElement* pElement, unsigned char uc
if (pPed->IsSpawned())
{
unsigned char ucCurrentWeapon = pPed->GetWeaponType();
unsigned char ucWeaponSlot = CWeaponNames::GetSlotFromWeapon(ucWeaponID);

CLuaArguments arguments;
arguments.PushNumber(ucWeaponID);
arguments.PushNumber(usAmmo);
arguments.PushNumber(ucWeaponSlot);
if (!pPed->CallEvent(IS_PLAYER(pElement) ? "onPlayerWeaponGiven" : "onPedWeaponGiven", arguments))
return false;

if (ucCurrentWeapon != ucWeaponID && bSetAsCurrent)
{
// Call our weapon switch command
Expand All @@ -4823,8 +4832,8 @@ bool CStaticFunctionDefinitions::GiveWeapon(CElement* pElement, unsigned char uc
bSetAsCurrent = false;
}

unsigned char ucWeaponSlot = CWeaponNames::GetSlotFromWeapon(ucWeaponID);
unsigned char ucPreviousWeaponID = pPed->GetWeaponType(ucWeaponSlot);

pPed->SetWeaponType(ucWeaponID, ucWeaponSlot);
if (bSetAsCurrent)
pPed->SetWeaponSlot(ucWeaponSlot);
Expand Down Expand Up @@ -4878,8 +4887,14 @@ bool CStaticFunctionDefinitions::TakeWeapon(CElement* pElement, unsigned char uc
// Just because it's the same slot doesn't mean it's the same weapon -_- - Caz
if (pPed->IsSpawned() && pPed->GetWeapon(ucWeaponSlot) && pPed->GetWeaponType(ucWeaponSlot) == ucWeaponID)
{
CLuaArguments arguments;
arguments.PushNumber(ucWeaponID);
arguments.PushNumber(usAmmo);
arguments.PushNumber(ucWeaponSlot);
if (!pPed->CallEvent(IS_PLAYER(pElement) ? "onPlayerWeaponTaken" : "onPedWeaponTaken", arguments))
return false;

CBitStream BitStream;

SWeaponTypeSync weaponType;
weaponType.data.ucWeaponType = ucWeaponID;
BitStream.pBitStream->Write(&weaponType);
Expand Down Expand Up @@ -4930,14 +4945,48 @@ bool CStaticFunctionDefinitions::TakeAllWeapons(CElement* pElement)
CPed* pPed = static_cast<CPed*>(pElement);
if (pPed->IsSpawned())
{
CBitStream BitStream;
m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pPed, TAKE_ALL_WEAPONS, *BitStream.pBitStream));
std::vector<unsigned char> weapons;

for (unsigned char ucWeaponSlot = 0; ucWeaponSlot < WEAPON_SLOTS; ++ucWeaponSlot)
{
pPed->SetWeaponType(0, ucWeaponSlot);
pPed->SetWeaponAmmoInClip(0, ucWeaponSlot);
pPed->SetWeaponTotalAmmo(0, ucWeaponSlot);
unsigned char ucWeaponID = pPed->GetWeaponType(ucWeaponSlot);
unsigned char ucAmmo = pPed->GetWeaponTotalAmmo(ucWeaponSlot);

if (ucWeaponID > 0)
{
CLuaArguments arguments;
arguments.PushNumber(ucWeaponID);
arguments.PushNumber(ucAmmo);
arguments.PushNumber(ucWeaponSlot);

bool shouldTake = true;
if (!pPed->CallEvent(IS_PLAYER(pElement) ? "onPlayerWeaponTaken" : "onPedWeaponTaken", arguments))
shouldTake = false;

if (shouldTake)
{
weapons.push_back(ucWeaponID);

pPed->SetWeaponType(0, ucWeaponSlot);
pPed->SetWeaponAmmoInClip(0, ucWeaponSlot);
pPed->SetWeaponTotalAmmo(0, ucWeaponSlot);
}
}
}

if (!weapons.empty())
{
CBitStream BitStream;
std::uint32_t weaponsTaken = static_cast<std::uint32_t>(weapons.size());

BitStream.pBitStream->Write(weaponsTaken);

for (auto& weaponID : weapons)
{
BitStream.pBitStream->Write(weaponID);
}

m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pPed, TAKE_WEAPONS, *BitStream.pBitStream));
}

return true;
Expand Down
2 changes: 2 additions & 0 deletions Shared/sdk/net/rpc_enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,5 +293,7 @@ enum eElementRPCFunctions

SET_ELEMENT_ON_FIRE,

TAKE_WEAPONS,

NUM_RPC_FUNCS // Add above this line
};
Loading