• Please make sure you are familiar with the forum rules. You can find them here: https://forums.tripwireinteractive.com/index.php?threads/forum-rules.2334636/

Code Problem since patch 1063

FluX

Grizzled Veteran
Oct 26, 2010
5,378
234
www.fluxiserver.co.uk
Hi guys. I have been getting a problem since I have installed the latest patch onto my custom server. Now for some reason, nothing spawns unless I use default zeds. My server uses fully customised versions for more control.

KFMod.KFGametype.BuildNextSquad > No squads to initialize with.

Anyone else got this or have any idea what to do? Never seen it before and looked but found nothing unusual.
 
Well the code to give that error message is in BuildNextSquad and only happens if the SquadsToUse.Length is zero. Stuff that function depends on are LoadUpMonsterList() and Waves.WaveMasks when it comes to generating that list each time. WaveMasks were moved around on the defaultproperties list, so look out for any possible issues.

Consider using the commented out debugger in SetupWave() to see what's going on in the initialization process. I have KFGameType's code from before and after the update and I don't see any substantial changes between them either.
 
Upvote 0
Everything working fine on our servers. All standard, Halloween and Xmas zed are spawning without any problems.

You are getting BuildNextSquad error because none of zeds in your collection was able to spawn. You should look for an issue inside your custom zed classes. What classes are they extended from? KFMonster? ZombieClot? ZombieClot_STANDARD? ZombieClot_HALLOWEEN?
 
Upvote 0
Well what i've got is this:

MutCustomMonsters.uc
Code:
/*
Custom monster balance mutator
(c) PooSH, 2012
Contact via Steam: [ScrN]PooSH 

Edited by FluX for FluXiPerks
*/
 
class MutCustomMonsters extends Mutator
    config (FluXiPerks);
    
var const string MonsterGroup;
    
var() config string ShiverPkgName;
var() config string ShiversBroPkgName;
var() config string HellfirePkgName;
var() config bool bAddShivers;
var() config bool bAddShiversBro;
var() config bool bAddHellfire;

var KFGameType KF;

/*function GetServerDetails( out GameInfo.ServerResponseLine ServerState )
{
	// append the mutator name.
	local int i;
    
    super.GetServerDetails(ServerState);
    
	i = ServerState.ServerInfo.Length;
	ServerState.ServerInfo.insert(i, 1);
    
	ServerState.ServerInfo[i].Key = "ScrnMonsters Version";
	ServerState.ServerInfo[i++].Value = String(VERSION);
}*/

static function FillPlayInfo(PlayInfo PlayInfo)
{
	Super.FillPlayInfo(PlayInfo);
	
    PlayInfo.AddSetting(default.MonsterGroup,"bAddShivers","Add Shivers to the game",1,0, "Check");
    PlayInfo.AddSetting(default.MonsterGroup,"bAddShiversBro","Add Shivers Brother to the game",1,0, "Check");
    PlayInfo.AddSetting(default.MonsterGroup,"bAddHellfire","Add Hellfires to the game",1,0, "Check");
    
	PlayInfo.AddSetting(default.MonsterGroup, "ShiverPkgName", "Shiver package name", 0, 0, "text");
	PlayInfo.AddSetting(default.MonsterGroup, "ShiverBroPkgName", "Shivers Brother package name", 0, 0, "text");  
	PlayInfo.AddSetting(default.MonsterGroup, "HellfirePkgName", "Hellfire package name", 0, 0, "text");
}

static event string GetDescriptionText(string PropName)
{
    switch (PropName)
    {
        case "bAddShivers":           	return "Add Shivers to the game, starting from wave 2";
        case "bAddShiversBro":           return "Add Shivers Brother to the game, starting from wave 6";
        case "bAddHellfire":           	return "Add Hellfires to the game, starting from wave 6";
        
        case "ShiverPkgName":           return "Name of the package (.u file), which contains Shiver's code";
        case "ShiverBroPkgName":           return "Name of the package (.u file), which contains Shiver's Brother code";
        case "HellfirePkgName":           return "Name of the package (.u file), which contains Hellfire's code";
    }
    return Super.GetDescriptionText(PropName);
}


