[Tutorial] Creating a Basic Mutator

  • 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/

braindead

FNG / Fresh Meat
Aug 22, 2009
918
346
0
Merry Ol' England
my bad, try this

Code:
class AmmoMut extends Mutator;
 

 
function PostBeginPlay() 
{  
SetTimer(300, true); 
} 
 
function Timer()
{
 local KFHumanPawn Player;
 local KFGameType KF;

    KF = KFGameType(Level.Game);
 
 foreach DynamicActors(class 'KFHumanPawn', Player)
 {
  if (KF!=none) && (KF.WaveNum >= 6) && (KF.NumPlayers >= 8)
  {
   GiveAmmo(Player);
   Player.ClientMessage ("You have been given an ammo box!");
   Player.PlaySound( Sound'KF_InventorySnd.Ammo_GenericPickup',,1.0,,600.f);
  }
  else return;
 }
}
 

FluX

Grizzled Veteran
Oct 26, 2010
5,392
233
63
www.fluxiserver.co.uk
my bad, try this

Code:
class AmmoMut extends Mutator;
 
 
 
function PostBeginPlay() 
{  
SetTimer(300, true); 
} 
 
function Timer()
{
 local KFHumanPawn Player;
 local KFGameType KF;
 
    KF = KFGameType(Level.Game);
 
 foreach DynamicActors(class 'KFHumanPawn', Player)
 {
 [COLOR=red] if (KF!=none) && (KF.WaveNum >= 6) && (KF.NumPlayers >= 8)[/COLOR]
  {
   GiveAmmo(Player);
   Player.ClientMessage ("You have been given an ammo box!");
   Player.PlaySound( Sound'KF_InventorySnd.Ammo_GenericPickup',,1.0,,600.f);
  }
  else return;
 }
}

Cheers that had a problem with the red line so I added ( )'s around the whole thing. It compiled but now it doesn't seem to actually want to give me the ammo anymore but the if statement is all that really has been changed. I changed the numbers to fit my testing so it came to this:

function Timer()
{
local KFHumanPawn Player;
local KFGameType KF;
KF = KFGameType(Level.Game);
foreach DynamicActors(class 'KFHumanPawn', Player)
{
if ((KF!=none) && (KF.WaveNum >= 2) && (KF.NumPlayers == 1))
{
GiveAmmo(Player);
Player.ClientMessage ("You have been given an ammo box!");
Player.PlaySound( Sound'KF_InventorySnd.Ammo_GenericPickup',,1.0,,600.f);
}
else return;
}
}

I also changed the timing to 5 instead of 600 to help the testing. All of a sudden I don't get ammo. :S In the logs nothing is said about the mutator. It's like it isn't getting to the section in yellow. Sorry for the indenting, the forums doesn't like it for some reason.
 

braindead

FNG / Fresh Meat
Aug 22, 2009
918
346
0
Merry Ol' England
hmmm thinking about it, you want this to happen on the the fly so try the tick instead?

Code:
class AmmoMut extends Mutator;
 
 
 
 
simulated function Tick(float DeltaTime)
{

 local KFHumanPawn Player;
 local KFGameType KF;
 
    KF = KFGameType(Level.Game);
 
 foreach DynamicActors(class 'KFHumanPawn', Player)
 {
  if ((KF!=none) && (KF.WaveNum >= 6) && (KF.NumPlayers >= 8))
    {
       GiveAmmo(Player);
       Player.ClientMessage ("You have been given an ammo box!");
       Player.PlaySound( Sound'KF_InventorySnd.Ammo_GenericPickup',,1.0,,600.f);
    }
 }

        super.Tick(Deltatime);
}
 

FluX

Grizzled Veteran
Oct 26, 2010
5,392
233
63
www.fluxiserver.co.uk
This is still not working lol. Why do I always pick the things that tend to have problems? :p

