-
Notifications
You must be signed in to change notification settings - Fork 4
Creating New Effects [WIP]
Starter template:
#pragma semicolon 1
/*
Effect by <your name here>
*/
public void Chaos_EffectName(EffectData effect){
}
public void Chaos_EffectName_OnMapStart(){
}
public void Chaos_EffectName_START(){
}
public void Chaos_EffectName_RESET(){
}
The minimum requirement to have your effect run is the Chaos_EffectName
function and a minimum of at least ONE forward, eg _START(), _RESET(), _OnPlayerRunCmd(), etc.
public void Chaos_EffectName(EffectData effect){
effect.Title = "Effect Name";
effect.Duration = 30;
//...
HookEvent("weapon_fire", Chaos_EffectName_Event_WeaponFire);
}
Configurable options in the effect
object. If the option is not used, assume the default is used. These functions are called during OnPluginStart, meaning you can also hook events here, as it is only run once.
[String] [Required]
effect.Title = "Effect Name";
Forces a default name for the effect. This name will also match the entry added into the chaos.phrases.txt
translation file that would overwrite the plugin's setting.
[Int] [Default: 30]
effect.Duration = 30;
Default duration of the effect. The standard is 30 seconds, but should be reduced if the effect is overpowered. Eg. the Blind All Players
effect is set to 7 seconds. The Spawn Chickens
effects are 45 seconds long. If the effect does not have a reset/expiry, you can skip this line, but must set HasNoDuration
to true
.
[Bool] [Default: false]
effect.HasNoDuration = true;
Indicates that the effect has no duration, and will not show a timer bar in the HUD. Will also ignore and _RESET() functions.
[Bool] [Default: false]
effect.OverrideDuration = true;
Prevents server owners from adjusting the effect's duration, and locks in effect.Duration
.
[Bool] [Default: false]
effect.HasCustomAnnouncement = true;
Setting this to true will prevent the plugin from automatically "Announcing" the effect once it is triggered. This ideally should only be used in effects that have no duration. You can then use the following to call it in your _START() function:
AnnounceChaos(GetChaosTitle("Chaos_EffectName"), -1.0);
[Bool] [Default: false]
effect.IsMetaEffect = false;
Used to flag the effect as a "Meta" effect, which holds a rare chance of spawning, and is displayed as a yellow effect in the HUD.
effect.AddAlias("Knife");
This will allow your effect to show up on the !effect menu. By default, Chaos_EffectName
and your effect's title, or any sub-string of either, will show up in the menu if used with !effect. In the example above, using !effect knife
in chat will list your effect in the menu. You can add as many aliases as you'd like to help assist server owners find your effect.
effect.IncompatibleWith("Chaos_DifferentEffectName");
This will prevent your effect from being triggered while the other effect is active. This will also prevent that effect from being triggered while yours is already active.
effect.AddFlag("playermodel");
There are multiple different groups of effects that would be incompatible with each other, for example any effects that change the player's model. Instead of using .IncompatibleWith()
multiple times for every effect, in all effects that change player models, a custom "flag" cam be used that will prevent any other effects from running, if they hold the same flag.
Currently all effects that change the player's model hold the "playermodel" flag. This means no effects will overlap in changing the player model, and that the active effect will reset to original player models before a different one of the same flag is allowed to be triggered.
This function is called when your effect is triggered. Here you can run everything you need to start your effect. In some cases you may need to define a bool EffectName = false
to keep track if your effect is active in other other functions such as OnGameFrame, OnPlayerRunCmd, etc. Set it to true in your START function.
public void Chaos_EffectName_START(){
EffectName = true;
}
This function is called when your effect's duration has expired, but will also be called during round ends, round starts, map loads, and plugin restarts. The ResetType
parameter is a bitflag that usually will hold two of the following flags when it's reset:
#define RESET_COMMAND (1 << 0) /** Chaos was disabled via command or menu - resetting effects */
#define RESET_EXPIRED (1 << 1) /** Effect timer has expired */
#define RESET_ROUNDSTART (1 << 2) /** Round start */
#define RESET_ROUNDEND (1 << 3) /** Round End */
#define RESET_PLUGINEND (1 << 4) /** Plugin was unloaded */
To check if a flag is found in ResetType, you can use:
public void Chaos_EffectName_RESET(int ResetType){
if(ResetType & RESET_EXPIRED){
}
}
These are used as in some cases, the round may end while your effect is active, and you may choose to handle the reset function a little bit differently as it might have in the middle of the round. For example, in the effect Chaos_QuickMath
, if you do not solve the math question by the end of the 10 seconds, you get slapped for 50hp. However, as the same reset function might be called much earlier due to a round end, it ensures that the effect was not ending in the round.
In your RESET function, you can set your EffectName
boolean back to false. In most cases you should be able to reset everything without checking what sort of reset it is. But there are cases where you will need to consider if you have to check for the reset type.
For example, at the end of the Knife Fight effect, it forces all players to switch back to their primary weapon to assist them in knowing that the effect is over, however you don't want to run this in the RESET function without checking that the effect has expired.
If this functions is defined, it will be used as the last and final check before running the effect. Returning true
will run the effect, and returning false
will skip to find a new effect. For example, if your effect relies on a C4, you might want to check that the game mode actually uses a C4. A helper function is available to check this and can be used like this:
You can also use the Conditions function to determine if you want your effect to run earlier or later in the round. For example, the Teleport all players back to spawn
effect contains a condition that prevents it from running too early in the round.
public bool Chaos_EffectName_Conditions(bool EffectRunRandomly)
{
/* Will always block the effect from running if it returns false */
if(IsHostageMap() || !GameModeUsesC4()) return false;
/* Will only block the effect from running if it's been called randomly, but will not be blocked if run through the menu manually */
if(GetRoundTime() <= 15 && EffectRunRandomly) return false;
return true;
}
The Conditions function is also called when selecting an effect through the !chaos menu. If the conditions function returns false, the effect is greyed-out in the menu and you won't able to run it. This means you might not want to enforce the round time condition when running the effect manually from a menu. The EffectRunRandomly
parameter is only true when the effect is generated randomly (automatically through the 15 second interval timer). So you should wrap "loose" checks with the EffectRunRandomly boolean, and leave stricter checks such as ensuring that a model is pre-cached.
These forwards will only be triggered if the effect is active. Use effect.RunForwardWhileInactive("OnGameFrame")
to force it to run while the effect is not active.
public void Chaos_EffectName_OnMapStart()
Same as the OnMapStart
forward, this function is called at the same time and should be used to precache models and materials, and adding files to the downloads table.
public void Chaos_EffectName_OnPlayerSpawn(int client)
This function is called 0.2 seconds after a player spawns WHILE your effect is active. If you need to hook player spawns while your effect is not active, you can hook the "player_spawn" event in your INIT function.
public void Chaos_EffectName_OnPlayerRunCmd(int client, int &buttons, int &iImpulse, float fVel[3], float fAngles[3], int &iWeapon, int &iSubType, int &iCmdNum, int &iTickCount, int &iSeed, int mouse[2])
This forward will only run while the effect is active.
public void Chaos_EffectName_OnGameFrame()
This forward will only run while the effect is active.
public void Chaos_EffectName_OnEntityCreated(int ent, const char[] classname)
This forward will only run while the effect is active.
public void Chaos_EffectName_OnEntityDestroyed(int ent)
This forward will only run while the effect is active.
Add the following to addons/sourcemod/translations/chaos.phrases.txt
.
"Chaos_EffectName"
{
"en" "Effect Name"
}
If translations are missing on the server, the effect.Title
will be used by the plugin
Include your EffectName.sp
inside of addons/sourcemod/scripting/Effects/EffectsList.sp
#include "Effects/Player/EffectName.sp"
Ensure that the contents of EffectsList.sp
is sorted alphabetically in descending order.
Add the name of your function to addons/sourcemod/scripting/Effects/EffectNames.sp
. This is used to call your function and add your effect.
"Chaos_EffectName",
This should match the name of your function that sets up your effect:
public void Chaos_EffectName(EffectData effect)