Server: Revamp Purchase of Wall Weapon Ammo

Adds some utility functions to make grabbing specific pieces of weapon
information in any of a player's slots easier. Fixes some mulekick bugs
as a side effect. Fixes https://github.com/nzp-team/nzportable/issues/52.
This commit is contained in:
moto 2022-10-24 08:44:41 -04:00
parent 328f1f8ee1
commit 19ae55654c
3 changed files with 137 additions and 64 deletions

View file

@ -3,7 +3,7 @@
used to communicate between server and client
Copyright (C) 2021 NZ:P Team
Copyright (C) 2021-2022 NZ:P Team
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -99,7 +99,7 @@ void NotifyNewRound(float to) {
WriteByte(MSG_MULTICAST, EVENT_NEWROUND);
WriteByte(MSG_MULTICAST, to);
multicast('0 0 0', MULTICAST_ALL);
#endif
#endif
#endif
@ -115,24 +115,24 @@ void SetRound(entity client, float to) {
WriteByte(MSG_MULTICAST, to);
msg_entity = client;
multicast('0 0 0', MULTICAST_ONE);
#endif
#endif
#endif
}
void SetPerk(entity client, float to)
void SetPerk(entity client, float to)
{
#ifndef PSP
#ifndef NX
#ifndef CTR
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EVENT_PERK);
WriteLong(MSG_MULTICAST, to);
msg_entity = client;
multicast('0 0 0', MULTICAST_ONE);
#endif
#endif
#endif
@ -143,7 +143,7 @@ void(float to) SwitchWeapon =
#ifndef PSP
#ifndef NX
#ifndef CTR
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EVENT_WEAPONCHANGE);
WriteByte(MSG_MULTICAST, to);
@ -152,7 +152,7 @@ void(float to) SwitchWeapon =
// hotfix for weapon2models not reseting
self.weapon2model = GetWeapon2Model(to);
#endif
#endif
#endif
@ -170,7 +170,7 @@ void(string to, float skin) UpdateVmodel =
WriteByte(MSG_MULTICAST, skin);
msg_entity = self;
multicast('0 0 0', MULTICAST_ONE);
#endif
#endif
#endif
@ -188,7 +188,7 @@ void(string to, float skin) UpdateV2model =
WriteByte(MSG_MULTICAST, skin);
msg_entity = self;
multicast('0 0 0', MULTICAST_ONE);
#endif
#endif
#endif
#endif
}
@ -203,7 +203,7 @@ void(float broadcast_time, float type) BroadcastMessage =
WriteByte(MSG_MULTICAST, broadcast_time);
WriteByte(MSG_MULTICAST, type);
multicast('0 0 0', MULTICAST_ALL);
#endif
#endif
#endif
@ -235,7 +235,7 @@ void(float playernum, float points, float am, float kills, string name, entity p
WriteString(MSG_MULTICAST, name);
multicast('0 0 0', MULTICAST_ALL);
}
#endif
#endif
#endif
@ -259,7 +259,7 @@ void(float count) UpdatePlayerCount = {
#endif
}
void(float newtime, float newtype, entity change) PromptLevelChange =
void(float newtime, float newtype, entity change) PromptLevelChange =
{
#ifndef PSP
#ifndef NX
@ -271,14 +271,14 @@ void(float newtime, float newtype, entity change) PromptLevelChange =
WriteByte(MSG_MULTICAST, newtype);
msg_entity = change;
multicast('0 0 0', MULTICAST_ONE);
#endif
#endif
#endif
}
void(entity who) UpdatePunchangle =
{
void(entity who) UpdatePunchangle =
{
// naievil -- shit logic lol...but result looks clean as fuck...
#ifndef PSP
@ -291,9 +291,9 @@ void(entity who) UpdatePunchangle =
WriteCoord(MSG_MULTICAST, who.punchangle_z);
msg_entity = who;
multicast('0 0 0', MULTICAST_ONE);
vector tempv = who.punchangle;
if (fabs(who.punchangle_x) > 0.01) {
if (who.punchangle_x >= 0.05*tempv_x)
who.punchangle_x -= 0.05*tempv_x;
@ -301,29 +301,29 @@ void(entity who) UpdatePunchangle =
who.punchangle_x -= 0.05*tempv_x;
else
who.punchangle_x = 0;
} else
} else
who.punchangle_x = 0;
if (fabs(who.punchangle_y) > 0.01) {
if (who.punchangle_y >= 0.05*tempv_y)
who.punchangle_y -= 0.05*tempv_y;
else if (who.punchangle_y <= -0.05*tempv_y)
who.punchangle_y -= 0.05*tempv_y;
else
else
who.punchangle_y = 0;
} else
} else
who.punchangle_y = 0;
if (fabs(who.punchangle_z) > 0.01) {
if (who.punchangle_z >= 0.05*tempv_z)
who.punchangle_z -= 0.05*tempv_z;
else if (who.punchangle_z <= -0.05*tempv_z)
who.punchangle_z -= 0.05*tempv_z;
else
else
who.punchangle_z = 0;
} else
} else
who.punchangle_z = 0;
#endif
#endif
#endif
@ -579,6 +579,69 @@ void(entity person, float expamt, float doublepoint) addmoney =
total_powerup_points += expamt;
person.points += expamt;
UpdatePlayerPoints(person.playernum, person.points, expamt, person.kills, person.netname, person);
};
//
// Util_GetPlayerAmmoInSlot(person, slot)
// Returns the reserve ammo the player has in a weapon slot.
//
float(entity person, float slot) Util_GetPlayerAmmoInSlot =
{
switch(slot) {
case 1: return person.currentammo;
case 2: return person.secondaryammo;
case 3: return person.thirdammo;
default: return 0;
}
}
//
// Util_SetPlayerAmmoInSlot(person, slot, ammo)
// Sets the player's reserve ammo in a slot to param3.
//
void(entity person, float slot, float ammo) Util_SetPlayerAmmoInSlot =
{
switch(slot) {
case 1: person.currentammo = ammo;
case 2: person.secondaryammo = ammo;
case 3: person.thirdammo = ammo;
default: return;
}
};
//
// Util_PlayerHasWeapon(peron, comparison, include_pap)
// Checks to see if the Player is holding a weapon in any
// of their three slots. `include_pap` dictates whether to
// consider Pack-A-Punch'd varients. Returns 1, 2, 3 depending
// on the slot the weapon is contained in.
//
float(entity person, float comparison, float include_pap) Util_PlayerHasWeapon =
{
// Storage.
float first, second, third;
// If we're including pap'd weapons, just convert the weapon set to the base
// ones to save on comparison checks.
if (include_pap == true) {
first = EqualNonPapWeapon(person.weapon);
second = EqualNonPapWeapon(person.secondaryweapon);
third = EqualNonPapWeapon(person.thirdweapon);
} else {
first = person.weapon;
second = person.secondaryweapon;
third = person.thirdweapon;
}
// Now do the comparisons
if (first == comparison)
return 1;
if (second == comparison)
return 2;
if (third == comparison)
return 3;
return 0;
};

View file

@ -254,55 +254,64 @@ void () buy_weapon_touch =
float startframe,endframe;
string modelname;
if (other.classname != "player" || other.downed || other.isBuying/* || !isFacing(other, self)*/) {
if (other.classname != "player" || other.downed || other.isBuying) {
return;
}
#ifndef PC
other.Weapon_Name_Touch = GetWeaponName(self.weapon);
#endif
if (self.weapon == other.weapon || self.weapon == other.secondaryweapon
|| self.weapon == EqualNonPapWeapon(other.weapon)
|| self.weapon == EqualNonPapWeapon(other.secondaryweapon)) {
if (self.weapon == EqualNonPapWeapon(other.secondaryweapon)
|| self.weapon == EqualNonPapWeapon(other.weapon))
useprint (other, 3, 4500, other.weapon);
else
useprint (other, 3, self.cost2, self.weapon);
float slot;
// Player has this weapon in any of their slots, PaP'd or not.
if ((slot = Util_PlayerHasWeapon(other, self.weapon, true)) != 0) {
float is_pap = true;
// But the utility function returns the same value if we are NOT PaP'd
if (Util_PlayerHasWeapon(other, self.weapon, false) == slot)
is_pap = false;
// Set the cost and weapon value (for useprint).
float wcost = (is_pap) ? 4500 : self.cost2;
float wep = (is_pap) ? EqualPapWeapon(self.weapon) : self.weapon;
useprint(other, 3, wcost, wep);
if (!other.button7 || other.semiuse || other.isBuying) {
return;
}
if ((self.weapon == other.weapon && other.currentammo >= getWeaponAmmo(self.weapon))
||(self.weapon == other.secondaryweapon && other.secondaryammo >= getWeaponAmmo(self.weapon))) {
return;
}
// Store current Ammo value.
float ammo = Util_GetPlayerAmmoInSlot(other, slot);
// Max carrying capacity of the wall weapon
float wall_ammo = (is_pap) ? getWeaponAmmo(EqualPapWeapon(self.weapon)) : getWeaponAmmo(self.weapon);
// Weapon is already full. Abort.
if (ammo >= wall_ammo)
return;
other.semiuse = true;
if ((other.points < self.cost2 && !IsPapWeapon(other.weapon)) || (other.points < 4500 && IsPapWeapon(other.weapon))) {
// Player doesn't have enough points. Abort.
if (other.points < wcost) {
centerprint(other, STR_NOTENOUGHPOINTS);
return;
}
other.ach_tracker_coll++;
if (self.weapon == other.weapon || (self.weapon == EqualNonPapWeapon(other.weapon))) {
other.currentammo = getWeaponAmmo(self.weapon);
} else if (self.weapon == other.secondaryweapon || (self.weapon == EqualNonPapWeapon(other.secondaryweapon)) ) {
other.secondaryammo = getWeaponAmmo(self.weapon);
}
// Set the weapon's ammo to the max capacity.
Util_SetPlayerAmmoInSlot(other, slot, wall_ammo);
sound(other, 0,"sounds/misc/ching.wav", 1, 1);
other.reload_delay = 0;
if (!IsPapWeapon(other.weapon))
addmoney(other, -1*self.cost2, 0);
else
addmoney(other, -1*4500, 0);
// Subtract the cost from player points.
addmoney(other, wcost*-1, 0);
if (self.enemy) {
oldent = self;
self = self.enemy;
@ -402,7 +411,7 @@ void () buy_weapon_touch =
else
{
entity tempe;
//centerprint(other, self.message);
useprint (other, 4, self.cost, self.weapon);
@ -416,6 +425,7 @@ void () buy_weapon_touch =
return;
}
other.semiuse = true;
other.ach_tracker_coll++;
if (other.weapon && !other.secondaryweapon) {
@ -458,7 +468,7 @@ void () buy_weapon_touch =
other.currentmag = 0;
other.weapon = 0;
}
sound(other, 0,"sounds/misc/ching.wav", 1, 1);
other.reload_delay = 0;
addmoney(other, -1*self.cost, 0);
@ -469,7 +479,7 @@ void () buy_weapon_touch =
self = oldent;
}
other.weapon = self.weapon;
other.currentammo = getWeaponAmmo(self.weapon);
other.currentmag = getWeaponMag(self.weapon);
tempe = self;
@ -477,20 +487,20 @@ void () buy_weapon_touch =
startframe = GetFrame(self.weapon,TAKE_OUT_START);
endframe = GetFrame(self.weapon,TAKE_OUT_END);
modelname = GetWeaponModel(self.weapon, 0);
if (self.weapon != W_KAR_SCOPE && self.weapon != W_HEADCRACKER && !IsDualWeapon(self.weapon)) {
self.weapon2model = "";
}
SwitchWeapon(self.weapon);
Set_W_Frame (startframe, endframe, 0, 0, 0, SUB_Null, modelname, false, S_BOTH);//FIXME
#ifndef PC
self.Flash_Offset = GetWeaponFlash_Offset(self.weapon);
self.Flash_Size = GetWeaponFlash_Size(self.weapon);
self.Weapon_Name = GetWeaponName(self.weapon);
#endif
self = tempe;
}

View file

@ -3,7 +3,7 @@
all weapon stats are stored here
Copyright (C) 2021 NZ:P Team
Copyright (C) 2021-2022 NZ:P Team
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -2622,7 +2622,7 @@ float(float wep) GetWepSkin = {
}
float(float wep) EqualNonPapWeapon =
loat(float wep) EqualNonPapWeapon =
{
switch (wep) {
@ -2683,7 +2683,7 @@ float(float wep) EqualNonPapWeapon =
case W_FIW:
return W_M2;
default:
return 0;
return wep;
}
}
float(float wep) EqualPapWeapon =