diff --git a/sources/Features/FixAmmoSelling/FixAmmoSelling.uc b/sources/Features/FixAmmoSelling/FixAmmoSelling.uc index 9b43f8a..dc82e43 100644 --- a/sources/Features/FixAmmoSelling/FixAmmoSelling.uc +++ b/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 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) diff --git a/sources/Features/FixAmmoSelling/MutatorListener_FixAmmoSelling.uc b/sources/Features/FixAmmoSelling/MutatorListener_FixAmmoSelling.uc index 21113e8..f0e2b41 100644 --- a/sources/Features/FixAmmoSelling/MutatorListener_FixAmmoSelling.uc +++ b/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 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'