Here is my full code:
Code:
class AmmoMut extends Mutator;
simulated function Tick(float DeltaTime)
{
 local KFHumanPawn Player;
 local KFGameType KF;
 
    KF = KFGameType(Level.Game);
 
 foreach DynamicActors(class 'KFHumanPawn', Player)
 {
  if ((KF!=none) && (KF.WaveNum >= 2) && (KF.NumPlayers >= 1))
    {
       GiveAmmo(Player);
       Player.ClientMessage ("You have been given an ammo box!");
       Player.PlaySound( Sound'KF_InventorySnd.Ammo_GenericPickup',,1.0,,600.f);
    }
 }
        super.Tick(Deltatime);
}
function GiveAmmo(Actor Other)
{
 local Inventory CurInv;
 local int AmmoPickupAmount;
 for ( CurInv = Other.Inventory; CurInv != none; CurInv = CurInv.Inventory )
 {
  if ( KFAmmunition(CurInv) != none && KFAmmunition(CurInv).bAcceptsAmmoPickups )
  {
   if ( KFAmmunition(CurInv).AmmoPickupAmount > 1 )
   {
    if ( KFAmmunition(CurInv).AmmoAmount < KFAmmunition(CurInv).MaxAmmo )
    {
     if ( KFPlayerReplicationInfo(Pawn(Other).PlayerReplicationInfo) != none && KFPlayerReplicationInfo(Pawn(Other).PlayerReplicationInfo).ClientVeteranSkill != none )
     {
      AmmoPickupAmount = float(KFAmmunition(CurInv).AmmoPickupAmount) * KFPlayerReplicationInfo(Pawn(Other).PlayerReplicationInfo).ClientVeteranSkill.static.GetAmmoPickupMod(KFPlayerReplicationInfo(Pawn(Other).PlayerReplicationInfo), KFAmmunition(CurInv));
     }
     else
     {
      AmmoPickupAmount = KFAmmunition(CurInv).AmmoPickupAmount;
     }
     KFAmmunition(CurInv).AmmoAmount = Min(KFAmmunition(CurInv).MaxAmmo, KFAmmunition(CurInv).AmmoAmount + AmmoPickupAmount);
    }
   }
   else if ( KFAmmunition(CurInv).AmmoAmount < KFAmmunition(CurInv).MaxAmmo )
   {
    if ( FRand() <= (1.0 / Level.Game.GameDifficulty) )
    {
     KFAmmunition(CurInv).AmmoAmount++;
    }
   }
  }
 }
}

defaultproperties
{
 GroupName="KFAmmoMutator"
 FriendlyName="FluXiServer Ammo Mutator (Version 2.4)"
 Description="Mutator after every 10 minutes, gives you an ammo box."
}
 

braindead

FNG / Fresh Meat
Aug 22, 2009
918
346
0
Merry Ol' England
ok here ya go.

tried this in single player and it worked a charm, you just need to test it on a server to see if it works ok.

Code:
class AmmoMut extends Mutator;
simulated function Tick(float DeltaTime)
{
 local KFHumanPawn Player;
 local KFGameType KF;
 
    KF = KFGameType(Level.Game);
 
 foreach DynamicActors(class 'KFHumanPawn', Player)
 {
  if ((KF!=none) && (KF.WaveNum >= 2) && (KF.NumPlayers >= 1))
    {
       GiveAmmo(Player);
       Player.ClientMessage ("You have been given an ammo box!");
       Player.PlaySound( Sound'KF_InventorySnd.Ammo_GenericPickup',,1.0,,600.f);
    }
 }
        super.Tick(Deltatime);
}
function GiveAmmo(Pawn Other)
{
 local Inventory CurInv;
 local int AmmoPickupAmount;
 for ( CurInv = Other.Inventory; CurInv != none; CurInv = CurInv.Inventory )
 {
  if ( KFAmmunition(CurInv) != none && KFAmmunition(CurInv).bAcceptsAmmoPickups )
  {
   if ( KFAmmunition(CurInv).AmmoPickupAmount > 1 )
   {
    if ( KFAmmunition(CurInv).AmmoAmount < KFAmmunition(CurInv).MaxAmmo )
    {
     if ( KFPlayerReplicationInfo(Other.Controller.PlayerReplicationInfo) != none && KFPlayerReplicationInfo(Other.PlayerReplicationInfo).ClientVeteranSkill != none )
     {
      AmmoPickupAmount = float(KFAmmunition(CurInv).AmmoPickupAmount) * KFPlayerReplicationInfo(Other.PlayerReplicationInfo).ClientVeteranSkill.static.GetAmmoPickupMod(KFPlayerReplicationInfo(Other.Controller.PlayerReplicationInfo), KFAmmunition(CurInv));
     }
     else
     {
      AmmoPickupAmount = KFAmmunition(CurInv).AmmoPickupAmount;
     }
     KFAmmunition(CurInv).AmmoAmount = Min(KFAmmunition(CurInv).MaxAmmo, KFAmmunition(CurInv).AmmoAmount + AmmoPickupAmount);
    }
   }
   else if ( KFAmmunition(CurInv).AmmoAmount < KFAmmunition(CurInv).MaxAmmo )
   {
    if ( FRand() <= (1.0 / Level.Game.GameDifficulty) )
    {
     KFAmmunition(CurInv).AmmoAmount++;
    }
   }
  }
 }
}

