Components: 🔮Buffs

From Cosmoteer Wiki
< Modding‎ | Components(Redirected from Components: 🔮Buffs)
Modding/Components/Buffs
Jump to navigation Jump to search


This page assumes you have read through the official Example Mod. If you haven't, consider starting there.
See also : List of Buffs

What are Buffs?

In Cosmoteer, Buffs are effects that allow a part to affect another part or even itself (so called "self-buffs").
Anything that can be affected by a buff is said to be "buffable".
Conversely, if a value you want to modify is not described as "buffable", you will have to find another way.

How they work

All the buffs in the game can be found in buffs/buffs.rules file (see more about where to find it and other .rules files). You can add new buffs to the game in your mod.

Let's look at examples from the base game.

Example

Engine Rooms apply a buff to nearby thrusters, making them 50% stronger for 50% increased fuel usage. In the code, that buff is named Engine.

CalloutIconNote.png
Info
Note: Engine Room .rules file can be found at path: ships\terran\engine_room\engine_room.rules

Now, let's look at the buff defined in buffs.rules file:

Engine
{
	CombineMode = Max
	BaseValue = 100%

	Icon
	{
		Texture
		{
			File = "buff_engine.png"
			MipLevels = 2
			SampleMode = Linear
		}
		Size = [2, 2]
	}
	IconTextFormatKey = "BuildBox/BuffPercentageFmt"
	IconTextMultiply = 100
	IconTextAdd = -100

	RectBorderColor = [10, 212, 98, 160]
	RectFillColor = [10, 212, 98, 64]
}

To provide the buff, the engine_room.rules file has a BuffProvider component.
This is where the value BuffAmount that indicates the "strength" of the buff is set:

BuffProvider
{
	Type = GridBuffProvider
	BuffType = Engine
	BuffAmount = 50%
	GridDistance = 1
	OperationalToggle = IsOperational
}


Finally, to receive the buff and apply its effect(s) we must go into a thruster .rules file and modify some things. Since there are multiple thrusters, let's pick, for example, the large thruster — its .rules file is located at ships\terran\thruster_large\thruster_large.rules.

For the buff to take effect, the .rules must contain the following four(4) parts:
1. The buff type (BuffType) must be added to the ReceivableBuffs list of buffs (anything within [] is a list).

Note: ^/0/ReceivableBuffs adds any buffs defined in the part from which the current part (EngineRoom) was inherited from. The base part for EngineRoom is base_part_terran.rules, so any buffs defined there in ReceivableBuffs will be added. This even includes the buffs inherited in base_part_terran.rules from its base part, base_part.rules.
More on path syntax.

ReceivableBuffs : ^/0/ReceivableBuffs [Engine]


2. A toggle must be added that "detects the presence" of the added buff type:

EngineBuffToggle
{
	Type = BuffToggle
	BuffType = Engine
}


3. The block added in step 2 must be used as toggle for the battery consumption component ToggledBatteryConsumer:

ToggledBatteryConsumer
{
	Type = ToggledComponents
	Toggle = EngineBuffToggle
	Invert = true
	IncludeInBlueprints = true
	Components
	{
		BatteryConsumer
		{
			Type = ResourceConsumer
			ResourceType = battery
			Storage = BatteryStorage
			DefaultPriority = &/PRIORITIES/Thruster_Supply
			ResupplyThreshold = 500
			OperationalToggle = PowerToggle
		}
	}
}


4. Lastly, the effect is applied in the MainThruster component (see MaxActivation field):

MainThruster
{
	Type = Thruster
	Location = [1, 2.5]// Relative to upper-left corner of unrotated part.
	Rotation = 90d// Relative to unrotated part.
	OperationalToggle = IsOperational
	Force = &../../ThrusterForce
	MinActivation = 0
	MaxActivation = { BaseValue=1; BuffType=Engine; BuffMode=Multiply; }
	MinUncommandedActivation = &MinActivation
	MaxUncommandedActivation = &MaxActivation
	ActivationIncreaseTime = &../../ThrustIncreaseTime
	ActivationRecoveryTime = &../../ThrustRecoveryTime
	FuelStorage = BatteryStorage
	FuelUsagePerSecond = &../../FuelUsage
}

