[Changed] - Dual pistols' spread was reduced by half (down to 250 from 500) - Commando no longer passively grants zed-time extensions - Commando's skill 'Perfect execution': zed-time granted by this skill can no longer be extended - Commando's skill 'Overclocking': now grants 4 additional zed-time extensions - Demolitionist's weapons: ammo cost doubled, max ammo reduced to about 2/3rds of previous values (except for harpoon that was unchanged, m32 that still has the same max ammo and L.A.W. that got its ammo halved and rocket cost raised fom 13 to 40) - Removed Hardcore level broadcasting bullshit
1097 lines
45 KiB
Ucode
1097 lines
45 KiB
Ucode
class NicePack extends Mutator
|
|
dependson(NiceStorageServer)
|
|
config(NicePack);
|
|
// Should we scale health off all zeds to 6-player level?
|
|
var config bool bScaleZedHealth;
|
|
// Should we replace all pickups with their Nice versions when available?
|
|
var config bool bReplacePickups;
|
|
// Settings for initial trader
|
|
var config bool bInitialTrader; // Use initial trader system?
|
|
var config bool bStillDuringInitTrader; // Force players to stand still during initial trader
|
|
var config int initialTraderTime; // How much time should be allowed for initial trade?
|
|
// Progressive dosh config
|
|
var config bool bUseProgresiveCash; // Use progressive dosh system?
|
|
var config array<int> waveCash;
|
|
var config float lateMultiplier;
|
|
// Experience-conversion controlling variables
|
|
var config bool bConvertExp; // Should we even convert old exp into a new one?
|
|
var config float vetFieldMedicExpCost; // Amount of exp per HP healed
|
|
var config float vetFieldMedicDmgExpCost; // Amount of exp per 1 medic damage
|
|
var config float vetSharpHeadshotExpCost; // Amount of exp per head-shot
|
|
var config float vetSupportDamageExpCost; // Amount of exp per 1 shotgun damage
|
|
var config float vetCommandoDamageExpCost; // Amount of exp per 1 assault rifle damage
|
|
var config float vetDemoDamageExpCost; // Amount of exp per 1 explosive damage
|
|
var config float vetZerkDamageExpCost; // Amount of exp per 1 melee damage
|
|
var config float vetHeavyMGDamageExpCost; // Amount of exp per 1 heavy machine gun damage
|
|
var config float vetGunslingerKillExpCost; // Amount of exp per 1 assault rifle damage
|
|
// Allow changing skills at any time
|
|
var config bool bAlwaysAllowSkillChange;
|
|
// Variables for controlling how zeds spawn
|
|
var config float minSpawnRate, maxSpawnRate; // Minimum and maximum allowed spawn rate
|
|
var config int minimalSpawnDistance; // Minimal distance between ZedVolume and players that should allow for zeds to spawn
|
|
// FF voting - related settings
|
|
var config bool bOneFFIncOnly; // Option that only allows one FF increase per game
|
|
var config bool bNoLateFFIncrease; // Disables FF increase through voting after 1st wave
|
|
// Configuration variables that store whether or not to replace the specimen with it's mean counterpart
|
|
var config bool bReplaceCrawler, bReplaceStalker, bReplaceClot, bReplaceGorefast, bReplaceBloat, bReplaceSiren, bReplaceHusk, bReplaceScrake, bReplaceFleshpound;
|
|
var config int bigZedMinHealth; // If zed's base Health >= this value, zed counts as Big
|
|
var config int mediumZedMinHealth;
|
|
|
|
var int maxPlayersInGame;
|
|
|
|
var bool bSpawnRateEnforced; // Set to true after spawn rate was altered
|
|
// 'Adrenaline junkie' zed-time extensions
|
|
var int junkieDoneGoals; // How many times we collected enough head-shots to trigger zed-time extension
|
|
var int junkieNextGoal; // How many head-shots we need for next zed-time extension
|
|
var int junkieDoneHeadshots; // How many head-shot in a row was done from the start of last zed-time
|
|
var array<String> replCaps;
|
|
var bool bFFWasIncreased;
|
|
var int nextSirenScreamID;
|
|
var int stuckCounter;
|
|
// Max dead bodies among all players
|
|
var int maxDeadBodies;
|
|
var int deadBodyCounter;
|
|
var ScrnBalance ScrnMut;
|
|
var ScrnGameType ScrnGT;
|
|
var NiceGameType NiceGT;
|
|
var NiceTSCGame NiceTSC;
|
|
var NicePack Mut;
|
|
var NiceRules GameRules;
|
|
var NiceStorageServer serverStorage;
|
|
var bool bClientLinkEstablished;
|
|
var bool interactionAdded;
|
|
var bool bIsPreGame;
|
|
var bool bIsTraderTime;
|
|
var bool bWasZedTime;
|
|
var array<KFHumanPawn> recordedHumanPawns;
|
|
struct PlayerRecord{
|
|
var string steamID;
|
|
var bool bHasSpawned;
|
|
var int lastCashWave; //Last wave in which player either participated, or for which he received cash
|
|
var int kills, assists, deaths;
|
|
};
|
|
var array<PlayerRecord> PlayerDatabase;
|
|
// Zed hardcore level record
|
|
struct ZedRecord{
|
|
var string ZedName;
|
|
var class<NiceMonster> ZedType;
|
|
var class<NiceMonster> MeanZedType;
|
|
var bool bAlreadySpawned;
|
|
var bool bMeanAlreadySpawned;
|
|
var float HL;
|
|
var float MeanHLBonus;
|
|
var bool bNeedsReplacement;
|
|
};
|
|
var int lastStandardZed;
|
|
var array<ZedRecord> ZedDatabase;
|
|
struct NicePickupReplacement{
|
|
var class<Pickup> vanillaClass;
|
|
var class<Pickup> scrnClass;
|
|
var class<Pickup> newClass;
|
|
};
|
|
var array<NicePickupReplacement> pickupReplaceArray;
|
|
struct CounterDisplay{
|
|
var string cName;
|
|
var Texture icon;
|
|
var int value;
|
|
var bool bShowZeroValue;
|
|
var class<NiceSkill> ownerSkill;
|
|
};
|
|
var array<CounterDisplay> niceCounterSet;
|
|
struct WeaponProgressDisplay{
|
|
var class<NiceWeapon> weapClass;
|
|
var float progress;
|
|
var bool bShowCounter;
|
|
var int counter;
|
|
};
|
|
var array<WeaponProgressDisplay> niceWeapProgressSet;
|
|
// Map Description array
|
|
var const array<localized string> NiceUniversalDescriptions[4];
|
|
// Replication of config between player and server
|
|
var int SrvFlags;
|
|
var array<NicePlayerController> playersList;
|
|
var NicePathBuilder globalPathBuilder;
|
|
|
|
replication{
|
|
reliable if(Role == ROLE_Authority)
|
|
SrvFlags, bIsPreGame, junkieDoneHeadshots, junkieNextGoal;
|
|
}
|
|
|
|
static function NicePathBuilder GetPathBuilder(){
|
|
if(default.globalPathBuilder == none)
|
|
default.globalPathBuilder = new() class'NicePathBuilder';
|
|
return default.globalPathBuilder;
|
|
}
|
|
|
|
static final function NiceStorageBase GetStorage(LevelInfo level){
|
|
local NicePlayerController localPlayer;
|
|
if(default.serverStorage != none) return default.serverStorage;
|
|
localPlayer = NicePlayerController(level.GetLocalPlayerController());
|
|
if(localPlayer != none)
|
|
return localPlayer.storageClient;
|
|
return none;
|
|
}
|
|
|
|
static final function NicePack Myself(LevelInfo Level){
|
|
local Mutator M;
|
|
local NicePack NicePackMutator;
|
|
if(default.Mut != none)
|
|
return default.Mut;
|
|
// server-side
|
|
if(Level != none && Level.Game != none){
|
|
for(M = Level.Game.BaseMutator;M != none;M = M.NextMutator){
|
|
NicePackMutator = NicePack(M);
|
|
if(NicePackMutator != none){
|
|
default.Mut = NicePackMutator;
|
|
return NicePackMutator;
|
|
}
|
|
}
|
|
}
|
|
// client-side
|
|
foreach Level.DynamicActors(class'NicePack', NicePackMutator){
|
|
default.Mut = NicePackMutator;
|
|
return NicePackMutator;
|
|
}
|
|
return none;
|
|
}
|
|
function PreBeginPlay()
|
|
{
|
|
local ZombieVolume ZV;
|
|
super.PreBeginPlay();
|
|
foreach AllActors(Class'ZombieVolume', ZV)
|
|
ZV.MinDistanceToPlayer = minimalSpawnDistance;
|
|
AddToPackageMap("NicePackA.ukx");
|
|
AddToPackageMap("NicePackSM.usx");
|
|
AddToPackageMap("NicePackSnd.uax");
|
|
AddToPackageMap("NicePackT.utx");
|
|
}
|
|
simulated function PostBeginPlay(){
|
|
local int i;
|
|
local ZedRecord record;
|
|
local ScrnVotingHandlerMut VH;
|
|
local MeanVoting VO;
|
|
local NiceFFVoting FFVO;
|
|
super.PostBeginPlay();
|
|
class'ScrnLightVestPickup'.default.cost = 50;
|
|
class'ScrnHorzineVestPickup'.default.weight = 2;
|
|
class'ScrnHorzineVestPickup'.default.cost = 750;
|
|
class'NicePack'.default.Mut = self;
|
|
// Gun skins
|
|
class'NicePack.NiceMaulerPickup'.default.VariantClasses[class'NicePack.NiceMaulerPickup'.default.VariantClasses.length] = class'ScrnBalanceSrv.ScrnSPSniperPickup';
|
|
class'NicePack.NiceDeaglePickup'.default.VariantClasses[class'NicePack.NiceDeaglePickup'.default.VariantClasses.length] = class'NicePack.SkinExecutionerPickup';
|
|
class'NicePack.NiceDualDeaglePickup'.default.VariantClasses[class'NicePack.NiceDualDeaglePickup'.default.VariantClasses.length] = class'NicePack.SkinDualExecutionerPickup';
|
|
class'NicePack.NiceMagnumPickup'.default.VariantClasses[class'NicePack.NiceMagnumPickup'.default.VariantClasses.length] = class'NicePack.SkinCowboyMagnumPickup';
|
|
class'NicePack.NiceDualMagnumPickup'.default.VariantClasses[class'NicePack.NiceDualMagnumPickup'.default.VariantClasses.length] = class'NicePack.SkinDualCowboyMagnumPickup';
|
|
class'NicePack.NiceWinchesterPickup'.default.VariantClasses[class'NicePack.NiceWinchesterPickup'.default.VariantClasses.length] = class'NicePack.SkinRetroLARPickup';
|
|
class'NicePack.NiceM14EBRPickup'.default.VariantClasses[class'NicePack.NiceM14EBRPickup'.default.VariantClasses.length] = class'NicePack.SkinM14EBR2ProPickup';
|
|
class'ScrnBalanceSrv.ScrnKrissMPickup'.default.VariantClasses[class'ScrnBalanceSrv.ScrnKrissMPickup'.default.VariantClasses.length] = class'NicePack.SkinGoldenKrissPickup';
|
|
class'NicePack.NiceSCARMK17Pickup'.default.VariantClasses[class'NicePack.NiceSCARMK17Pickup'.default.VariantClasses.length] = class'NicePack.SkinCamoSCARMK17Pickup';
|
|
// Abilities
|
|
class'NiceAbilityManager'.default.events.static.AddAdapter(class'NiceSharpshooterAbilitiesAdapter', level);
|
|
class'NiceAbilityManager'.default.events.static.AddAdapter(class'NiceEnforcerAbilitiesAdapter', level);
|
|
SetTimer(0.25, true);
|
|
if(Role < ROLE_Authority)
|
|
return;
|
|
// Create sync node
|
|
serverStorage = new class'NicePack.NiceStorageServer';
|
|
default.serverStorage = serverStorage;
|
|
serverStorage.events.static.AddAdapter(class'NiceRemoteDataAdapter', Level);
|
|
// Find game type and ScrN mutator
|
|
ScrnGT = ScrnGameType(Level.Game);
|
|
NiceGT = NiceGameType(Level.Game);
|
|
NiceTSC = NiceTSCGame(Level.Game);
|
|
if(ScrnGT == none){
|
|
Log("ERROR: Wrong GameType (requires at least ScrnGameType)", Class.Outer.Name);
|
|
Destroy();
|
|
return;
|
|
}
|
|
// Skills menu
|
|
ScrnGT.LoginMenuClass = string(Class'NicePack.NiceInvasionLoginMenu');
|
|
if(NiceGT != none)
|
|
NiceGT.RegisterMutator(Self);
|
|
if(NiceTSC != none)
|
|
NiceTSC.RegisterMutator(Self);
|
|
ScrnMut = ScrnGT.ScrnBalanceMut;
|
|
if(bReplacePickups)
|
|
ScrnMut.bReplacePickups = false;
|
|
// Replication of some variables
|
|
SetReplicationData();
|
|
// New player controller class
|
|
if(!ClassIsChildOf(ScrnGT.PlayerControllerClass, class'NicePack.NicePlayerController')){
|
|
ScrnGT.PlayerControllerClass = class'NicePack.NicePlayerController';
|
|
ScrnGT.PlayerControllerClassName = string(Class'NicePack.NicePlayerController');
|
|
}
|
|
// Game rules
|
|
GameRules = Spawn(Class'NicePack.NiceRules', self);
|
|
// -- Lower starting HL
|
|
ScrnMut.GameRules.HardcoreLevel -= 7;
|
|
ScrnMut.GameRules.HardcoreLevelFloat -= 7;
|
|
// -- Fill-in zed info
|
|
i = 0;
|
|
// - Clot
|
|
record.ZedName = "Clot";
|
|
record.ZedType = class'NicePack.NiceZombieClot';
|
|
record.MeanZedType = class'NicePack.MeanZombieClot';
|
|
record.HL = 0.0;
|
|
record.MeanHLBonus = 0.5;
|
|
record.bNeedsReplacement = bReplaceClot;
|
|
ZedDatabase[i++] = record;
|
|
// - Crawler
|
|
record.ZedName = "Crawler";
|
|
record.ZedType = class'NicePack.NiceZombieCrawler';
|
|
record.MeanZedType = class'NicePack.MeanZombieCrawler';
|
|
record.HL = 0.5;
|
|
record.MeanHLBonus = 1.5;
|
|
record.bNeedsReplacement = bReplaceCrawler;
|
|
ZedDatabase[i++] = record;
|
|
// - Stalker
|
|
record.ZedName = "Stalker";
|
|
record.ZedType = class'NicePack.NiceZombieStalker';
|
|
record.MeanZedType = class'NicePack.MeanZombieStalker';
|
|
record.HL = 0.5;
|
|
record.MeanHLBonus = 0.5;
|
|
record.bNeedsReplacement = bReplaceStalker;
|
|
ZedDatabase[i++] = record;
|
|
// - Gorefast
|
|
record.ZedName = "Gorefast";
|
|
record.ZedType = class'NicePack.NiceZombieGorefast';
|
|
record.MeanZedType = class'NicePack.MeanZombieGorefast';
|
|
record.HL = 0.0;
|
|
record.MeanHLBonus = 0.5;
|
|
record.bNeedsReplacement = bReplaceGorefast;
|
|
ZedDatabase[i++] = record;
|
|
// - Bloat
|
|
record.ZedName = "Bloat";
|
|
record.ZedType = class'NicePack.NiceZombieBloat';
|
|
record.MeanZedType = class'NicePack.MeanZombieBloat';
|
|
record.HL = 0.0;
|
|
record.MeanHLBonus = 0.5;
|
|
record.bNeedsReplacement = bReplaceBloat;
|
|
ZedDatabase[i++] = record;
|
|
// - Siren
|
|
record.ZedName = "Siren";
|
|
record.ZedType = class'NicePack.NiceZombieSiren';
|
|
record.MeanZedType = class'NicePack.MeanZombieSiren';
|
|
record.HL = 1.0;
|
|
record.MeanHLBonus = 1.0;
|
|
record.bNeedsReplacement = bReplaceSiren;
|
|
ZedDatabase[i++] = record;
|
|
// - Husk
|
|
record.ZedName = "Husk";
|
|
record.ZedType = class'NicePack.NiceZombieHusk';
|
|
record.MeanZedType = class'NicePack.MeanZombieHusk';
|
|
record.HL = 1.0;
|
|
record.MeanHLBonus = 1.5;
|
|
record.bNeedsReplacement = bReplaceHusk;
|
|
ZedDatabase[i++] = record;
|
|
// - Scrake
|
|
record.ZedName = "Scrake";
|
|
record.ZedType = class'NicePack.NiceZombieScrake';
|
|
record.MeanZedType = class'NicePack.MeanZombieScrake';
|
|
record.HL = 1.5;
|
|
record.MeanHLBonus = 1.5;
|
|
record.bNeedsReplacement = bReplaceScrake;
|
|
ZedDatabase[i++] = record;
|
|
// - Fleshpound
|
|
lastStandardZed = i;
|
|
record.ZedName = "Fleshpound";
|
|
record.ZedType = class'NicePack.NiceZombieFleshPound';
|
|
record.MeanZedType = class'NicePack.MeanZombieFleshPound';
|
|
record.HL = 2.5;
|
|
record.MeanHLBonus = 1.5;
|
|
record.bNeedsReplacement = bReplaceFleshpound;
|
|
ZedDatabase[i++] = record;
|
|
// - Shiver
|
|
record.ZedName = "Shiver";
|
|
record.ZedType = class'NicePack.NiceZombieShiver';
|
|
record.MeanZedType = none;
|
|
record.HL = 1;
|
|
record.bNeedsReplacement = false;
|
|
ZedDatabase[i++] = record;
|
|
// - Jason
|
|
record.ZedName = "Jason";
|
|
record.ZedType = class'NicePack.NiceZombieJason';
|
|
record.MeanZedType = none;
|
|
record.HL = 1.5;
|
|
record.bNeedsReplacement = false;
|
|
ZedDatabase[i++] = record;
|
|
// - Tesla Husk
|
|
record.ZedName = "Tesla husk";
|
|
record.ZedType = class'NicePack.NiceZombieTeslaHusk';
|
|
record.MeanZedType = none;
|
|
record.HL = 1.5;
|
|
record.bNeedsReplacement = false;
|
|
ZedDatabase[i++] = record;
|
|
// - Brute
|
|
record.ZedName = "Brute";
|
|
record.ZedType = class'NicePack.NiceZombieBrute';
|
|
record.MeanZedType = none;
|
|
record.HL = 2;
|
|
record.bNeedsReplacement = false;
|
|
ZedDatabase[i++] = record;
|
|
// - Ghost
|
|
record.ZedName = "Ghost";
|
|
record.ZedType = class'NicePack.NiceZombieGhost';
|
|
record.MeanZedType = none;
|
|
record.HL = 0.5;
|
|
record.bNeedsReplacement = false;
|
|
ZedDatabase[i++] = record;
|
|
// - Sick
|
|
record.ZedName = "Sick";
|
|
record.ZedType = class'NicePack.NiceZombieSick';
|
|
record.MeanZedType = none;
|
|
record.HL = 1.0;
|
|
record.bNeedsReplacement = false;
|
|
ZedDatabase[i++] = record;
|
|
// Nothing has yet spawned
|
|
for(i = 0;i < ZedDatabase.length;i ++){
|
|
ZedDatabase[i].bAlreadySpawned = false;
|
|
ZedDatabase[i].bMeanAlreadySpawned = false;
|
|
}
|
|
// Add voting for mean zeds
|
|
VH = class'ScrnVotingHandlerMut'.static.GetVotingHandler(Level.Game);
|
|
if(VH == none){
|
|
Level.Game.AddMutator(string(class'ScrnVotingHandlerMut'), false);
|
|
VH = class'ScrnVotingHandlerMut'.static.GetVotingHandler(Level.Game);
|
|
}
|
|
if(VH != none){
|
|
VO = MeanVoting(VH.AddVotingOptions(class'MeanVoting'));
|
|
if(VO != none)
|
|
VO.Mut = self;
|
|
FFVO = NiceFFVoting(VH.AddVotingOptions(class'NiceFFVoting'));
|
|
if(FFVO != none)
|
|
FFVO.Mut = self;
|
|
}
|
|
else
|
|
log("Unable to spawn voting handler mutator", class.outer.name);
|
|
}
|
|
simulated function PostNetBeginPlay()
|
|
{
|
|
super.PostNetBeginPlay();
|
|
if(Role < ROLE_Authority)
|
|
LoadReplicationData();
|
|
}
|
|
function SetReplicationData(){
|
|
SrvFlags = 0;
|
|
if(bInitialTrader)
|
|
SrvFlags = SrvFlags | 0x00000001;
|
|
if(bStillDuringInitTrader)
|
|
SrvFlags = SrvFlags | 0x00000002;
|
|
}
|
|
simulated function LoadReplicationData(){
|
|
if(Role == ROLE_Authority)
|
|
return;
|
|
bInitialTrader = (SrvFlags & 0x00000001) > 0;
|
|
bStillDuringInitTrader = (SrvFlags & 0x00000002) > 0;
|
|
}
|
|
simulated function Timer(){
|
|
local KFHumanPawn nextPawn;
|
|
local int currentPlayersMax;
|
|
local Controller P;
|
|
local NicePlayerController nicePlayer;
|
|
// Cull excessive pawns
|
|
if(Role < Role_AUTHORITY){
|
|
recordedHumanPawns.Length = 0;
|
|
foreach DynamicActors(class'KFHumanPawn', nextPawn)
|
|
if(nextPawn != none && nextPawn.health > 0)
|
|
recordedHumanPawns[recordedHumanPawns.Length] = nextPawn;
|
|
return;
|
|
}
|
|
// Broadcast skills & record latest player controller list
|
|
BroadcastSkills();
|
|
playersList.length = 0;
|
|
for(P = Level.ControllerList; P != none; P = P.nextController){
|
|
nicePlayer = NicePlayerController(P);
|
|
if(nicePlayer != none){
|
|
nicePlayer.wallHitsLeft = 10;
|
|
//nicePlayer.FreeOldStuckBullets();
|
|
playersList[playersList.Length] = nicePlayer;
|
|
if(nicePlayer.Pawn != none && nicePlayer.Pawn.health > 0 && !nicePlayer.PlayerReplicationInfo.bIsSpectator
|
|
&& !nicePlayer.PlayerReplicationInfo.bOnlySpectator)
|
|
currentPlayersMax ++;
|
|
}
|
|
}
|
|
maxPlayersInGame = Max(maxPlayersInGame, currentPlayersMax);
|
|
}
|
|
simulated function Tick(float Delta){
|
|
local int i;
|
|
local NiceInteraction niceInt;
|
|
local NicePlayerController localPlayer;
|
|
super.Tick(Delta);
|
|
if(ScrnGT != none && ScrnGT.WaveCountDown <= 5)
|
|
bIsPreGame = false;
|
|
if(ScrnMut != none && !bSpawnRateEnforced && ScrnMut.bTickExecuted){
|
|
bSpawnRateEnforced = true;
|
|
ScrnMut.OriginalWaveSpawnPeriod = FMax(minSpawnRate, FMin(maxSpawnRate, ScrnMut.OriginalWaveSpawnPeriod));
|
|
}
|
|
localPlayer = NicePlayerController(Level.GetLocalPlayerController());
|
|
// Check if the local PlayerController is available yet
|
|
if(localPlayer == none)
|
|
return;
|
|
if( Role < Role_AUTHORITY && !bClientLinkEstablished
|
|
&& localPlayer.storageClient != none && localPlayer.remoteRI != none){
|
|
bClientLinkEstablished = true;
|
|
localPlayer.storageClient.remoteRI = localPlayer.remoteRI;
|
|
localPlayer.storageClient.events.static.CallLinkEstablished();
|
|
}
|
|
if(localPlayer.bFlagDisplayCounters){
|
|
for(i = 0;i < niceCounterSet.Length;i ++){
|
|
if(niceCounterSet[i].ownerSkill == none)
|
|
niceCounterSet[i].value = UpdateCounterValue(niceCounterSet[i].cName);
|
|
else if(class'NiceVeterancyTypes'.static.hasSkill(localPlayer, niceCounterSet[i].ownerSkill))
|
|
niceCounterSet[i].value = niceCounterSet[i].ownerSkill.static.
|
|
UpdateCounterValue(niceCounterSet[i].cName, localPlayer);
|
|
else
|
|
niceCounterSet[i].value = 0;
|
|
}
|
|
}
|
|
// Reset tick counter for traces
|
|
localPlayer.tracesThisTick = 0;
|
|
// Manage resetting of effects' limits
|
|
if(Level.TimeSeconds >= localPlayer.nextEffectsResetTime){
|
|
localPlayer.nextEffectsResetTime = Level.TimeSeconds + 0.1;
|
|
localPlayer.currentEffectTimeWindow ++;
|
|
if(localPlayer.currentEffectTimeWindow >= 10)
|
|
localPlayer.currentEffectTimeWindow = 0;
|
|
localPlayer.effectsSpawned[localPlayer.currentEffectTimeWindow] = 0;
|
|
}
|
|
// Add interaction
|
|
if(interactionAdded)
|
|
return;
|
|
// Actually add the interaction
|
|
niceInt = NiceInteraction(localPlayer.Player.InteractionMaster.AddInteraction("NicePack.NiceInteraction", localPlayer.Player));
|
|
niceInt.RegisterMutator(Self);
|
|
interactionAdded = true;
|
|
}
|
|
simulated function bool CheckReplacement(Actor Other, out byte bSuperRelevant){
|
|
local int i;
|
|
local NiceMonster niceMonster;
|
|
local NiceZombieBoss boss;
|
|
local Controller cIt;
|
|
local int currNumPlayers;
|
|
local NicePlayerController playerContr;
|
|
local NiceRepInfoRemoteData remoteRI;
|
|
local NiceReplicationInfo niceRI;
|
|
local MeanReplicationInfo meanRI;
|
|
local PlayerReplicationInfo pri;
|
|
// Replace loot on levels
|
|
if(Other.class == class'KFRandomItemSpawn' || Other.class == class'ScrnBalanceSrv.ScrnRandomItemSpawn'){
|
|
ReplaceWith(Other, "NicePack.NiceRandomItemSpawn");
|
|
return false;
|
|
}
|
|
else if(Other.class == class'KFAmmoPickup' || Other.class == class'ScrnBalanceSrv.ScrnAmmoPickup') {
|
|
ReplaceWith(Other, "NicePack.NiceAmmoPickup");
|
|
return false;
|
|
}
|
|
else if(bReplacePickups && Pickup(Other) != none){
|
|
i = FindPickupReplacementIndex(Pickup(Other));
|
|
if (i != -1){
|
|
ReplaceWith(Other, String(pickupReplaceArray[i].NewClass));
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
// Add our replication info
|
|
if(PlayerReplicationInfo(Other) != none && NicePlayerController(PlayerReplicationInfo(Other).Owner) != none){
|
|
pri = PlayerReplicationInfo(Other);
|
|
niceRI = spawn(class'NiceReplicationInfo', pri.Owner);
|
|
niceRI.Mut = self;
|
|
remoteRI = spawn(class'NiceRepInfoRemoteData', pri.Owner);
|
|
meanRI = spawn(class'MeanReplicationInfo', pri.Owner);
|
|
meanRI.ownerPRI = pri;
|
|
playerContr = NicePlayerController(PlayerReplicationInfo(Other).Owner);
|
|
playerContr.niceRI = niceRI;
|
|
playerContr.remoteRI = remoteRI;
|
|
}
|
|
niceMonster = NiceMonster(Other);
|
|
if(niceMonster != none){
|
|
if (bUseProgresiveCash) {
|
|
niceMonster.ScoringValue = 0;
|
|
}
|
|
}
|
|
// Replace zeds with a healthier ones.
|
|
// Code taken from a scary ghost's SpecimenHPConfig
|
|
if(!bScaleZedHealth)
|
|
return true;
|
|
boss = NiceZombieBoss(Other);
|
|
if(niceMonster != none){
|
|
for(cIt= Level.ControllerList; cIt != none; cIt= cIt.NextController)
|
|
if(cIt.bIsPlayer && cIt.Pawn != none && cIt.Pawn.Health > 0)
|
|
currNumPlayers++;
|
|
if(boss == none) {
|
|
niceMonster.Health *= hpScale(niceMonster.PlayerCountHealthScale) / niceMonster.NumPlayersHealthModifer();
|
|
niceMonster.HealthMax = niceMonster.Health;
|
|
niceMonster.HeadHealth *= hpScale(niceMonster.PlayerNumHeadHealthScale) / niceMonster.NumPlayersHeadHealthModifer();
|
|
niceMonster.HeadHealthMax = niceMonster.HeadHealth;
|
|
if(Level.Game.NumPlayers == 1){
|
|
niceMonster.MeleeDamage /= 0.75;
|
|
niceMonster.ScreamDamage /= 0.75;
|
|
niceMonster.SpinDamConst /= 0.75;
|
|
niceMonster.SpinDamRand /= 0.75;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
// returns -1, if not found
|
|
function int FindPickupReplacementIndex(Pickup item)
|
|
{
|
|
local int i;
|
|
for(i=0; i < pickupReplaceArray.length;i ++){
|
|
if(pickupReplaceArray[i].vanillaClass == item.class || pickupReplaceArray[i].scrnClass == item.class)
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
// Try to extend zed-time, junkie-style
|
|
function JunkieZedTimeExtend(){
|
|
if((ScrnGT != none && !ScrnGT.bZEDTimeActive) || ScrnGT.CurrentZEDTimeDuration <= 0)
|
|
return;
|
|
junkieDoneHeadshots ++;
|
|
if(junkieNextGoal <= junkieDoneHeadshots){
|
|
junkieDoneHeadshots = 0;
|
|
junkieDoneGoals ++;
|
|
junkieNextGoal ++;
|
|
ScrnGT.DramaticEvent(1.0);
|
|
}
|
|
}
|
|
simulated function AddCounter(string cName, Texture icon, optional bool bShowZeroValue,
|
|
optional class<NiceSkill> owner){
|
|
local CounterDisplay newCounter;
|
|
RemoveCounter(cName);
|
|
newCounter.cName = cName;
|
|
newCounter.icon = icon;
|
|
newCounter.bShowZeroValue = bShowZeroValue;
|
|
newCounter.ownerSkill = owner;
|
|
niceCounterSet[niceCounterSet.Length] = newCounter;
|
|
}
|
|
simulated function RemoveCounter(string cName){
|
|
local int i;
|
|
local array<CounterDisplay> newCounterSet;
|
|
for(i = 0;i < niceCounterSet.Length;i ++)
|
|
if(niceCounterSet[i].cName != cName)
|
|
newCounterSet[newCounterSet.Length] = niceCounterSet[i];
|
|
niceCounterSet = newCounterSet;
|
|
}
|
|
simulated function int GetVisibleCountersAmount(){
|
|
local int i;
|
|
local int amount;
|
|
for(i = 0;i < niceCounterSet.Length;i ++)
|
|
if(niceCounterSet[i].value != 0 || niceCounterSet[i].bShowZeroValue)
|
|
amount ++;
|
|
return amount;
|
|
}
|
|
simulated function int UpdateCounterValue(string cName){
|
|
return 0;
|
|
}
|
|
simulated function AddWeapProgress(class<NiceWeapon> weapClass, float progress,
|
|
optional bool bShowCounter, optional int counter){
|
|
local WeaponProgressDisplay newProgress;
|
|
newProgress.weapClass = weapClass;
|
|
newProgress.progress = progress;
|
|
newProgress.bShowCounter = bShowCounter;
|
|
newProgress.counter = counter;
|
|
niceWeapProgressSet[niceWeapProgressSet.Length] = newProgress;
|
|
}
|
|
simulated function ClearWeapProgress(){
|
|
niceWeapProgressSet.Length = 0;
|
|
}
|
|
// Returns cash per wave based on current difficulty
|
|
// Returns cash per wave based on current difficulty
|
|
function int GetWaveCash(int lastCashWave, int nextWave){
|
|
local int i;
|
|
local int accumulatedDosh;
|
|
for (i = lastCashWave; i < nextWave; i += 1) {
|
|
accumulatedDosh += waveCash[i];
|
|
}
|
|
if (lastCashWave + 1 < nextWave) {
|
|
accumulatedDosh *= lateMultiplier;
|
|
}
|
|
return accumulatedDosh;
|
|
}
|
|
// Gives out appropriate (for the wave he entered) amount of dosh to the player
|
|
function GiveProgressiveDosh(NicePlayerController nicePlayer){
|
|
local int nextWave;
|
|
local PlayerRecord record;
|
|
// Too early to give dosh
|
|
if(!ScrnGT.IsInState('MatchInProgress'))
|
|
return;
|
|
// Real spectators shouldn't be affected
|
|
if(nicePlayer == none) return;
|
|
if(nicePlayer.PlayerReplicationInfo.bIsSpectator) return;
|
|
if(nicePlayer.PlayerReplicationInfo.bOnlySpectator) return;
|
|
record = FindPlayerRecord(nicePlayer.steamID64);
|
|
nextWave = ScrnGT.WaveNum + 1;
|
|
nicePlayer.PlayerReplicationInfo.Score += GetWaveCash(record.lastCashWave, nextWave);
|
|
record.lastCashWave = nextWave;
|
|
UpdatePlayerRecord(record);
|
|
}
|
|
simulated function Mutate(string MutateString, PlayerController kfPlayer){
|
|
local int i, readLenght;
|
|
local NicePlayerController nicePlayer;
|
|
local NiceServerData remoteData;
|
|
// Tokens from 'MutateString'
|
|
local array<String> wordsArray;
|
|
local String command, mod;
|
|
local String white;
|
|
local BitStreamWriter inputStream;
|
|
local BitStreamReader outputStream;
|
|
// Array with command modifiers.
|
|
// Always contains at least 10 elements, that may be empty strings if there wasn't enough modifiers.
|
|
// Done for safe access without the need to check for bounds.
|
|
local array<String> modArray;
|
|
// Helpful sequence
|
|
white = chr(27)$chr(200)$chr(200)$chr(200);
|
|
// Transform our command into array for convenience
|
|
wordsArray = SplitString(MutateString, " ");
|
|
// Exit if command is empty
|
|
if(wordsArray.Length == 0)
|
|
return;
|
|
// Fancier access
|
|
command = wordsArray[0];
|
|
if(wordsArray.Length > 1)
|
|
mod = wordsArray[1];
|
|
else
|
|
mod = "";
|
|
i = 0;
|
|
while(i + 1 < wordsArray.Length || i < 10){
|
|
if(i + 1 < wordsArray.Length)
|
|
modArray[i] = wordsArray[i+1];
|
|
else
|
|
modArray[i] = "";
|
|
i ++;
|
|
}
|
|
nicePlayer = NicePlayerController(kfPlayer);
|
|
if(command ~= "ECHO")
|
|
kfPlayer.ClientMessage(Mid(MutateString, 5));
|
|
else if(command ~= "ZED" && bAlwaysAllowSkillChange)
|
|
ScrnGT.DramaticEvent(1.0);
|
|
else if(command ~= "SAVECFG" && nicePlayer != none)
|
|
nicePlayer.ClientSaveConfig();
|
|
else if(command ~= "CONFIG" && nicePlayer != none){
|
|
if(nicePlayer.bFlagAltSwitchesModes)
|
|
nicePlayer.ClientMessage(white$"Alt fire button will switch between single and burst modes for assault rifles");
|
|
else
|
|
nicePlayer.ClientMessage(white$"Alt fire button will shoot either single or burst mode for assault rifles");
|
|
if(nicePlayer.bFlagShowHLMessages)
|
|
nicePlayer.ClientMessage(white$"Messages about HL change will be displayed for you");
|
|
else
|
|
nicePlayer.ClientMessage(white$"Messages about HL change will be hidden from you");
|
|
}
|
|
else if(command ~= "HLMESSAGES" && nicePlayer != none){
|
|
if(mod ~= "ON")
|
|
nicePlayer.ServerSetHLMessages(true);
|
|
else if(mod ~= "OFF")
|
|
nicePlayer.ServerSetHLMessages(false);
|
|
}
|
|
else if(command ~= "ALTSWITCH"){
|
|
if(mod ~= "ON")
|
|
nicePlayer.ServerSetAltSwitchesModes(true);
|
|
else if(mod ~= "OFF")
|
|
nicePlayer.ServerSetAltSwitchesModes(false);
|
|
}
|
|
else if(command ~= "SETKEY" && nicePlayer != none){
|
|
if(Int(mod) > 0)
|
|
nicePlayer.ClientSetKey(Int(mod));
|
|
}
|
|
else if(command ~= "NICEWEAPMANAGE" && nicePlayer != none){
|
|
if(mod ~= "ON")
|
|
nicePlayer.ClientSetNiceWeapManagement(true);
|
|
else if(mod ~= "OFF")
|
|
nicePlayer.ClientSetNiceWeapManagement(false);
|
|
}
|
|
else if(command ~= "DEBUG" && nicePlayer != none){
|
|
if(mod ~= "ON")
|
|
nicePlayer.ServerSetDebug(true);
|
|
else if(mod ~= "OFF")
|
|
nicePlayer.ServerSetDebug(false);
|
|
}
|
|
else if(command ~= "LOGLINE" && nicePlayer != none)
|
|
nicePlayer.ClientLog("UserLine:"$mod);
|
|
else if(command ~= "CREATE"){
|
|
nicePlayer.ClientMessage("ATTEMPT"@string(serverStorage));
|
|
serverStorage.CreateData(modArray[0], NSP_HIGH);
|
|
remoteData = NiceServerData(serverStorage.GetData(modArray[0]));
|
|
remoteData.isAdminOnly = true;
|
|
nicePlayer.ClientMessage("ATTEMPT2"@string(remoteData));
|
|
}
|
|
else if(command ~= "CREATELOW"){
|
|
serverStorage.CreateData(modArray[0], NSP_LOW);
|
|
}
|
|
else if(command ~= "SET"){
|
|
remoteData = NiceServerData(serverStorage.GetData(modArray[0]));
|
|
nicePlayer.ClientMessage("SETATTEMPT"@string(remoteData));
|
|
remoteData.SetInt(modArray[1], Int(modArray[2]));
|
|
nicePlayer.ClientMessage("SETATTEMPT 2"@modArray[1]@modArray[2]);
|
|
}
|
|
else if(command ~= "PRINT"){
|
|
nicePlayer.ClientPrint();
|
|
}
|
|
else if(command ~= "TEST"){
|
|
inputStream = new class'BitStreamWriter';
|
|
outputStream = new class'BitStreamReader';
|
|
inputStream.WriteInt(Len(mod), 5);
|
|
inputStream.WriteClassName(mod);
|
|
outputStream.Initialize(inputStream.GetData());
|
|
readLenght = outputStream.ReadInt(5);
|
|
nicePlayer.ClientMessage("Input lenght:" @ string(Len(mod)));
|
|
nicePlayer.ClientMessage("Compressed lenght:" @ string(inputStream.GetSizeInBytes()) );
|
|
nicePlayer.ClientMessage("Output:"@outputStream.ReadClassName(readLenght));
|
|
}
|
|
Super.Mutate(MutateString, kfPlayer);
|
|
}
|
|
/* Good test for writer
|
|
else if(command ~= "TEST"){
|
|
inputStream = new class'BitStreamWriter';
|
|
outputStream = new class'BitStreamReader';
|
|
//stream.PushByte(167, int(mod));
|
|
inputStream.WriteInt(3, 3);
|
|
inputStream.WriteByte(49, 7);
|
|
inputStream.WriteInt(1651779982, 25);
|
|
inputStream.WriteInt(2, 2);
|
|
bytes = inputStream.GetData();
|
|
bits = inputStream.GetSize();
|
|
nicePlayer.ClientMessage("SIZE:" @ string(bits));
|
|
for (i = 0; i < bytes.length; i += 1) {
|
|
nicePlayer.ClientMessage("Content:" @ string(bytes[i]));
|
|
}
|
|
outputStream.Initialize(bytes);
|
|
//nicePlayer.ClientMessage("OUT:" @ string(outputStream.ReadByte(3)));
|
|
//nicePlayer.ClientMessage("OUT:" @ string(outputStream.ReadByte(7)));
|
|
nicePlayer.ClientMessage("OUT:" @ string(outputStream.ReadByte(8)));
|
|
nicePlayer.ClientMessage("OUT:" @ string(outputStream.ReadByte(4)));
|
|
nicePlayer.ClientMessage("OUT:" @ string(outputStream.ReadByte(4)));
|
|
outputStream.Initialize(bytes);
|
|
nicePlayer.ClientMessage("OUT:" @ string(outputStream.ReadByte(3)));
|
|
nicePlayer.ClientMessage("OUT:" @ string(outputStream.ReadByte(7)));
|
|
nicePlayer.ClientMessage("OUT:" @ string(outputStream.ReadByte(5)));
|
|
outputStream.Initialize(bytes);
|
|
nicePlayer.ClientMessage("OUT:" @ string(outputStream.ReadInt(3)));
|
|
nicePlayer.ClientMessage("OUT:" @ string(outputStream.ReadByte(7)));
|
|
nicePlayer.ClientMessage("OUT:" @ string(outputStream.ReadInt(25)));
|
|
nicePlayer.ClientMessage("OUT:" @ string(outputStream.ReadInt(2)));
|
|
}
|
|
*/
|
|
// Event functions
|
|
// Called at the start of the match
|
|
function MatchBegan(){
|
|
}
|
|
// Called when new wave begins
|
|
function WaveStart(){
|
|
local Controller P;
|
|
local NiceHumanPawn nicePawn;
|
|
local NicePlayerController nicePlayer;
|
|
bIsPreGame = false;
|
|
bIsTraderTime = false;
|
|
for(P = Level.ControllerList; P != none; P = P.nextController){
|
|
nicePlayer = NicePlayerController(P);
|
|
if(nicePlayer != none){
|
|
// Give out armor
|
|
nicePawn = NiceHumanPawn(nicePlayer.Pawn);
|
|
if(nicePawn != none && nicePawn.Health > 0){
|
|
nicePawn.bGotFreeJacket = false;
|
|
nicePawn.getFreeJacket();
|
|
nicePawn.bReactiveArmorUsed = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Called when trader time begins
|
|
simulated function TraderStart(){
|
|
local Controller P;
|
|
local NiceHumanPawn nicePawn;
|
|
local NicePlayerController nicePlayer;
|
|
bIsTraderTime = true;
|
|
for(P = Level.ControllerList; P != none; P = P.nextController){
|
|
nicePlayer = NicePlayerController(P);
|
|
if(nicePlayer != none){
|
|
nicePlayer.TryActivatePendingSkills();
|
|
nicePlayer.ClientSaveConfig();
|
|
nicePawn = NiceHumanPawn(nicePlayer.Pawn);
|
|
if (bUseProgresiveCash) {
|
|
GiveProgressiveDosh(nicePlayer);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Called when zed-time begins
|
|
simulated function ZedTimeActivated(){
|
|
}
|
|
// Called when zed-time deactivated
|
|
simulated function ZedTimeDeactivated(){
|
|
local Controller P;
|
|
local NicePlayerController Player;
|
|
junkieNextGoal=1;
|
|
junkieDoneGoals=0;
|
|
junkieDoneHeadshots=0;
|
|
for(P = Level.ControllerList; P != none; P = P.nextController){
|
|
Player = NicePlayerController(P);
|
|
if(Player != none)
|
|
Player.bJunkieExtFailed = false;
|
|
}
|
|
}
|
|
// Returns player record, corresponding to the given steam id
|
|
function PlayerRecord FindPlayerRecord(string steamID){
|
|
local int i;
|
|
local PlayerRecord newRecord;
|
|
for(i = 0;i < PlayerDatabase.Length;i ++)
|
|
if(PlayerDatabase[i].steamID == steamID)
|
|
return PlayerDatabase[i];
|
|
newRecord.steamID = steamID;
|
|
newRecord.bHasSpawned = false;
|
|
newRecord.lastCashWave = 0;
|
|
newRecord.kills = 0;
|
|
newRecord.assists = 0;
|
|
newRecord.deaths = 0;
|
|
PlayerDatabase[PlayerDatabase.Length] = newRecord;
|
|
return newRecord;
|
|
}
|
|
// Updates existing PlayerRecord (with a same steam id) and adds a new one, if necessary (record with a same steam is not found)
|
|
function UpdatePlayerRecord(PlayerRecord record){
|
|
local int i;
|
|
for(i = 0;i < PlayerDatabase.Length;i ++)
|
|
if(PlayerDatabase[i].steamID == record.steamID){
|
|
PlayerDatabase[i] = record;
|
|
return;
|
|
}
|
|
PlayerDatabase[PlayerDatabase.Length] = record;
|
|
}
|
|
// Checks if it should be possible to change skills right now
|
|
function bool CanChangeSkill(NicePlayerController player){
|
|
local PlayerRecord record;
|
|
record = FindPlayerRecord(player.SteamID64);
|
|
return (bIsTraderTime || (bIsPreGame && bInitialTrader) || bAlwaysAllowSkillChange || !record.bHasSpawned);
|
|
}
|
|
// Outputs info about given skill in console
|
|
function DisplaySkill(class<NiceSkill> skill, int level, bool selected, PlayerController player){
|
|
local String skillColor;
|
|
local String white;
|
|
if(selected)
|
|
skillColor = chr(27)$chr(1)$chr(200)$chr(1);
|
|
else
|
|
skillColor = chr(27)$chr(200)$chr(1)$chr(1);
|
|
white = chr(27)$chr(200)$chr(200)$chr(200);
|
|
player.ClientMessage(white$"Level"@String(level)$skillColor@"skill"$white$":"@skill.default.SkillName);
|
|
// Just in case description is too long
|
|
player.ClientMessage(" ");
|
|
}
|
|
function UpdateHealthLevels(){
|
|
local Controller P, S;
|
|
local NiceHumanPawn updatePawn;
|
|
for(P = Level.ControllerList;P != none;P = P.nextController){
|
|
updatePawn = NiceHumanPawn(P.Pawn);
|
|
if(updatePawn == none)
|
|
continue;
|
|
updatePawn.HealthMax = (updatePawn.default.HealthMax + updatePawn.HealthBonus) * updatePawn.ScrnPerk.static.HealthMaxMult(KFPlayerReplicationInfo(P.PlayerReplicationInfo), updatePawn);
|
|
for(S = Level.ControllerList;S != none;S = S.nextController)
|
|
if(NicePlayerController(S) != none)
|
|
NicePlayerController(S).ClientUpdatePawnMaxHealth(updatePawn, updatePawn.HealthMax);
|
|
}
|
|
}
|
|
function BroadcastSkills(){
|
|
local int i, j;
|
|
local bool bSameSkillFound;
|
|
local Controller P;
|
|
local NicePlayerController nicePlayer;
|
|
local array< class<NiceSkill> > playerSkills;
|
|
// Skills to broadcast
|
|
local array<int> teamNumbers;
|
|
local array< class<NiceSkill> > skillsToSend;
|
|
for(P = Level.ControllerList;P != none;P = P.nextController){
|
|
nicePlayer = NicePlayerController(P);
|
|
if(nicePlayer != none){
|
|
playerSkills = nicePlayer.GetActiveBroadcastSkills();
|
|
// Process player's skills
|
|
for(i = 0;i < playerSkills.Length;i ++){
|
|
bSameSkillFound = false;
|
|
// Try to find if someone already shares the same skill in the same team
|
|
for(j = 0;j < skillsToSend.Length && !bSameSkillFound;j ++)
|
|
if(playerSkills[i] == skillsToSend[j] && teamNumbers[j] == nicePlayer.PlayerReplicationInfo.Team.TeamIndex)
|
|
bSameSkillFound = true;
|
|
// If not - add it
|
|
if(!bSameSkillFound){
|
|
teamNumbers[teamNumbers.Length] = nicePlayer.PlayerReplicationInfo.Team.TeamIndex;
|
|
skillsToSend[skillsToSend.Length] = playerSkills[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for(P = Level.ControllerList;P != none;P = P.nextController){
|
|
nicePlayer = NicePlayerController(P);
|
|
if(nicePlayer != none){
|
|
for(i = 0;i < skillsToSend.Length;i ++)
|
|
if(teamNumbers[i] == nicePlayer.PlayerReplicationInfo.Team.TeamIndex)
|
|
nicePlayer.ClientReceiveSkill(skillsToSend[i]);
|
|
nicePlayer.ClientBroadcastEnded();
|
|
}
|
|
}
|
|
}
|
|
// Function for string splitting, because why would we have it as a standard function? It would be silly, right?
|
|
function array<string> SplitString(string inputString, string div){
|
|
local array<string> parts;
|
|
local bool bEOL;
|
|
local string tempChar;
|
|
local int preCount, curCount, partCount, strLength;
|
|
strLength = Len(inputString);
|
|
if(strLength == 0)
|
|
return parts;
|
|
bEOL = false;
|
|
preCount = 0;
|
|
curCount = 0;
|
|
partCount = 0;
|
|
while(!bEOL)
|
|
{
|
|
tempChar = Mid(inputString, curCount, 1);
|
|
if(tempChar != div)
|
|
curCount ++;
|
|
else
|
|
{
|
|
if(curCount == preCount)
|
|
{
|
|
curCount ++;
|
|
preCount ++;
|
|
}
|
|
else
|
|
{
|
|
parts[partCount] = Mid(inputString, preCount, curCount - preCount);
|
|
partCount ++;
|
|
preCount = curCount + 1;
|
|
curCount = preCount;
|
|
}
|
|
}
|
|
if(curCount == strLength)
|
|
{
|
|
if(preCount != strLength)
|
|
parts[partCount] = Mid(inputString, preCount, curCount);
|
|
bEOL = true;
|
|
}
|
|
}
|
|
return parts;
|
|
}
|
|
// Function for broadcasting messages to players
|
|
function BroadcastToAll(string message){
|
|
local Controller P;
|
|
local PlayerController Player;
|
|
for(P = Level.ControllerList; P != none; P = P.nextController){
|
|
Player = PlayerController(P);
|
|
if(Player != none)
|
|
Player.ClientMessage(message);
|
|
}
|
|
}
|
|
// Function for finding number, corresponding to zed's name
|
|
function int ZedNumber(String ZedName){
|
|
local int i;
|
|
for(i = 0;i < ZedDatabase.Length;i ++)
|
|
if(ZedName ~= ZedDatabase[i].ZedName)
|
|
return i;
|
|
return -1;
|
|
}
|
|
// Function for correct hp scaling
|
|
function float hpScale(float hpScale) {
|
|
return 1.0 + 5.0 * hpScale;
|
|
}
|
|
static function FillPlayInfo(PlayInfo PlayInfo){
|
|
Super.FillPlayInfo(PlayInfo);
|
|
PlayInfo.AddSetting("NicePack", "bScaleZedHealth", "Scale zeds' health?", 0, 0, "check");
|
|
PlayInfo.AddSetting("NicePack", "bReplacePickups", "Replace pickups?", 0, 0, "check");
|
|
PlayInfo.AddSetting("NicePack", "bInitialTrader", "Use init trader?", 0, 0, "check");
|
|
PlayInfo.AddSetting("NicePack", "bStillDuringInitTrader", "Be still during init trader?", 0, 0, "check");
|
|
PlayInfo.AddSetting("NicePack", "initialTraderTime", "Time for init trader?", 0, 0, "text", "3;1:999");
|
|
PlayInfo.AddSetting("NicePack", "bUseProgresiveCash", "Use progressive dosh?", 0, 0, "check");
|
|
PlayInfo.AddSetting("NicePack", "bConvertExp", "Convert old exp?", 0, 0, "check");
|
|
PlayInfo.AddSetting("NicePack", "bAlwaysAllowSkillChange", "Skill change at anytime?", 0, 0, "check");
|
|
PlayInfo.AddSetting("NicePack", "minimalSpawnDistance", "Min spawn distance", 0, 0, "text", "5;0:99999");
|
|
PlayInfo.AddSetting("NicePack", "minSpawnRate", "Min spawn rate", 0, 0, "text", "6;0.0:10.0");
|
|
PlayInfo.AddSetting("NicePack", "maxSpawnRate", "Max spawn rate", 0, 0, "text", "6;0.0:10.0");
|
|
PlayInfo.AddSetting("NicePack", "bOneFFIncOnly", "Only 1 FF increase?", 0, 0, "check");
|
|
PlayInfo.AddSetting("NicePack", "bNoLateFFIncrease", "FF increase wave 1 only?", 0, 0, "check");
|
|
}
|
|
static function string GetDescriptionText(string SettingName){
|
|
switch (SettingName){
|
|
case "bScaleZedHealth":
|
|
return "Should we scale health off all zeds to 6-player level?";
|
|
case "bReplacePickups":
|
|
return "Should we replace all pickups with their Nice versions when available?";
|
|
case "bInitialTrader":
|
|
return "Use initial trader system?";
|
|
case "bStillDuringInitTrader":
|
|
return "Force players to stand still during initial trader?";
|
|
case "initialTraderTime":
|
|
return "How much time should be allowed for initial trade?";
|
|
case "bUseProgresiveCash":
|
|
return "Use progressive dosh system?";
|
|
case "bConvertExp":
|
|
return "Should we convert old exp into a new one?";
|
|
case "bAlwaysAllowSkillChange":
|
|
return "Allows changing skills at any time.";
|
|
case "minimalSpawnDistance":
|
|
return "Minimal distance between ZedVolume and players that should allow for zeds to spawn.";
|
|
case "minSpawnRate":
|
|
return "Minimal allowed spawn rate.";
|
|
case "maxSpawnRate":
|
|
return "Maximal allowed spawn rate.";
|
|
case "bOneFFIncOnly":
|
|
return "Option that only allows one FF increase per game.";
|
|
case "bNoLateFFIncrease":
|
|
return "Disables FF increase through voting after 1st wave.";
|
|
}
|
|
return Super.GetDescriptionText(SettingName);
|
|
}
|
|
defaultproperties
|
|
{
|
|
bScaleZedHealth=True
|
|
bReplacePickups=True
|
|
bInitialTrader=True
|
|
initialTraderTime=10
|
|
bUseProgresiveCash=True
|
|
waveCash(0)=1000
|
|
waveCash(1)=900
|
|
waveCash(2)=800
|
|
waveCash(3)=650
|
|
waveCash(4)=600
|
|
waveCash(5)=450
|
|
waveCash(6)=350
|
|
waveCash(7)=250
|
|
lateMultiplier=0.5
|
|
bConvertExp=True
|
|
vetFieldMedicExpCost=2.000000
|
|
vetFieldMedicDmgExpCost=0.025000
|
|
vetSharpHeadshotExpCost=10.000000
|
|
vetSupportDamageExpCost=0.050000
|
|
vetCommandoDamageExpCost=0.050000
|
|
vetDemoDamageExpCost=0.050000
|
|
vetZerkDamageExpCost=0.050000
|
|
vetHeavyMGDamageExpCost=0.050000
|
|
vetGunslingerKillExpCost=20.000000
|
|
bigZedMinHealth=1000
|
|
mediumZedMinHealth=500
|
|
minSpawnRate=0.700000
|
|
maxSpawnRate=1.500000
|
|
minimalSpawnDistance=600
|
|
bNoLateFFIncrease=True
|
|
junkieNextGoal=1
|
|
bIsPreGame=True
|
|
pickupReplaceArray(0)=(vanillaClass=Class'KFMod.MAC10Pickup',scrnClass=Class'ScrnBalanceSrv.ScrnMAC10Pickup',NewClass=Class'NicePack.NiceMAC10Pickup')
|
|
pickupReplaceArray(1)=(vanillaClass=Class'KFMod.WinchesterPickup',scrnClass=Class'ScrnBalanceSrv.ScrnWinchesterPickup',NewClass=Class'NicePack.NiceWinchesterPickup')
|
|
pickupReplaceArray(2)=(vanillaClass=Class'KFMod.CrossbowPickup',scrnClass=Class'ScrnBalanceSrv.ScrnCrossbowPickup',NewClass=Class'NicePack.NiceCrossbowPickup')
|
|
pickupReplaceArray(3)=(vanillaClass=Class'KFMod.SPSniperPickup',scrnClass=Class'ScrnBalanceSrv.ScrnSPSniperPickup',NewClass=Class'NicePack.NiceMaulerPickup')
|
|
pickupReplaceArray(4)=(vanillaClass=Class'KFMod.M14EBRPickup',scrnClass=Class'ScrnBalanceSrv.ScrnM14EBRPickup',NewClass=Class'NicePack.NiceM14EBRPickup')
|
|
pickupReplaceArray(5)=(vanillaClass=Class'KFMod.M99Pickup',scrnClass=Class'ScrnBalanceSrv.ScrnM99Pickup',NewClass=Class'NicePack.NiceM99Pickup')
|
|
pickupReplaceArray(6)=(vanillaClass=Class'KFMod.ShotgunPickup',scrnClass=Class'ScrnBalanceSrv.ScrnShotgunPickup',NewClass=Class'NicePack.NiceShotgunPickup')
|
|
pickupReplaceArray(7)=(vanillaClass=Class'KFMod.BoomStickPickup',scrnClass=Class'ScrnBalanceSrv.ScrnBoomStickPickup',NewClass=Class'NicePack.NiceBoomStickPickup')
|
|
pickupReplaceArray(8)=(vanillaClass=Class'KFMod.NailGunPickup',scrnClass=Class'ScrnBalanceSrv.ScrnNailGunPickup',NewClass=Class'NicePack.NiceNailGunPickup')
|
|
pickupReplaceArray(9)=(vanillaClass=Class'KFMod.KSGPickup',scrnClass=Class'ScrnBalanceSrv.ScrnKSGPickup',NewClass=Class'NicePack.NiceKSGPickup')
|
|
pickupReplaceArray(10)=(vanillaClass=Class'KFMod.BenelliPickup',scrnClass=Class'ScrnBalanceSrv.ScrnBenelliPickup',NewClass=Class'NicePack.NiceBenelliPickup')
|
|
pickupReplaceArray(11)=(vanillaClass=Class'KFMod.AA12Pickup',scrnClass=Class'ScrnBalanceSrv.ScrnAA12Pickup',NewClass=Class'NicePack.NiceAA12Pickup')
|
|
NiceUniversalDescriptions(0)="Survive on %m in ScrN Balance mode"
|
|
NiceUniversalDescriptions(1)="Survive on %m in ScrN Balance mode with Hardcore Level 5+"
|
|
NiceUniversalDescriptions(2)="Survive on %m in ScrN Balance mode with Hardcore Level 10+"
|
|
NiceUniversalDescriptions(3)="Survive on %m in ScrN Balance mode with Hardcore Level 15+"
|
|
bAddToServerPackages=True
|
|
GroupName="KFNicePack"
|
|
FriendlyName="Package for nice/mean servers"
|
|
Description="Does stuff."
|
|
bAlwaysRelevant=True
|
|
RemoteRole=ROLE_SimulatedProxy
|
|
}
|