defaultproperties
{
 GroupName="KFAmmoMutator"
 FriendlyName="FluXiServer Ammo Mutator (Version 2.4)"
 Description="Mutator after every 10 minutes, gives you an ammo box."
}
 

FluX

Grizzled Veteran
Oct 26, 2010
5,392
233
63
www.fluxiserver.co.uk
Right tested the last code you gave and it only works once the round ends.

I thought i'd try find a way of fixing the timer version and found out it does work. The only way it works is if (KF.WaveNum >= 2) is taken out :mad:.

This is the code I am currently using (and works):

Code:
class AmmoMut extends Mutator;
function PostBeginPlay()
{
 SetTimer(5, true);
}
function Timer()
{
 local KFHumanPawn Player;
 local KFGameType KF;
 
    KF = KFGameType(Level.Game);
 
 foreach DynamicActors(class 'KFHumanPawn', Player)
 {
  if ((KF!=none) && (KF.NumPlayers > 0))
    {
       GiveAmmo(Player);
       Player.ClientMessage ("You have been given an ammo box!");
       Player.PlaySound( Sound'KF_InventorySnd.Ammo_GenericPickup',,1.0,,600.f);
    }
   else return;
 }
}
function GiveAmmo(Pawn Other)
{
 local Inventory CurInv;
 local int AmmoPickupAmount;
 for ( CurInv = Other.Inventory; CurInv != none; CurInv = CurInv.Inventory )
 {
  if ( KFAmmunition(CurInv) != none && KFAmmunition(CurInv).bAcceptsAmmoPickups )
  {
   if ( KFAmmunition(CurInv).AmmoPickupAmount > 1 )
   {
    if ( KFAmmunition(CurInv).AmmoAmount < KFAmmunition(CurInv).MaxAmmo )
    {
     if ( KFPlayerReplicationInfo(Other.Controller.PlayerReplicationInfo) != none && KFPlayerReplicationInfo(Other.PlayerReplicationInfo).ClientVeteranSkill != none )
     {
      AmmoPickupAmount = float(KFAmmunition(CurInv).AmmoPickupAmount) * KFPlayerReplicationInfo(Other.PlayerReplicationInfo).ClientVeteranSkill.static.GetAmmoPickupMod(KFPlayerReplicationInfo(Other.Controller.PlayerReplicationInfo), KFAmmunition(CurInv));
     }
     else
     {
      AmmoPickupAmount = KFAmmunition(CurInv).AmmoPickupAmount;
     }
     KFAmmunition(CurInv).AmmoAmount = Min(KFAmmunition(CurInv).MaxAmmo, KFAmmunition(CurInv).AmmoAmount + AmmoPickupAmount);
    }
   }
   else if ( KFAmmunition(CurInv).AmmoAmount < KFAmmunition(CurInv).MaxAmmo )
   {
    if ( FRand() <= (1.0 / Level.Game.GameDifficulty) )
    {
     KFAmmunition(CurInv).AmmoAmount++;
    }
   }
  }
 }
}
defaultproperties
{
 GroupName="KFAmmoMutator"
 FriendlyName="FluXiServer Ammo Mutator (Version 2.4)"
 Description="Mutator after every 10 minutes, gives you an ammo box."
}

