![]() |
![]() |
|
#1
|
||||
|
||||
|
Ok. Now to try and continue the attempt to limit version miss matching and to help people out who wish to create custom perks or server admins who want to work custom weapons into their perks.
Note: This first post may look like a lot, but it's less than an afternoon's reading. Part One : Prerequisites Primers Forum member Benjamin created some very useful tutorials. I suggest you read the first one at least as it covers the actual set up and compiling of mods/muts/packages. Creating a Basic Mutator Mutator Essentials Multiplayer Mutators Modifying Existing Weapons C++ & UnrealScript Unreal Script is an object based programming language derived from C++. I'm not going to teach you about C++, I'm no where near qualified (or patient) enough to do so. http://www.cplusplus.com has all the info you need on C++ including tutorials. Take note of how object based programming works including inheritance and projected properties. In here are all the operators and statements you'll need for the maths and checks. UnrealScriptReference Has pretty much all the info you need on the unreal script functions and more. You can also use http://wiki.beyondunreal.com/ as a resource. This should be enough to get you started by the time you've had a skim over and maybe tried some of Benjamin's tutorials I'll have written up the next section of the tutorial. Note: To the experienced programmers; Marco, ScaryGhost, Benjamin etc. If you spot any mistakes or omissions please do send me a message and I'll correct any mistakes I've made. Also feel free to send any suggestions. Tutorial One – Setting Up & Testing So now that we have covered some basics of C++/UnrealScript and compiling we need to set ourselves up to build our new perks. There are other ways of doing this but this is the way I prefer to do things. First download and install ServerPerks from this thread. -Be sure to thank Marco while you are there. ![]() First create your mod folder; “WhiskyPerks” for this example and within that a folder called “classes” ![]() Next navigate to .../KillingFloor/System and open the killingfloor.ini In the EditPackages lines I add after ‘KFMutators’ the packages for ServerPerks and then your own. ![]() Now going back to our mod folder we set up I’m going to create a simple perk extension that I will use for following tutorials. This is saved as a .uc file in the classes folder. Don't forget the file name has to be the same as the class name. Code:
class WVetCommando extends SRVetCommando
abstract;
defaultproperties
{
VeterancyName="Whisky Commando"
}
Compile and if you’ve been following along you should have no problems. Next navigate to .../KillingFloor/System and open the ServerPerks.ini file (you can do this in game as well from the mutator window I just prefer doing it here) and add your new perk to the Perks= lines, in this case Perks=WhiskyPerks.WVetCommando. ![]() Run the game and test. (Don’t forget to turn on ServerPerks from the mutator menu!) -Remind me to take a picture to put here.- And there we have it, our very own ‘custom’ perk in game. Admittedly this is only a name change but it is a start. Next tutorial will show you how to start customising bonuses and discounts.
__________________
Whisky's Workshop ![]() "As you can see here, I'm -ALL ON MY F***ING OWN! Guys where the hell are you?!" Last edited by Gartley; 05-20-2012 at 08:56 PM. |
|
#2
|
||||
|
||||
|
Tutorial Two : Extending and Overriding Perks
We will start simply to begin with. Now you can find ALL the functions you need in other files, both in the original perks in the KFMod folder in your .../killingfloor/ directory and in Marco’s ServerPerksV5 source files which are still available on his thread. Returning to our new Commando class, there is a gun that he’s always enjoyed but finds very expensive. So let’s give him a discount on a weapon. Now there are two ways we can do this, we can either extend the function or overwrite the function. Extending a Function I’m going to opt to extend the function to start with because it’s less coding and I don't need to do it from scratch. Our weapon shall be the G36C by Flux. First download the mod and install it. You’ll need the files to be able to compile the perk. This is what we are going to add to our perk to give it a discount for the weapon. Code:
#exec obj load file="FX-KFG36C.u"
// Change the cost of particular items
static function float GetCostScaling(KFPlayerReplicationInfo KFPRI, class<Pickup> Item)
{
if ( Item == class'G36CPickup' )
{
return 0.9 - fmin(0.10 * float(KFPRI.ClientVeteranSkillLevel),0.6f); // Up to 70% discount on Assault Rifles
}
return super.GetCostScaling(KFPRI, Item);
}
Let us break it down: Code:
#exec obj load file="FX-KFG36C.u" Code:
// Change the cost of particular items Code:
static function float GetCostScaling(KFPlayerReplicationInfo KFPRI, class<Pickup> Item) Code:
if ( Item == class'G36CPickup' ) Code:
return 0.9 - fmin(0.10 * float(KFPRI.ClientVeteranSkillLevel),0.6f); // Up to 70% discount on Assault Rifles Code:
return super.GetCostScaling(KFPRI, Item); Compile and test by adding the weapon to the store and switching between perks to see the effect on the discount. Overriding a Function Overriding is ideal if you want replace a function completely, for example removing all damage bonues; like so. Code:
//Remove Damage Boosts
static function int AddDamage(KFPlayerReplicationInfo KFPRI, KFMonster Injured, KFPawn DamageTaker, int InDamage, class<DamageType> DmgType)
{
return InDamage;
}
Perk as it stands now:
Spoiler!
__________________
Whisky's Workshop ![]() "As you can see here, I'm -ALL ON MY F***ING OWN! Guys where the hell are you?!" Last edited by Gartley; 05-11-2012 at 04:02 PM. |
|
#3
|
||||
|
||||
|
Tutorial Three : Perk From Scratch with Custom Stats
“But Whisky, Gartley or whatever you call yourself” I hear you cry “I don’t want to edit existing perks I want to make my own big shiny new perk!” Well ok let us start to make our own perk then. Firstly we are going to start by setting up the requirements; scary ghost was kind enough to start this one off. So I’m going to use his as a base and work from there. I’ll also be turning the new commando perk into a standalone perk. #1: First we need a new damage type. Have the AwardDamage function use the ProgressCustomValue function. You'll want to derive your custom damage type from KFWeaponDamageType. Code:
class DamTypeG36CNew extends KFWeaponDamageType
abstract;
static function AwardDamage(KFSteamStatsAndAchievements KFStatsAndAchievements, int Amount)
{
if( SRStatsBase(KFStatsAndAchievements)!=None && SRStatsBase(KFStatsAndAchievements).Rep!=None )
SRStatsBase(KFStatsAndAchievements).Rep.ProgressCustomValue(Class'G36CProgress',Amount);
}
defaultproperties
{
DeathString="%o was shot by %k."
FemaleSuicide="%o was shot."
MaleSuicide="%o was shot again."
bArmorStops=False
bAlwaysGibs=True
bLocationalHit=False
GibPerterbation=1.000000
bCheckForHeadShots=False
}
Code:
class G36CProgress extends SRCustomProgressInt;
static function AwardDamage(KFSteamStatsAndAchievements KFStatsAndAchievements, int Amount)
{
if( SRStatsBase(KFStatsAndAchievements)!=None && SRStatsBase(KFStatsAndAchievements).Rep!=None )
SRStatsBase(KFStatsAndAchievements).Rep.ProgressCustomValue(Class'G36CProgress',Amount);
}
defaultproperties
{
ProgressName= "G36C Damage"
}
Code:
static function AddCustomStats( ClientPerkRepLink Other )
{
Other.AddCustomValue(Class'G36CProgress');
}
Code:
static function AddCustomStats( ClientPerkRepLink Other )
{
Other.AddCustomValue(Class'G36CProgress');
Class'G36CFire'.Default.DamageType = Class'DamTypeG36CNew';
}
Code:
var array<int> progressArray;
//Perk Progression
static function int GetPerkProgressInt( ClientPerkRepLink StatOther, out int FinalInt, byte CurLevel, byte ReqNum )
{
if (CurLevel < 7)
{
FinalInt= default.progressArray[curLevel];
}
else
{
FinalInt = default.progressArray[6]+GetDoubleScaling(CurLevel,500000);
}
return Min(StatOther.GetCustomValueInt(Class'G36CProgress'),FinalInt);
}
defaultproperties
{
progressArray(0)=5000
progressArray(1)=25000
progressArray(2)=100000
progressArray(3)=500000
progressArray(4)=1500000
progressArray(5)=3500000
progressArray(6)=5500000
}
#6: Set up the default properties including perk descriptions. If you wish the custom info to display past perk 6 you need to know your maths and string replacements. Don't forget to define in the properties if you use more than a single requirement and their description. Code:
static function string GetCustomLevelInfo( byte Level )
{
local string S;
S = Default.CustomLevelInfo;
ReplaceText(S,"%s",GetPercentStr(0.05 * float(Level)));
return S;
}
defaultproperties
{
progressArray(0)=5000
progressArray(1)=25000
progressArray(2)=100000
progressArray(3)=500000
progressArray(4)=1500000
progressArray(5)=3500000
progressArray(6)=5500000
VeterancyName="Whisky Commando"
OnHUDIcon=Texture'WhiskyPerks_T.WCommandoPerk'
OnHUDGoldIcon=Texture'WhiskyPerks_T.WCommandoPerk_Gold'
Requirements(0)="Deal %x G36C damage"
SRLevelEffects(0)="5% Perk Bonus"
SRLevelEffects(1)="10% Perk Bonus"
SRLevelEffects(2)="15% Perk Bonus"
SRLevelEffects(3)="20% Perk Bonus"
SRLevelEffects(4)="25% Perk Bonus"
SRLevelEffects(5)="30% Perk Bonus"
SRLevelEffects(6)="35% Perk Bonus"
CustomLevelInfo="%s Perk Bonus"
PerkIndex=7
}
Code:
NumRequirements=2 Requirements(0)="Kill %x Stalkers with Bullpup/AK47/SCAR" Requirements(1)="Deal %x damage with Bullpup/AK47/SCAR Code:
#exec obj load file="WhiskyPerks_T.utx"
Spoiler!
Special thanks to Scary for pre-empting this one. His original post (link below) helped me to put this last one together. The final perk.
Spoiler!
EXTRAS You can also define what weapons you want the perk to be able to buy. Code:
static function bool AllowWeaponInTrader( class<KFWeaponPickup> Pickup, KFPlayerReplicationInfo KFPRI, byte Level )
{
if ( class<M79healPickup>(Pickup) != none || class<VirusMistPickup>(Pickup) != none
|| class<DoctorRiflePickup>(Pickup) != none || class<NovaSixPickup>(Pickup) != none )
return false;
else
return true;
}
Marco says: A better example, you could use that to make like a portal science perk and hide Portal Turret from trader if you don't have level 5 or hide portal gun before level 10 (also require that you have that perk selected): Code:
static function bool AllowWeaponInTrader( class<KFWeaponPickup> Pickup, KFPlayerReplicationInfo KFPRI, byte Level )
{
if( Pickup==Class'PTurretPickup' )
return (KFPRI.ClientVeteranSkill==Default.Class && Level>=5);
if( Pickup==Class'pgPortalGunPickup' )
return (KFPRI.ClientVeteranSkill==Default.Class && Level>=10);
return true;
}
If you want to replace a perks starting equipment here is the way to do it. Code:
static function AddDefaultInventory(KFPlayerReplicationInfo KFPRI, Pawn P)
{
local Inventory I;
// Delete standard guns
I = P.FindInventoryType(Class'Knife');
if( I!=None )
I.Destroy();
I = P.FindInventoryType(Class'Single');
if( I!=None )
I.Destroy();
KFHumanPawn(P).RequiredEquipment[0] = "";
KFHumanPawn(P).RequiredEquipment[1] = "";
// Then give perk specific weapons.
if ( KFPRI.ClientVeteranSkillLevel < 3 )
KFHumanPawn(P).CreateInventoryVeterancy(string(Class'MyTireIron'), GetCostScaling(KFPRI, class'MyTireIron'));
else KFHumanPawn(P).CreateInventoryVeterancy(string(Class'MyShovel'), GetCostScaling(KFPRI, class'MyShovel'));
}
__________________
Whisky's Workshop ![]() "As you can see here, I'm -ALL ON MY F***ING OWN! Guys where the hell are you?!" Last edited by Gartley; 06-26-2012 at 09:22 AM. |
|
#4
|
||||
|
||||
|
Oops, saw this after I wrote this up:
http://forums.tripwireinteractive.co...&postcount=690 Oh well, feel free to use it if you haven't already gotten around to custom perk requirements. |
|
#5
|
||||
|
||||
|
I think that's all of for now. If there are any other bits and pieces I'll try and answer what I can but remember the answers are all out there. You just need to look for them.
__________________
Whisky's Workshop ![]() "As you can see here, I'm -ALL ON MY F***ING OWN! Guys where the hell are you?!" |
|
#6
|
|||
|
|||
|
http://forums.tripwireinteractive.co...ad.php?t=48277
As you may be now aware of that custom perk My problem is i followed every instructions and everything loaded perfectly the only problems is that the perks won't show up this is probably a offtopic but its still related to adding custom perks anyways I would like to know why it doesn't show up not even in the veterancy handler.Thank you. |
|
#7
|
||||
|
||||
|
2 Qustions...
First, How do I insert another level conditions? (this part of rhe "GetPerkProgressInt" & progressArray" Snd, Is it possible to insert a condition existing perk? (E.g : movement, reload .. etc) Last edited by ASSAYARO; 05-13-2012 at 04:34 PM. |
|
#8
|
||||
|
||||
|
Hey ASSAYARO,
#1: I used an array just to keep things easy, you can do it the same way as in the orginal perks, commando or support are a good example ala:
Spoiler!
Or define a second array, either works. And two, fully possible, just extend the perk and add the function you wish to include. Commando with speed boost? Quote:
__________________
Whisky's Workshop ![]() "As you can see here, I'm -ALL ON MY F***ING OWN! Guys where the hell are you?!" Last edited by Gartley; 05-14-2012 at 05:13 AM. |
|
#9
|
||||
|
||||
|
You might also want to add in a part where you can hide weapons from the trader using something like this.
Quote:
|
|
#10
|
|||
|
|||
|
Do remember to add the bool requirement in the default to say how many requirements the perk should have:
Code:
NumRequirements=2 Code:
Requirements(0)="Kill %x Stalkers with Bullpup/AK47/SCAR"
Requirements(1)="Deal %x damage with Bullpup/AK47/SCAR"
|
|
#11
|
||||
|
||||
|
Posts amended, thanks guys.
__________________
Whisky's Workshop ![]() "As you can see here, I'm -ALL ON MY F***ING OWN! Guys where the hell are you?!" |
|
#12
|
|||
|
|||
|
Quote:
Code:
static function bool AllowWeaponInTrader( class<KFWeaponPickup> Pickup, KFPlayerReplicationInfo KFPRI, byte Level )
{
if( Pickup==Class'PTurretPickup' )
return (KFPRI.ClientVeteranSkill==Default.Class && Level>=5);
if( Pickup==Class'pgPortalGunPickup' )
return (KFPRI.ClientVeteranSkill==Default.Class && Level>=10);
return true;
}
|
|
#13
|
||||
|
||||
|
Quote:
|
|
#14
|
||||
|
||||
|
oops, I deleted the pictures, I'll sort that out now.
__________________
Whisky's Workshop ![]() "As you can see here, I'm -ALL ON MY F***ING OWN! Guys where the hell are you?!" |
|
#15
|
||||
|
||||
|
Quote:
But, see the following error messages. something wrong?? Quote:
Last edited by ASSAYARO; 05-22-2012 at 06:00 PM. |
|
#16
|
|||
|
|||
|
Quote:
Code:
static function int GetPerkProgressInt( ClientPerkRepLink StatOther, out int FinalInt, byte CurLevel, byte ReqNum ) |
|
#17
|
||||
|
||||
|
Quote:
I've made a mistake... h a i solved
|
|
#18
|
||||
|
||||
|
Quote:
|
|
#19
|
||||
|
||||
|
This code works fine for me, what were you trying to add/change?
__________________
Whisky's Workshop ![]() "As you can see here, I'm -ALL ON MY F***ING OWN! Guys where the hell are you?!" |
|
#20
|
|||
|
|||
|
If you want, give us what code you implemented and what you intend it to do and we'll see about helpping you.
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|