Jump to content

[Tutorial] Create a mutator to add special abilties/passives to infantry


NodSaibot

Recommended Posts

  • Totem Arts Staff

In this tutorial I will explain a bit how to use Rx_PassiveAbility, and utilize it fully to create a mutator that is compatible with other mutators (don't need to overwrite any classes). This mutator will give Sydney a healing passive ability.

 

Rx_PassiveAbility is a class that is spawned when a character is spawned(bought or spawned from crate). This all starts in the SetCharacterClassFromInfo function of Rx_Pawn. From there, we can see in that function that GivePassiveAbility is where abilities are given, so that will be our entry point in the mutator.

 

(Rx_PassiveAbility_ArmourHeal)

First, let's create the passive ability that we will apply to Sydney. We define a couple variables that we will be using so that we don't have plain numbers lying around in the code, and we can tweak the code easily using DefaultProperties. The Init function is called when a passive ability is attached to a Pawn, so let's use that as the time to start the timer for the healing. We also need to create a heal function, so we will create that function with all the needed checks and functionality. Since we don't want this to be too overpowered, let's add a penalty for taking damage, which is easily doable using the NotifyTookDamage function provided in Rx_PassiveAbility.

 

(Rx_Mutator_HealingSydney)

Using CheckReplacement we can see when an Rx_InventoryManager_GDI_Sydney is spawned, this means a player just bought a Sydney or got one from a crate. Whenever we verify this information, we can go ahead and call GivePassiveAbility on the player's pawn. Since Other is the InventoryManager, and the InventoryManager is spawned by the Pawn, we can check the Owner of the Other and get the Pawn from there.

The code is decently commented, so it should be self explanatory, however, if you have any questions, feel free to ask.

Finished files

Spoiler

class Rx_PassiveAbility_ArmourHeal extends Rx_PassiveAbility;

var float ArmourHealAmount, TimerInterval, TakeDamagePenalty;
var array<float> VeterancyBonus;

// Ability was added to a pawn
simulated function Init(Pawn InitiatingPawn, byte SlotNum)
{
	super.Init(InitiatingPawn, SlotNum);

	// When ability is started, start the timer to heal
	SetTimer(TimerInterval, true, nameof(HealArmour));
}

// Heal
function HealArmour()
{
	local Rx_Pawn P;
	local float TotalHealAmount;

	P = Rx_Pawn(UsingPawn);

	TotalHealAmount = ArmourHealAmount + VeterancyBonus[P.GetVRank()];

	if (P != None)
	{
		// Don't give the pawn more armour than it can have
		if (P.Armor + TotalHealAmount >= P.ArmorMax)
			P.Armor = P.ArmorMax;
		// Not all full armour, so give some
		else
			P.Armor += TotalHealAmount;
	}

	// In NotifyTakeDamage we use false in the loop parameter, this will make sure we start regening again at normal rate after the penalty
	if (!IsTimerActive(nameof(HealArmour)))
		SetTimer(TimerInterval, true, nameof(HealArmour));
}

// Hook for taking damage
simulated function NotifyTookDamage()
{
	// If you take damage, add some time until you start regening again
	SetTimer(TimerInterval + TakeDamagePenalty, false, nameof(HealArmour));
}

DefaultProperties
{
	ArmourHealAmount = 1.f  // Base heal amount
	TimerInterval = 1.f          // How often to heal, in seconds
	TakeDamagePenalty = 3.f     // Amount to add to timer when taken damage, in seconds

	VeterancyBonus(0) = 0.f 	// Recruit
	VeterancyBonus(1) = 1.f 	// Veteran
	VeterancyBonus(2) = 2.f 	// Elite
	VeterancyBonus(3) = 5.f 	// Heroic
}

class Rx_Mutator_HealingSydney extends Rx_Mutator;

var class<Rx_PassiveAbility> HealingAbilityClass;

// Called when an actor spawns
function bool CheckReplacement(Actor Other)
{
	local Rx_Pawn P;
	local int i;

	// Inventory Manager spawns when a pawn is set to the FamilyInfo corresponding to this Inventory Manager

	// Check if the actor is being kept, then make sure the character is a Sydney
	if (GetNextRxMutator().CheckReplacement(Other) && Rx_InventoryManager_GDI_Sydney(Other) != None)
	{
		// Get the actual pawn from the Inventory Manager
		P = Rx_Pawn(Other.Owner);

		// Make sure we don't replace any existing passive abilities. Use the first available slot
		if (P != None)
			for (i = 0; i < ArrayCount(P.PassiveAbilities); i++)
				if (P.PassiveAbilities[i] == None)
				{
					P.GivePassiveAbility(i, HealingAbilityClass);
					break;
				}

		return true;
	}

	return true;
}

DefaultProperties
{
	HealingAbilityClass = class'Rx_PassiveAbility_ArmourHeal'
}

 

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...