Is the (KF.WaveNum >= 2) really asking which wave that the game is currently on? I saw another thing like it but thought this was it.
 
Last edited:

braindead

FNG / Fresh Meat
Aug 22, 2009
918
346
0
Merry Ol' England
try this? it will only work after wave 2 and will not happen at trader time (i hope?)

Code:
class AmmoMut extends Mutator;

function PostBeginPlay()
{
 SetTimer(5, true);
}
function Timer()
{
 local KFHumanPawn Player;
 local KFGameType KF;
 
    KF = KFGameType(Level.Game);

[COLOR=MediumTurquoise]    if( !KF.bWaveInProgress || KF.Wavenum < 2 )
    {
    return;
    }[/COLOR]
 
 foreach DynamicActors(class 'KFHumanPawn', Player)
 {
  if ((KF!=none) && (KF.NumPlayers > 0))
    {
       GiveAmmo(Player);
       Player.ClientMessage ("You have been given an ammo box!");
       Player.PlaySound( Sound'KF_InventorySnd.Ammo_GenericPickup',,1.0,,600.f);
    }
   else return;
 }
}
function GiveAmmo(Pawn Other)
{
 local Inventory CurInv;
 local int AmmoPickupAmount;
 for ( CurInv = Other.Inventory; CurInv != none; CurInv = CurInv.Inventory )
 {
  if ( KFAmmunition(CurInv) != none && KFAmmunition(CurInv).bAcceptsAmmoPickups )
  {
   if ( KFAmmunition(CurInv).AmmoPickupAmount > 1 )
   {
    if ( KFAmmunition(CurInv).AmmoAmount < KFAmmunition(CurInv).MaxAmmo )
    {
     if ( KFPlayerReplicationInfo(Other.Controller.PlayerReplicationInfo) != none && KFPlayerReplicationInfo(Other.PlayerReplicationInfo).ClientVeteranSkill != none )
     {
      AmmoPickupAmount = float(KFAmmunition(CurInv).AmmoPickupAmount) * KFPlayerReplicationInfo(Other.PlayerReplicationInfo).ClientVeteranSkill.static.GetAmmoPickupMod(KFPlayerReplicationInfo(Other.Controller.PlayerReplicationInfo), KFAmmunition(CurInv));
     }
     else
     {
      AmmoPickupAmount = KFAmmunition(CurInv).AmmoPickupAmount;
     }
     KFAmmunition(CurInv).AmmoAmount = Min(KFAmmunition(CurInv).MaxAmmo, KFAmmunition(CurInv).AmmoAmount + AmmoPickupAmount);
    }
   }
   else if ( KFAmmunition(CurInv).AmmoAmount < KFAmmunition(CurInv).MaxAmmo )
   {
    if ( FRand() <= (1.0 / Level.Game.GameDifficulty) )
    {
     KFAmmunition(CurInv).AmmoAmount++;
    }
   }
  }
 }
}
defaultproperties
{
 GroupName="KFAmmoMutator"
 FriendlyName="FluXiServer Ammo Mutator (Version 2.4)"
 Description="Mutator after every 10 minutes, gives you an ammo box."
}
 
  • Like
Reactions: FluX

FluX

Grizzled Veteran
Oct 26, 2010
5,392
233
63
www.fluxiserver.co.uk
Fairly stupid question but when I run UCC.exe it flashes a dos screen and then closes rather quickly, how do I run the make command?

Make a .bat file with this inside:

Code:
del filename.u
UCC make
UCC Dumpint filename.u
del steam_appid.txt
pause

But do remember to change the "filename.u" to the folder you are trying to compress.
 

RuneHarle

FNG / Fresh Meat
Jan 5, 2011
316
49
0
On Steam: VelvetHarle
Make a .bat file with this inside:

Code:
del filename.u
UCC make
UCC Dumpint filename.u
del steam_appid.txt
pause
But do remember to change the "filename.u" to the folder you are trying to compress.