Breakdown

(WIP)

How to mod buffs

There are multiple possibilities for how your own buff can be implemented.

Modifying an existing buff

This is done with Actions of the following types: Replace, or Overrides. If you're not sure what this means, refer to the official Example Mod.

It is preferable to avoid doing this if you want your mod to be compatible with other mods that modify the same base game files. If two or more mods are trying to modify the same thing, that causes problems. Not to mention, the original functionality of the buffs may be lost, in case that's not what you are trying to achieve.

Making your own buff

To add a new buff to the game, in your mod.rules file you need Actions of the following types: Add, AddMany.

You can also use Overrides with CreateIfNotExisting = true.

Creation

In your mod.rules file, give a name to your buff in the Action adding it to the buffs.rules file, then add it to ReceivableBuffs like so:

{
		Action = Overrides
		OverrideIn = "<buffs/buffs.rules>/NameOfMyBuff"
		CreateIfNotExisting = true
		Overrides
		{
			CombineMode = Max
			BaseValue = 100%

			Icon
			{
				Texture
				{
					File = "icons/buff_nameofmybuff.png"
					MipLevels = 2
					SampleMode = Linear
				}
				Size = [2, 2]
			}

			RectBorderColor = [10, 212, 98, 160]
			RectFillColor = [10, 212, 98, 64]
		}
	}

	{
		Action = Add
		AddTo = "<ships/base_part.rules>/Part/ReceivableBuffs"
		Name = NameOfMyBuff
		ToAdd = NameOfMyBuff
	}


The name should be descriptive and unique (it could include your personal prefix for example, like mod.rules files in general) so that any buff added by another mod is unlikely to have the same name. That would cause problems.

Source

There must a source for the buff. Two possibilities :


Option 1 : Add it to an existing part

This will allow you to skip the part-making process entirely. However your buff provider may be affected by changes from other mods that affect the same part. To do this, add a BuffProvider component in the .rules file of an existing part, with an Action like this one :

{
	Action = Overrides
	OverrideIn = "<ships/terran/reactor_small/reactor_small.rules>/Part/Components"
	CreateIfNotExisting = true
	Overrides
	{
		BuffProvider
		{
			Type = GridBuffProvider
			BuffType = NameOfMyBuff
			BuffAmount = 25%
			GridDistance = 2
			Criteria
			{
				Category = uses_power
			}
		}
	}
}


Option 2 : Bake it into a new part that comes with your mod.

To do this, the BuffProvider component will simply be included in the .rules file of your new part, like so :

BuffProvider
		{
			Type = GridBuffProvider
			BuffType = NameOfMyBuff
			BuffAmount = 50%
			GridDistance = 1
			OperationalToggle = IsOperational
		}

There are a few parameters you can change here :

BuffAmount can be any amount you want for the "strength" of your buff. This amount can be applied in different ways as we will see later.

GridDistance is how far (in terms of tiles) your buff will apply. Engine Rooms for example have this set to 1, meaning only parts that share a wall with them will be affected. Some mods add a buff to reactors so they can remotely power things, using this setting at a higher value.

OperationalToggle decides whether or not your buff is being provided based on the state of the referenced toggle. In other words, if the toggle you put there is ("returns", technically) true, your buff is being provided. If it's false, the buff isn't being provided.
Typically the value used here in the base game is IsOperational, which is defined near the top of the part's components and checks for the part being turned On, and powered/crewed if applicable. You might want to change this to a custom toggle for example.


Examples

(WIP)

Affected parts

Finally, something needs to be affected by it, else the buff has no reason to be in the game, taking up memory.
Add this BuffToggle component to any part it should affect, or use an Add/Overrides action to insert it into an existing part.

NameOfMyBuffToggle
	{
		Type = BuffToggle
		BuffType = NameOfMyBuff
	}

You can then reference it in the rest of the part's code for effects. It can be done in multiple places.
"What places" depends entirely on what you want your buff to do.


((work in progress))