function PostBeginPlay()
{
	KF = KFGameType(Level.Game);
	if (KF == none) {
		Log("ERROR: Wrong GameType (requires KFGameType)", Class.Outer.Name);
		Destroy();
		return;
	}
	
    KF.StandardMonsterClasses.Length = 0; //fill MonstersCollection instead
        
    if (bAddShivers) 
        AddShivers();
        
    if (bAddShiversBro) 
        AddShiversBro();
        
     if (bAddHellfire) 
        AddHellfire();
        
    //if (bHardPat && GetItemName(GetEndGameBoss()) ~= "ZombieBoss")
    //    SetEndGameBoss(string(Class'ScrnMonstersMut.HardPat'));

}

/*function SetEndGameBoss(string BossClassName)
{   
    KF.EndGameBossClass = BossClassName;
    KF.MonsterCollection.default.EndGameBossClass = BossClassName;
}

function string GetEndGameBoss()
{
    return KF.MonsterCollection.default.EndGameBossClass;
}*/


// Original code taken from MutAddShivers (c) [WPC]
function ReplaceMonsterInSquad(int SquadID, string SpecToReplace, int AmountToReplace, string NewMonsterID)
{
	if (SpecToReplace != "")
		KF.StandardMonsterSquads[SquadID] = AmountToReplace $ NewMonsterID
			$ RemoveFromSquad(KF.StandardMonsterSquads[SquadID], SpecToReplace, AmountToReplace);
	else
		KF.StandardMonsterSquads[SquadID] = AmountToReplace $ NewMonsterID
			$ KF.StandardMonsterSquads[SquadID];
}

// copy-pasted from MutAddShvers (c) [WPC]
function string RemoveFromSquad(string SquadStr, string ID, int NumToRemove)
{
	local int x;
	local int OldNum;
	
	// Locate said specimen
	for (x = 0; x < Len(SquadStr); x += 2)
		if (Mid(SquadStr, x + 1, 1) == ID)
			break;
			
	if (x == Len(SquadStr))
		return SquadStr;
		
	OldNum = int(Mid(SquadStr, x, 1));
		
	// If we are removing all, remove completely
	if (OldNum - NumToRemove <= 0)
		return Left(SquadStr, x) $ Right(SquadStr, Len(SquadStr) - x - 2);

	return Left(SquadStr, x) $ (OldNum - NumToRemove) $ ID $ Right(SquadStr, Len(SquadStr) - x - 2);
}

/**
 * Adds specimen to a special squad.
 * @param SpecialSquad : KF.ShortSpecialSquads[x], KF.NormalSpecialSquads[x] or KF.LongSpecialSquads[x],
 *                       where x is a wave number starting with 0 (pass 9 for wave 10)
 * @param ZedClass     : Zed class to add, e.g. ScrnMonstersMut.ZombieBruteSE
 * @param NumZeds      : Zed count to spawn in a squad 
 *
 * @author PooSH
 **/
function AddToSpecialSquadGT(KFGameType.SpecialSquad SpecialSquad, string ZedClass, int NumZeds)
{
    SpecialSquad.ZedClass.insert(0, 1);
    SpecialSquad.NumZeds.insert(0, 1);
    SpecialSquad.ZedClass[0] = ZedClass;
    SpecialSquad.NumZeds[0] = NumZeds;
}

function AddToSpecialSquadMC(KFMonstersCollection.SpecialSquad SpecialSquad, string ZedClass, int NumZeds)
{
    SpecialSquad.ZedClass.insert(0, 1);
    SpecialSquad.NumZeds.insert(0, 1);
    SpecialSquad.ZedClass[0] = ZedClass;
    SpecialSquad.NumZeds[0] = NumZeds;
}

// ShortIndex - aray index in ShortSpecialSquads, pass -1 to skip adding to squad 
function AddToSpecialSquad(string ZedClass, int NumZeds, int ShortIndex, int NormalIndex, int LongIndex)
{
    if ( ShortIndex >= 0) {
        //AddToSpecialSquadGT(KF.ShortSpecialSquads[ShortIndex], ZedClass, NumZeds);     
        AddToSpecialSquadMC(KF.MonsterCollection.default.ShortSpecialSquads[ShortIndex], ZedClass, NumZeds);     
    }
    if ( NormalIndex >= 0) {
        //AddToSpecialSquadGT(KF.NormalSpecialSquads[NormalIndex], ZedClass, NumZeds);     
        AddToSpecialSquadMC(KF.MonsterCollection.default.NormalSpecialSquads[NormalIndex], ZedClass, NumZeds);     
    }
    if ( LongIndex >= 0) {
        //AddToSpecialSquadGT(KF.LongSpecialSquads[LongIndex], ZedClass, NumZeds);     
        AddToSpecialSquadMC(KF.MonsterCollection.default.LongSpecialSquads[LongIndex], ZedClass, NumZeds);     
    }
}