Thank you, but I'm still having issues compiling the example mutator. It deletes the files and gives me 3 errors in the process.

I'll attach the .uc , .bat , and a screenshot of the errors

Batch File
Code:
del "C:\Program Files (x86)\Steam\steamapps\common\killingfloor\System\AddHealthRegen\classes\AddHealthRegen.uc"
"C:\Program Files (x86)\Steam\steamapps\common\killingfloor\System\UCC.exe" make
"C:\Program Files (x86)\Steam\steamapps\common\killingfloor\System\UCC.exe" Dumpint "C:\Program Files (x86)\Steam\steamapps\common\killingfloor\System\AddHealthRegen\classes\AddHealthRegen.uc"
del "C:\Program Files (x86)\Steam\steamapps\common\killingfloor\System\steam_appid.txt"
pause
Example Mutator
Code:
class AddHealthRegen extends Mutator;

function PostBeginPlay()
{
    SetTimer(3, true);
}

function Timer()
{
    local KFHumanPawn Player;
    
    foreach DynamicActors(class 'KFHumanPawn', Player)
    {
        if (Player.Health + 1 <= Player.HealthMax) Player.Health += 1;
        else Player.Health = Player.HealthMax;
    }
}

defaultproperties
{
    GroupName="KFAddHealthRegen"
    FriendlyName="Health Regeneration"
    Description="Slowly regenerates player"
}
Image of error located here
 

Snebbers

FNG / Fresh Meat
Jul 27, 2011
25
0
0
I know this off topic, but your Desktop picture, RuneHarle, is awesome.. May I ask where I could get such a picture?

And by the looks of things, according to your error I mean, it cannot find the textures required.
 

FluX

Grizzled Veteran
Oct 26, 2010
5,392
233
63
www.fluxiserver.co.uk
Hey, if you look above where it says "3 errors" in the picture you will see that it can't find 3 different TGA files you are trying to import. Make sure these files are put in the "../MutatorDirectory/Textures/" folder.
 

RuneHarle

FNG / Fresh Meat
Jan 5, 2011
316
49
0
On Steam: VelvetHarle
I know this off topic, but your Desktop picture, RuneHarle, is awesome.. May I ask where I could get such a picture?

And by the looks of things, according to your error I mean, it cannot find the textures required.

As for the picture, it's not my work but I can post the image on my photobucket account if you would like it as there is no way of me finding the artist to credit it.

As for the coding, I saw that it was erroring on textures but I don't understand why it is pulling textures in the first place. I didn't ask it to, to my knowledge.
 

FluX

Grizzled Veteran
Oct 26, 2010
5,392
233
63
www.fluxiserver.co.uk
As for the picture, it's not my work but I can post the image on my photobucket account if you would like it as there is no way of me finding the artist to credit it.

As for the coding, I saw that it was erroring on textures but I don't understand why it is pulling textures in the first place. I didn't ask it to, to my knowledge.

Thinking about it, it's not your file that's giving the error.
 

Snebbers

FNG / Fresh Meat
Jul 27, 2011
25
0
0
As for the picture, it's not my work but I can post the image on my photobucket account if you would like it as there is no way of me finding the artist to credit it.

As for the coding, I saw that it was erroring on textures but I don't understand why it is pulling textures in the first place. I didn't ask it to, to my knowledge.

I would be very grateful if you could do that :)

I'm sorry I am not much help I am fairly new to this coding.
 

RuneHarle

FNG / Fresh Meat
Jan 5, 2011
316
49
0
On Steam: VelvetHarle
Solved texture errors, verified game integrity, still having issues with it not compiling.

Code:
del "C:\Program Files (x86)\Steam\steamapps\common\killingfloor\System\AddHealthRegen.u"
"C:\Program Files (x86)\Steam\steamapps\common\killingfloor\System\UCC.exe" make
del "C:\Program Files (x86)\Steam\steamapps\common\killingfloor\System\steam_appid.txt"
pause
UPDATE:

Solved the problem of it not recognizing the mut, I didn't know that I couldnt seperate it from the main string to identify it as custom with
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
EditPackages=AddHealthRegen
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

new error
Spoiler!
 
Last edited: