• 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 RPG Code Queries

FluX

Grizzled Veteran
Oct 26, 2010
5,378
234
www.fluxiserver.co.uk
Ok so I would like to do my own style of RPG from almost scratch. Thought i'll ask some questions to help me in the morning to figure some stuff out.

I'll need a level for the player and one for each weapon. I can make custom stats but what is the best way to set what the levels are? I would prefer to not use a perk at all as I want to remove perks overall. I can figure out some of the bonuses by checking where they are effected and do a level check etc and then give a return value like damage bonus of a weapon from the weapon level in the GameRules.

My main worry is getting the code to figure out how to code what the levels are as in, if they got this experience, the level is this. Also, where is best for this to go? Sorry, it's 3:30am and I can't think straight right now lol. This will be a good learning curve to see something different and maybe port over for KF2 later. Overall, I will be using a custom ServerPerks but with a lot of it stripped out. Reason being, I can then adapt it to what I need and change into the mod idea I currently have.
 
If you plan to have regular EXP steps, just code your stat in as a round number then do integer division or modulo or idk.

If you plan to have irregular EXP steps (exponential and whatnot), if-else works fine unless you have a mathematical function

All-in-all, one custom stat for each EXP (because level is determined via code). Or if you're feeling adventurous, make a long string with something like delimited values, then custom parsing
 
Upvote 0
You can use the custom stats functionality built into SVP to achieve your aim. Like in your scenario you have multiple exp values for multiple guns, so you can have a stat class for each type of weapon.

Basically, ClientPerkRepLink is attached to every PC's PRI's LinkedRepInfo List. In CPRL, there are 2 functions that you can use to get the value of whichever, which goes like this (example):

Code:
//If your value is stored as an int:
MyRank = C.GetCustomValueInt(class'MyMut.MyRankStat');

//If your value is stored as a string:
MyText = C.GetCustomValue(class'MyMut.MyTextStat');

What the above 2 functions does is to basically call GetProgress() (for string) and GetProgressInt (for ints), in whichever stat class you specify. Each stat class should extend from SRCustomProgress (base).

Do note that before you do any of these, you have to add your custom stat class into CPRL for replication, via CPRL.AddCustomValue(your stat class). This can be done by checking first for SRStatsBase through CheckReplacement, and if it exists, add your classes there through SRStatsBase(Other).Rep <-- Rep is a CPRL object,

An example of one of my Stat classes:
Code:
class BRStat_Rank extends SRCustomProgress;
var int RankLevel;
var int MaxRank;
var int MinRank;

replication
{
	reliable if( Role==ROLE_Authority && bNetOwner )
		RankLevel;
}

simulated function string GetProgress()
{
	switch(RankLevel)
	{
		case 1:
			return "Regular+";
		case 2:
			return "VIP";
		case 3:
			return "Moderator";
		case 4:
			return "Administrator";
		default:
			return "Regular";
	}
}

simulated function int GetProgressInt()
{
	return RankLevel;
}

simulated function string GetDisplayString()
{
	return ProgressName;
}

function SetProgress( string S )
{
	//RankLevel = int(s);
	switch(s)
	{
		case "Regular+":
			RankLevel = 1;
			break;
		case "VIP":
			RankLevel = 2;
			break;
		case "Moderator":
			RankLevel = 3;
			break;
		case "Administrator":
			RankLevel = 4;
			break;
		default:
			RankLevel = 0;
			break;
	}
	log("SET RANK!" @ RankLevel);
}

function Promote()
{
	if(RankLevel < MaxRank) RankLevel++;
	ValueUpdated();
}

function Demote()
{
	if(RankLevel > MinRank) RankLevel--;
	ValueUpdated();
}

defaultproperties
{
	bAlwaysRelevant=true
	bNetNotify=true
	ProgressName="BRTSRank"
	MaxRank=4
	MinRank=0
}
 
Upvote 0
I suggest using the same functions from KFVeterancyTypes (or SRVeterancyTypes), but loading bonuses from KFPlayerReplicationInfo.

Code:
class RPGPlayerReplicationInfo extends KFPlayerReplicationInfo;

var float MeleeMovementSpeedModifier;
var float DamageModifier;
// and others

replication
{
    // Things the server should send to the client.
    reliable if ( bNetDirty && (Role == Role_Authority) )
        MeleeMovementSpeedModifier, DamageModifier;
}

Code:
class RPGPlayerReplicationInfo extends KFPlayerReplicationInfo;

var float MeleeMovementSpeedModifier;
var float DamageModifier;
// and others

replication
{
    // Things the server should send to the client.
    reliable if ( bNetDirty && (Role == Role_Authority) )
        MeleeMovementSpeedModifier, DamageModifier;
}    
    

    
class RPGVeterancyTypes extends KFVeterancyTypes;

static function float GetMovementSpeedModifier(KFPlayerReplicationInfo KFPRI, KFGameReplicationInfo KFGRI)
{
    return RPGPlayerReplicationInfo(KFPRI).MeleeMovementSpeedModifier;
}

static function int AddDamage(KFPlayerReplicationInfo KFPRI, KFMonster Injured, KFPawn Instigator, int InDamage, class<DamageType> DmgType)
{
    return InDamage *  RPGPlayerReplicationInfo(KFPRI).DamageModifier;
}

Code:
class RPGHumanPawn extends KFHumanPawn;

function ServerChangedWeapon(Weapon OldWeapon, Weapon NewWeapon)
{
    super.ServerChangedWeapon(OldWeapon,NewWeapon);
    
    //todo: load weapon stats from somewhere
    //RPGPlayerReplicationInfo(PlayerReplicationInfo).MeleeMovementSpeedModifier = ...
    //RPGPlayerReplicationInfo(PlayerReplicationInfo).DamageModifier = ...
}
 
Upvote 0