First commit
This commit is contained in:
commit
b289a44a9f
44 changed files with 4578 additions and 0 deletions
85
sources/Features/FixAmmoSelling/AmmoPickupStalker.uc
Normal file
85
sources/Features/FixAmmoSelling/AmmoPickupStalker.uc
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/**
|
||||
* This actor attaches itself to the ammo boxes
|
||||
* and imitates their collision to let us detect when they're picked up.
|
||||
* Copyright 2020 Anton Tarasenko
|
||||
*------------------------------------------------------------------------------
|
||||
* This file is part of Acedia.
|
||||
*
|
||||
* Acedia is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Acedia is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
class AmmoPickupStalker extends Actor;
|
||||
|
||||
// Ammo box this stalker is attached to.
|
||||
// If it is destroyed (not just picked up) - stalker must die too.
|
||||
var private KFAmmoPickup target;
|
||||
|
||||
// This variable is used to record if our 'target' ammo box was in
|
||||
// active state ('Pickup') last time we've checked.
|
||||
// We need this because ammo box's 'Touch' event can fire off first and
|
||||
// force the box to sleep before stalker could catch same event.
|
||||
// Without this variable we would have no way to know if player
|
||||
// simply walked near the place of a sleeping box or actually grabbed it.
|
||||
var private bool wasActive;
|
||||
|
||||
// Static function that spawns a new stalker for the given box.
|
||||
// Careful, as there's no checks for whether a stalker is
|
||||
// already attached to it.
|
||||
// Ensuring that is on the user of the function.
|
||||
public final static function StalkAmmoPickup(KFAmmoPickup newTarget)
|
||||
{
|
||||
local AmmoPickupStalker newStalker;
|
||||
if (newTarget == none) return;
|
||||
|
||||
newStalker = newTarget.Spawn(class'AmmoPickupStalker');
|
||||
newStalker.target = newTarget;
|
||||
newStalker.SetBase(newTarget);
|
||||
newStalker.SetCollision(true);
|
||||
newStalker.SetCollisionSize(newTarget.collisionRadius,
|
||||
newTarget.collisionHeight);
|
||||
}
|
||||
|
||||
event Touch(Actor other)
|
||||
{
|
||||
local FixAmmoSelling ammoSellingFix;
|
||||
if (target == none) return;
|
||||
// If our box was sleeping for while (more than a tick), -
|
||||
// player couldn't have gotten any ammo.
|
||||
if (!wasActive && !target.IsInState('Pickup')) return;
|
||||
|
||||
ammoSellingFix = FixAmmoSelling(class'FixAmmoSelling'.static.GetInstance());
|
||||
if (ammoSellingFix != none)
|
||||
{
|
||||
ammoSellingFix.RecordAmmoPickup(Pawn(other), target);
|
||||
}
|
||||
}
|
||||
|
||||
event Tick(float delta)
|
||||
{
|
||||
if (target != none)
|
||||
{
|
||||
wasActive = target.IsInState('Pickup');
|
||||
}
|
||||
else
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
// Server-only, hidden
|
||||
remoteRole = ROLE_None
|
||||
bAlwaysRelevant = true
|
||||
drawType = DT_None
|
||||
}
|
||||
372
sources/Features/FixAmmoSelling/FixAmmoSelling.uc
Normal file
372
sources/Features/FixAmmoSelling/FixAmmoSelling.uc
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
/**
|
||||
* This feature addressed an oversight in vanilla code that
|
||||
* allows clients to sell weapon's ammunition.
|
||||
* Moreover, when being sold, ammunition cost is always multiplied by 0.75,
|
||||
* without taking into an account possible discount a player might have.
|
||||
* This allows cheaters to "print money" by buying and selling ammo over and
|
||||
* over again ammunition for some weapons,
|
||||
* notably pipe bombs (74% discount for lvl6 demolition)
|
||||
* and crossbow (42% discount for lvl6 sharpshooter).
|
||||
*
|
||||
* This feature fixes this problem by setting 'pickupClass' variable in
|
||||
* potentially abusable weapons to our own value that won't receive a discount.
|
||||
* Luckily for us, discount checks are the only place where variable is
|
||||
* directly checked in a vanilla game's code
|
||||
* ('default.pickupClass' is used everywhere else),
|
||||
* so we can easily deal with the only side effect of such change.
|
||||
* Copyright 2020 Anton Tarasenko
|
||||
*------------------------------------------------------------------------------
|
||||
* This file is part of Acedia.
|
||||
*
|
||||
* Acedia is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Acedia is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
class FixAmmoSelling extends Feature;
|
||||
|
||||
/**
|
||||
* We will replace 'pickupClass' variable for all instances of potentially
|
||||
* abusable weapons. That is weapons, that have a discount for their ammunition
|
||||
* (via 'GetAmmoCostScaling' function in a corresponding perk class).
|
||||
* They are defined (along with our pickup replacements) in 'rules' array.
|
||||
* That array isn't configurable, since the abusable status is hardcoded into
|
||||
* perk classes and the main mod that allows to change those (ServerPerks),
|
||||
* also solves ammo selling by a more direct method
|
||||
* (only available for the mods that replace player pawn class).
|
||||
* This change already completely fixes ammo printing.
|
||||
* Possible concern with changing the value of 'pickupClass' is that
|
||||
* it might affect gameplay in too many ways.
|
||||
* But, luckily for us, that value is only used in 'ServerBuyAmmo'
|
||||
* function of 'KFPawn' (all the other places use it's default value instead).
|
||||
* This means that the only side-effect of our change is that ammo will be
|
||||
* sold at a different (lower for us) price, while trader would still display
|
||||
* and require the original price. This problem is solved by manually taking
|
||||
* from player the difference between what he should have had to pay
|
||||
* and what he actually paid.
|
||||
* This brings us to the second issue -
|
||||
* detecting when player bought the ammo.
|
||||
* Unfortunately, it doesn't seem possible to detect with 100% certainty
|
||||
* without replacing pawn or shop classes,
|
||||
* so we have to eliminate other possibilities.
|
||||
* There are seem to be three ways for players to get more ammo:
|
||||
* 1. For some mod to give it;
|
||||
* 2. Found it an ammo box;
|
||||
* 3. To buy ammo (can only happen in trader).
|
||||
* We don't want to provide mods with low-level API for bug fixes,
|
||||
* so to ensure the compatibility, mods that want to increase ammo values
|
||||
* will have to solve compatibility issue by themselves:
|
||||
* either by reimplementing this fix (possibly the best option)
|
||||
* or by giving players appropriate money along with the ammo.
|
||||
* The only other case we have to eliminate is ammo boxes.
|
||||
* First, all cases of ammo boxes outside the trader are easy to detect,
|
||||
* since in this case we can be sure that player didn't buy ammo
|
||||
* (and mods that can allow it can just get rid of
|
||||
* 'ServerSellAmmo' function directly, similarly to how ServerPerks does it).
|
||||
* We'll detect all the other boxes by attaching an auxiliary actor
|
||||
* ('AmmoPickupStalker') to them, that will fire off 'Touch' event
|
||||
* at the same time as ammo boxes.
|
||||
* The only possible problem is that part of the ammo cost is
|
||||
* taken with a slight delay, which leaves cheaters a window of opportunity
|
||||
* to buy more than they can afford.
|
||||
* This issue is addressed by each ammo type costing as much as possible
|
||||
* (its' cost for corresponding perk at lvl6)
|
||||
* and a flag that does allow players to go into negative dosh values
|
||||
* (the cost is potential bugs in this fix itself, that
|
||||
* can somewhat affect regular players).
|
||||
*/
|
||||
|
||||
// Due to how this fix works, players with level below 6 get charged less
|
||||
// than necessary by the shop and this fix must take the rest of
|
||||
// the cost by itself. While for unreliable and for minuscule benefit,
|
||||
// this can potentially be abused by cheaters.
|
||||
// To decrease the amount of value they can get from it, this fix can be
|
||||
// allowed to decrease players' money into negative values.
|
||||
// The trade off is a small chance that a some bug in this fix and
|
||||
// an unlucky circumstances can lead to regular players
|
||||
// having negative dosh values.
|
||||
// Both situations are highly unlikely, but the option is there.
|
||||
var private config const bool allowNegativeDosh;
|
||||
|
||||
// This structure records what classes of weapons can be abused
|
||||
// and what pickup class we should use to fix the exploit.
|
||||
struct ReplacementRule
|
||||
{
|
||||
var class<KFWeapon> abusableWeapon;
|
||||
var class<KFWeaponPickup> pickupReplacement;
|
||||
};
|
||||
|
||||
// Actual list of abusable weapons.
|
||||
var private const array<ReplacementRule> rules;
|
||||
|
||||
// We create one such record for any
|
||||
// abusable weapon instance in the game to store:
|
||||
struct WeaponRecord
|
||||
{
|
||||
// The instance itself.
|
||||
var KFWeapon weapon;
|
||||
// Corresponding ammo instance
|
||||
// (all abusable weapons only have one ammo type).
|
||||
var KFAmmunition ammo;
|
||||
// Last ammo amount we've seen, used to detect players gaining ammo
|
||||
// (from either ammo boxes or buying it).
|
||||
var int lastAmmoAmount;
|
||||
};
|
||||
|
||||
// All weapons we've detected so far.
|
||||
var private array<WeaponRecord> registeredWeapons;
|
||||
|
||||
public function OnEnabled()
|
||||
{
|
||||
local KFWeapon nextWeapon;
|
||||
local KFAmmoPickup nextPickup;
|
||||
// Find all abusable weapons
|
||||
foreach level.DynamicActors(class'KFMod.KFWeapon', nextWeapon)
|
||||
{
|
||||
FixWeapon(nextWeapon);
|
||||
}
|
||||
// Start tracking all ammo boxes
|
||||
foreach level.DynamicActors(class'KFMod.KFAmmoPickup', nextPickup)
|
||||
{
|
||||
class'AmmoPickupStalker'.static.StalkAmmoPickup(nextPickup);
|
||||
}
|
||||
}
|
||||
|
||||
public function OnDisabled()
|
||||
{
|
||||
local int i;
|
||||
local AmmoPickupStalker nextStalker;
|
||||
local array<AmmoPickupStalker> stalkers;
|
||||
// Restore all the 'pickupClass' variables we've changed.
|
||||
for (i = 0; i < registeredWeapons.length; i += 1)
|
||||
{
|
||||
if (registeredWeapons[i].weapon != none)
|
||||
{
|
||||
registeredWeapons[i].weapon.pickupClass =
|
||||
registeredWeapons[i].weapon.default.pickupClass;
|
||||
}
|
||||
}
|
||||
registeredWeapons.length = 0;
|
||||
// Kill all the stalkers;
|
||||
// to be safe, avoid destroying them directly in the iterator.
|
||||
foreach level.DynamicActors(class'AmmoPickupStalker', nextStalker)
|
||||
{
|
||||
stalkers[stalkers.length] = nextStalker;
|
||||
}
|
||||
for (i = 0; i < stalkers.length; i += 1)
|
||||
{
|
||||
if (stalkers[i] != none)
|
||||
{
|
||||
stalkers[i].Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
local int i;
|
||||
local WeaponRecord newRecord;
|
||||
if (potentialAbuser == none) return;
|
||||
|
||||
for (i = 0; i < registeredWeapons.length; i += 1)
|
||||
{
|
||||
if (registeredWeapons[i].weapon == potentialAbuser)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < rules.length; i += 1)
|
||||
{
|
||||
if (potentialAbuser.class == rules[i].abusableWeapon)
|
||||
{
|
||||
potentialAbuser.pickupClass = rules[i].pickupReplacement;
|
||||
newRecord.weapon = potentialAbuser;
|
||||
registeredWeapons[registeredWeapons.length] = newRecord;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finds ammo instance for recorded weapon in it's owner's inventory.
|
||||
private final function WeaponRecord FindAmmoInstance(WeaponRecord record)
|
||||
{
|
||||
local Inventory invIter;
|
||||
local KFAmmunition ammo;
|
||||
if (record.weapon == none) return record;
|
||||
if (record.weapon.instigator == none) return record;
|
||||
|
||||
// Find instances anew
|
||||
invIter = record.weapon.instigator.inventory;
|
||||
while (invIter != none)
|
||||
{
|
||||
if (record.weapon.ammoClass[0] == invIter.class)
|
||||
{
|
||||
ammo = KFAmmunition(invIter);
|
||||
}
|
||||
invIter = invIter.inventory;
|
||||
}
|
||||
// Add missing instances
|
||||
if (ammo != none)
|
||||
{
|
||||
record.ammo = ammo;
|
||||
record.lastAmmoAmount = ammo.ammoAmount;
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
// Calculates how much more player should have paid for 'ammoAmount'
|
||||
// amount of ammo, compared to how much trader took after our fix.
|
||||
private final function float GetPriceCorrection
|
||||
(
|
||||
KFWeapon kfWeapon,
|
||||
int ammoAmount
|
||||
)
|
||||
{
|
||||
local float boughtMagFraction;
|
||||
// 'vanillaPrice' - price that would be calculated
|
||||
// without our interference
|
||||
// 'fixPrice' - price that will be calculated after
|
||||
// we've replaced pickup class
|
||||
local float vanillaPrice, fixPrice;
|
||||
local KFPlayerReplicationInfo kfRI;
|
||||
local class<KFWeaponPickup> vanillaPickupClass, fixPickupClass;
|
||||
if (kfWeapon == none || kfWeapon.instigator == none) return 0.0;
|
||||
fixPickupClass = class<KFWeaponPickup>(kfWeapon.pickupClass);
|
||||
vanillaPickupClass = class<KFWeaponPickup>(kfWeapon.default.pickupClass);
|
||||
if (fixPickupClass == none || vanillaPickupClass == none) return 0.0;
|
||||
|
||||
// Calculate base prices
|
||||
boughtMagFraction = (float(ammoAmount) / kfWeapon.default.magCapacity);
|
||||
fixPrice = boughtMagFraction * fixPickupClass.default.AmmoCost;
|
||||
vanillaPrice = boughtMagFraction * vanillaPickupClass.default.AmmoCost;
|
||||
// Apply perk discount for vanilla price
|
||||
// (we don't need to consider secondary ammo or husk gun special cases,
|
||||
// since such weapons can't be abused via ammo dosh-printing)
|
||||
kfRI = KFPlayerReplicationInfo(kfWeapon.instigator.playerReplicationInfo);
|
||||
if (kfRI != none && kfRI.clientVeteranSkill != none)
|
||||
{
|
||||
vanillaPrice *= kfRI.clientVeteranSkill.static.
|
||||
GetAmmoCostScaling(kfRI, vanillaPickupClass);
|
||||
}
|
||||
// TWI's code rounds up ammo cost
|
||||
// to the integer value whenever ammo is bought,
|
||||
// so to calculate exactly how much we need to correct the cost,
|
||||
// we must find difference between the final, rounded cost values.
|
||||
return float(Max(0, int(vanillaPrice) - int(fixPrice)));
|
||||
}
|
||||
|
||||
// Takes current ammo and last recorded in 'record' value to calculate
|
||||
// how much money to take from the player
|
||||
// (calculations are done via 'GetPriceCorrection').
|
||||
private final function WeaponRecord TaxAmmoChange(WeaponRecord record)
|
||||
{
|
||||
local int ammoDiff;
|
||||
local KFPawn taxPayer;
|
||||
local PlayerReplicationInfo replicationInfo;
|
||||
taxPayer = KFPawn(record.weapon.instigator);
|
||||
if (record.weapon == none || taxPayer == none) return record;
|
||||
// No need to charge money if player couldn't have
|
||||
// possibly bought the ammo.
|
||||
if (!taxPayer.CanBuyNow()) return record;
|
||||
// Find ammo difference with recorded value.
|
||||
if (record.ammo != none)
|
||||
{
|
||||
ammoDiff = Max(0, record.ammo.ammoAmount - record.lastAmmoAmount);
|
||||
record.lastAmmoAmount = record.ammo.ammoAmount;
|
||||
}
|
||||
// Make player pay dosh
|
||||
replicationInfo = taxPayer.playerReplicationInfo;
|
||||
if (replicationInfo != none)
|
||||
{
|
||||
replicationInfo.score -= GetPriceCorrection(record.weapon, ammoDiff);
|
||||
// This shouldn't happen, since shop is supposed to make sure
|
||||
// player has enough dosh to buy ammo at full price
|
||||
// (actual price + our correction).
|
||||
// But if user is extra concerned about it, -
|
||||
// we can additionally for force the score above 0.
|
||||
if (!allowNegativeDosh)
|
||||
{
|
||||
replicationInfo.score = FMax(0, replicationInfo.score);
|
||||
}
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
// Changes our records to account for player picking up the ammo box,
|
||||
// to avoid charging his for it.
|
||||
public final function RecordAmmoPickup(Pawn pawnWithAmmo, KFAmmoPickup pickup)
|
||||
{
|
||||
local int i;
|
||||
local int newAmount;
|
||||
// Check conditions from 'KFAmmoPickup' code ('Touch' function)
|
||||
if (pickup == none) return;
|
||||
if (pawnWithAmmo == none) return;
|
||||
if (pawnWithAmmo.controller == none) return;
|
||||
if (!pawnWithAmmo.bCanPickupInventory) return;
|
||||
if (!FastTrace(pawnWithAmmo.location, pickup.location)) return;
|
||||
|
||||
// Add relevant amount of ammo to our records
|
||||
for (i = 0; i < registeredWeapons.length; i += 1)
|
||||
{
|
||||
if (registeredWeapons[i].weapon == none) continue;
|
||||
if (registeredWeapons[i].weapon.instigator == pawnWithAmmo)
|
||||
{
|
||||
newAmount = registeredWeapons[i].lastAmmoAmount
|
||||
+ registeredWeapons[i].ammo.ammoPickupAmount;
|
||||
newAmount = Min(registeredWeapons[i].ammo.maxAmmo, newAmount);
|
||||
registeredWeapons[i].lastAmmoAmount = newAmount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
event Tick(float delta)
|
||||
{
|
||||
local int i;
|
||||
// For all the weapon records...
|
||||
i = 0;
|
||||
while (i < registeredWeapons.length)
|
||||
{
|
||||
// ...remove dead records
|
||||
if (registeredWeapons[i].weapon == none)
|
||||
{
|
||||
registeredWeapons.Remove(i, 1);
|
||||
continue;
|
||||
}
|
||||
// ...find ammo if it's missing
|
||||
if (registeredWeapons[i].ammo == none)
|
||||
{
|
||||
registeredWeapons[i] = FindAmmoInstance(registeredWeapons[i]);
|
||||
}
|
||||
// ...tax for ammo, if we can
|
||||
registeredWeapons[i] = TaxAmmoChange(registeredWeapons[i]);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
allowNegativeDosh = true;
|
||||
rules(0)=(abusableWeapon=class'KFMod.Crossbow',pickupReplacement=class'FixAmmoSellingClass_CrossbowPickup')
|
||||
rules(1)=(abusableWeapon=class'KFMod.PipeBombExplosive',pickupReplacement=class'FixAmmoSellingClass_PipeBombPickup')
|
||||
rules(2)=(abusableWeapon=class'KFMod.M79GrenadeLauncher',pickupReplacement=class'FixAmmoSellingClass_M79Pickup')
|
||||
rules(3)=(abusableWeapon=class'KFMod.GoldenM79GrenadeLauncher',pickupReplacement=class'FixAmmoSellingClass_GoldenM79Pickup')
|
||||
rules(4)=(abusableWeapon=class'KFMod.M32GrenadeLauncher',pickupReplacement=class'FixAmmoSellingClass_M32Pickup')
|
||||
rules(5)=(abusableWeapon=class'KFMod.CamoM32GrenadeLauncher',pickupReplacement=class'FixAmmoSellingClass_CamoM32Pickup')
|
||||
rules(6)=(abusableWeapon=class'KFMod.LAW',pickupReplacement=class'FixAmmoSellingClass_LAWPickup')
|
||||
rules(7)=(abusableWeapon=class'KFMod.SPGrenadeLauncher',pickupReplacement=class'FixAmmoSellingClass_SPGrenadePickup')
|
||||
rules(8)=(abusableWeapon=class'KFMod.SealSquealHarpoonBomber',pickupReplacement=class'FixAmmoSellingClass_SealSquealPickup')
|
||||
rules(9)=(abusableWeapon=class'KFMod.SeekerSixRocketLauncher',pickupReplacement=class'FixAmmoSellingClass_SeekerSixPickup')
|
||||
// Listeners
|
||||
requiredListeners(0) = class'MutatorListener_FixAmmoSelling'
|
||||
requiredListeners(1) = class'BroadcastListenerBase'
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* A helper class for 'FixAmmoSelling' that sets ammo cost for M32 to that
|
||||
* of a level 6 player and doesn't allow for a perk discount.
|
||||
* Copyright 2019 Anton Tarasenko
|
||||
*------------------------------------------------------------------------------
|
||||
* This file is part of Acedia.
|
||||
*
|
||||
* Acedia is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Acedia is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
class FixAmmoSellingClass_CamoM32Pickup extends CamoM32Pickup;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
AmmoCost = 42
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* A helper class for 'FixAmmoSelling' that sets ammo cost for xbow to that
|
||||
* of a level 6 player and doesn't allow for a perk discount.
|
||||
* Copyright 2019 Anton Tarasenko
|
||||
*------------------------------------------------------------------------------
|
||||
* This file is part of Acedia.
|
||||
*
|
||||
* Acedia is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Acedia is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
class FixAmmoSellingClass_CrossbowPickup extends CrossbowPickup;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
AmmoCost = 11.6
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* A helper class for 'FixAmmoSelling' that sets ammo cost for m79 to that
|
||||
* of a level 6 player and doesn't allow for a perk discount.
|
||||
* Copyright 2019 Anton Tarasenko
|
||||
*------------------------------------------------------------------------------
|
||||
* This file is part of Acedia.
|
||||
*
|
||||
* Acedia is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Acedia is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
class FixAmmoSellingClass_GoldenM79Pickup extends GoldenM79Pickup;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
AmmoCost = 7
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* A helper class for 'FixAmmoSelling' that sets ammo cost for LAW to that
|
||||
* of a level 6 player and doesn't allow for a perk discount.
|
||||
* Copyright 2019 Anton Tarasenko
|
||||
*------------------------------------------------------------------------------
|
||||
* This file is part of Acedia.
|
||||
*
|
||||
* Acedia is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Acedia is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
class FixAmmoSellingClass_LAWPickup extends LAWPickup;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
AmmoCost = 21
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* A helper class for 'FixAmmoSelling' that sets ammo cost for M32 to that
|
||||
* of a level 6 player and doesn't allow for a perk discount.
|
||||
* Copyright 2019 Anton Tarasenko
|
||||
*------------------------------------------------------------------------------
|
||||
* This file is part of Acedia.
|
||||
*
|
||||
* Acedia is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Acedia is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
class FixAmmoSellingClass_M32Pickup extends M32Pickup;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
AmmoCost = 42
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* A helper class for 'FixAmmoSelling' that sets ammo cost for M79 to that
|
||||
* of a level 6 player and doesn't allow for a perk discount.
|
||||
* Copyright 2019 Anton Tarasenko
|
||||
*------------------------------------------------------------------------------
|
||||
* This file is part of Acedia.
|
||||
*
|
||||
* Acedia is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Acedia is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
class FixAmmoSellingClass_M79Pickup extends M79Pickup;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
AmmoCost = 7
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* A helper class for 'FixAmmoSelling' that sets ammo cost for pipes
|
||||
* to that of a level 6 player and doesn't allow for a perk discount.
|
||||
* Copyright 2019 Anton Tarasenko
|
||||
*------------------------------------------------------------------------------
|
||||
* This file is part of Acedia.
|
||||
*
|
||||
* Acedia is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Acedia is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
class FixAmmoSellingClass_PipeBombPickup extends PipeBombPickup;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
AmmoCost = 195
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* A helper class for 'FixAmmoSelling' that sets ammo cost for
|
||||
* orca grnade launcher to that of a level 6 player
|
||||
* and doesn't allow for a perk discount.
|
||||
* Copyright 2019 Anton Tarasenko
|
||||
*------------------------------------------------------------------------------
|
||||
* This file is part of Acedia.
|
||||
*
|
||||
* Acedia is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Acedia is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
class FixAmmoSellingClass_SPGrenadePickup extends SPGrenadePickup;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
AmmoCost = 7
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* A helper class for 'FixAmmoSelling' that sets ammo cost for harpoon
|
||||
* to that of a level 6 player and doesn't allow for a perk discount.
|
||||
* Copyright 2019 Anton Tarasenko
|
||||
*------------------------------------------------------------------------------
|
||||
* This file is part of Acedia.
|
||||
*
|
||||
* Acedia is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Acedia is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
class FixAmmoSellingClass_SealSquealPickup extends SealSquealPickup;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
AmmoCost = 21
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* A helper class for 'FixAmmoSelling' that sets ammo cost for seeker
|
||||
* to that of a level 6 player and doesn't allow for a perk discount.
|
||||
* Copyright 2019 Anton Tarasenko
|
||||
*------------------------------------------------------------------------------
|
||||
* This file is part of Acedia.
|
||||
*
|
||||
* Acedia is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Acedia is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
class FixAmmoSellingClass_SeekerSixPickup extends SeekerSixPickup;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
AmmoCost = 10.5
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* Overloaded mutator events listener to register every new
|
||||
* spawned weapon and ammo pickup.
|
||||
* Copyright 2020 Anton Tarasenko
|
||||
*------------------------------------------------------------------------------
|
||||
* This file is part of Acedia.
|
||||
*
|
||||
* Acedia is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Acedia is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
class MutatorListener_FixAmmoSelling extends MutatorListenerBase
|
||||
abstract;
|
||||
|
||||
static function bool CheckReplacement(Actor other, out byte isSuperRelevant)
|
||||
{
|
||||
CheckAbusableWeapon(KFWeapon(other));
|
||||
CheckAmmoPickup(KFAmmoPickup(other));
|
||||
return true;
|
||||
}
|
||||
|
||||
static function CheckAbusableWeapon(KFWeapon newWeapon)
|
||||
{
|
||||
local FixAmmoSelling ammoSellingFix;
|
||||
if (newWeapon == none) return;
|
||||
ammoSellingFix = FixAmmoSelling(class'FixAmmoSelling'.static.GetInstance());
|
||||
if (ammoSellingFix == none) return;
|
||||
ammoSellingFix.FixWeapon(newWeapon);
|
||||
}
|
||||
|
||||
static function CheckAmmoPickup(KFAmmoPickup newAmmoPickup)
|
||||
{
|
||||
if (newAmmoPickup == none) return;
|
||||
class'AmmoPickupStalker'.static.StalkAmmoPickup(newAmmoPickup);
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
relatedEvents = class'MutatorEvents'
|
||||
}
|
||||
Reference in a new issue