Browse Source

Fix `FixAmmoSelling` causing invisible pickups

Non-default value of pickup class was used to
spawn pickup when player drops a weapon.
But since we've replaced that class and it doesn't
(or might not) exist on the client - dropped weapons
appeared as invisible.

Catch the moment our custom pickup is spawned and
replace it back with default one.
master
Anton Tarasenko 5 years ago
parent
commit
1a58ba0620
  1. 15
      sources/Features/FixAmmoSelling/FixAmmoSelling.uc
  2. 53
      sources/Features/FixAmmoSelling/MutatorListener_FixAmmoSelling.uc

15
sources/Features/FixAmmoSelling/FixAmmoSelling.uc

@ -170,6 +170,21 @@ public function OnDisabled()
}
}
// Checks if given class is a one of our pickup replacer classes.
public static final function bool IsReplacer(class<Actor> pickupClass)
{
local int i;
if (pickupClass == none) return false;
for (i = 0; i < default.rules.length; i += 1)
{
if (pickupClass == default.rules[i].pickupReplacement)
{
return true;
}
}
return false;
}
// 1. Checks if weapon can be abused and if it can, - fixes the problem.
// 2. Starts tracking abusable weapon to detect when player buys ammo for it.
public final function FixWeapon(KFWeapon potentialAbuser)

53
sources/Features/FixAmmoSelling/MutatorListener_FixAmmoSelling.uc

@ -23,6 +23,15 @@ class MutatorListener_FixAmmoSelling extends MutatorListenerBase
static function bool CheckReplacement(Actor other, out byte isSuperRelevant)
{
if (other == none) return true;
// We need to replace pickup classes back,
// as they might not even exist on clients.
if (class'FixAmmoSelling'.static.IsReplacer(other.class))
{
ReplacePickupWith(Pickup(other));
return false;
}
CheckAbusableWeapon(KFWeapon(other));
CheckAmmoPickup(KFAmmoPickup(other));
return true;
@ -43,6 +52,50 @@ private static final function CheckAmmoPickup(KFAmmoPickup newAmmoPickup)
class'AmmoPickupStalker'.static.StalkAmmoPickup(newAmmoPickup);
}
// This function recreates the logic of 'KFWeapon.DropFrom()',
// since standard 'ReplaceWith' function produces bad results.
private static function ReplacePickupWith(Pickup oldPickup)
{
local Pawn instigator;
local Pickup newPickup;
local KFWeapon relevantWeapon;
if (oldPickup == none) return;
instigator = oldPickup.instigator;
if (instigator == none) return;
relevantWeapon = GetWeaponOfClass(instigator, oldPickup.inventoryType);
if (relevantWeapon == none) return;
newPickup = relevantWeapon.Spawn( relevantWeapon.default.pickupClass,,,
relevantWeapon.location);
newPickup.InitDroppedPickupFor(relevantWeapon);
newPickup.velocity = relevantWeapon.velocity +
Vector(instigator.rotation) * 100;
if (instigator.health > 0)
KFWeaponPickup(newPickup).bThrown = true;
}
// TODO: this is code duplication, some sort of solution is needed
static final function KFWeapon GetWeaponOfClass
(
Pawn playerPawn,
class<Inventory> weaponClass
)
{
local Inventory invIter;
if (playerPawn == none) return none;
invIter = playerPawn.inventory;
while (invIter != none)
{
if (invIter.class == weaponClass)
{
return KFWeapon(invIter);
}
invIter = invIter.inventory;
}
return none;
}
defaultproperties
{
relatedEvents = class'MutatorEvents'