function int AddMonsterClass(String MonsterClass, out string MonsterID)
{
	local int MonsterSlot;

    // Get new slot in monster list
    MonsterSlot = KF.MonsterCollection.default.MonsterClasses.Length;
    KF.MonsterCollection.default.MonsterClasses.Length = MonsterSlot + 1;
    MonsterID = Chr(65 + MonsterSlot);
    
    // Add monster to monster list
    KF.MonsterCollection.default.MonsterClasses[MonsterSlot].MClassName = MonsterClass;
    KF.MonsterCollection.default.MonsterClasses[MonsterSlot].MID = MonsterID;
    
    KF.MonsterCollection.default.StandardMonsterClasses[MonsterSlot] = KF.MonsterCollection.default.MonsterClasses[MonsterSlot];

    return MonsterSlot;
}

function AddShivers()
{
	local string MonsterID;

    AddMonsterClass("FluXiPerksV9.ZombieShiverEx", MonsterID);
    
    ReplaceMonsterInSquad(4, "A", 1/*2*/, MonsterID); // Clot
    ReplaceMonsterInSquad(6, "A", 1/*2*/, MonsterID); // Clot
    ReplaceMonsterInSquad(9, "C", 1, MonsterID); // Gorefast
    ReplaceMonsterInSquad(10, "A", 1, MonsterID); // Clot
    ReplaceMonsterInSquad(19, "C", 2, MonsterID); // Gorefast

}

function AddShiversBro()
{
	local string MonsterID;
	
	AddMonsterClass("FluXiPerksV9.ZombieShiverBro", MonsterID);
	
	ReplaceMonsterInSquad(12, "A", 1, MonsterID); // Clot
	ReplaceMonsterInSquad(14, "C", 1, MonsterID); // Gorefast
}

function AddHellfire()
{
	local string MonsterID;
	
	AddMonsterClass("FluXiPerksV9.ZombieHellFire", MonsterID);
	
	ReplaceMonsterInSquad(26, "", 1, MonsterID); // With two Husks
	
	ReplaceMonsterInSquad(12, "", 1, MonsterID); // Adds to wave 6+
	ReplaceMonsterInSquad(13, "", 1, MonsterID); // Adds to wave 6+
	
	AddToSpecialSquad("FluXiPerksV9.ZombieHellFire", 6, -1, -1, 2); // Add with the Flesh Pound
	
}

/*
function ReplaceMonsterInSquad(int SquadID, string SpecToReplace, int AmountToReplace, string NewMonsterID)
{
	if (SpecToReplace != "")
		KF.StandardMonsterSquads[SquadID] = AmountToReplace $ NewMonsterID
			$ RemoveFromSquad(KF.StandardMonsterSquads[SquadID], SpecToReplace, AmountToReplace);
	else
		KF.StandardMonsterSquads[SquadID] = AmountToReplace $ NewMonsterID
			$ KF.StandardMonsterSquads[SquadID];
}

function string RemoveFromSquad(string SquadStr, string ID, int NumToRemove)
{
	local int x;
	local int OldNum;
	
	// Locate said specimen
	for (x = 0; x < Len(SquadStr); x += 2)
		if (Mid(SquadStr, x + 1, 1) == ID)
			break;
			
	if (x == Len(SquadStr))
		return SquadStr;
		
	OldNum = int(Mid(SquadStr, x, 1));
		
	// If we are removing all, remove completely
	if (OldNum - NumToRemove <= 0)
		return Left(SquadStr, x) $ Right(SquadStr, Len(SquadStr) - x - 2);

	return Left(SquadStr, x) $ (OldNum - NumToRemove) $ ID $ Right(SquadStr, Len(SquadStr) - x - 2);
}

function AddToSpecialSquad(KFGameType.SpecialSquad SpecialSquad, string ZedClass, int NumZeds)
{
    SpecialSquad.ZedClass.insert(0, 1);
    SpecialSquad.NumZeds.insert(0, 1);
    SpecialSquad.ZedClass[0] = ZedClass;
    SpecialSquad.NumZeds[0] = NumZeds;
}
*/

defaultproperties
{
     MonsterGroup="Monsters"
     ShiverPkgName="FluXiPerksV9"     
     ShiversBroPkgName="FluXiPerksV9"
     HellfirePkgName="FluXiPerksV9"
     bAddShivers=True
     bAddShiversBro=True     
     bAddHellfire=True
     GroupName="KF-FluXiCustomMonsters"
     FriendlyName="[Fs] Custom Monster Spawn"
     Description="Spawning system for the custom specimens with or without changes to them."
     bAlwaysRelevant=True
     RemoteRole=ROLE_SimulatedProxy
}

And inside ServerPerksMut I have a globalconfig that changes zeds on the setting.
Code:
		if ( ZedTypes != 0 )
		{
			if ( ZedTypes == 1 )
				FsGameType(Level.Game).MonsterCollection = Class'FluXiPerksV9.FsMonstersHalloween';
			else if ( ZedTypes == 2 )
				FsGameType(Level.Game).MonsterCollection = Class'FluXiPerksV9.FsMonstersXMAS';
			else if ( ZedTypes == 3 )
				FsGameType(Level.Game).MonsterCollection = Class'FluXiPerksV9.FsMonstersMix';
			else if ( ZedTypes > 0 && ZedTypes < 4 )
				FsGameType(Level.Game).MonsterCollection = Class'FluXiPerksV9.FsMonstersCollection';
		}
		else FsGameType(Level.Game).MonsterCollection = Class'FluXiPerksV9.FsMonstersCollection';

Like I said, this has always worked until the latest patch. I have no idea if any changes have been made as there is no patch log, so i'm guessing not. To me, this is a really big wtf for something to suddenly stop working lol.

I must admit, it sounds to be like what the other guy is having with PoosH's ScrnBalance (no zeds are spawning at all).
 
Upvote 0
Getting all together:
Code:
    local FsGameType KF;
    
    KF = FsGameType(Level.Game);
    if ( ZedTypes != 0 )
    {
        if ( ZedTypes == 1 )
            KF.MonsterCollection = Class'FluXiPerksV9.FsMonstersHalloween';
        else if ( ZedTypes == 2 )
            KF.MonsterCollection = Class'FluXiPerksV9.FsMonstersXMAS';
        else if ( ZedTypes == 3 )
            KF.MonsterCollection = Class'FluXiPerksV9.FsMonstersMix';
        else if ( ZedTypes > 0 && ZedTypes < 4 )
            KF.MonsterCollection = Class'FluXiPerksV9.FsMonstersCollection';
    }
    else KF.MonsterCollection = Class'FluXiPerksV9.FsMonstersCollection';
[COLOR="Lime"]    for( i=0; i<KF.SpecialEventMonsterCollections.Length; ++i )
        KF.SpecialEventMonsterCollections[i] = KF.MonsterCollection;[/COLOR]
 
Upvote 0
try adding at end of PostBeginPlay:

Code:
    for(i= 0; i < KF.SpecialEventMonsterCollections.Length; i++) {
        KF.SpecialEventMonsterCollections[i]= KF.MonsterCollection;
    }

(like in scaryghost's patch...)

Sorry, I was looking on the parts above it. My bad. Will test it now.

Edit:
Hasn't worked. This still shows:
Warning: FsGameType KF-BioticsLab.FsGameType (Function KFmod.KFGameType.BuildNextSquad:009D) No squads to initilize with.
 
Last edited:
Upvote 0
Ok so I have resolved the problem. I remembered that I got my MonsterCollection replacement and reset code from PoosH's ScrnBalance a long time ago. He had helpped me quiet a bit and I ended up tweaking it so it doesn't work the same, but slightly different (due to mine being serverperks related, his is client based so different).

The code was fixed upon doing all zeds at once but never had checked squad length or specific game length. Once researching to see if PoosH had updated, I had looked into what he did and worked around his new fix. Turns out, this problem should of effected me awhile ago but for some reason, it never.

Thanks anyway guys, much appreciated.
 
Upvote 0