Effect Tutorial: Difference between revisions
| Line 231: | Line 231: | ||
5 // Cooldown (5 seconds) | 5 // Cooldown (5 seconds) | ||
] | ] | ||
=== TARG_* target constants === | |||
{| class="wikitable" | |||
|+ | |||
!Name | |||
!Value | |||
!Description | |||
|- | |||
|TARG_CASTER | |||
|0x1 | |||
|Target the player that applied the package. | |||
|- | |||
|TARG_VICTIM | |||
|0x2 | |||
|Victim of the package (the person who has the package that the event is attached to) | |||
|- | |||
|TARG_PC | |||
|0x4 | |||
|Not used in events | |||
|- | |||
|TARG_NPC | |||
|0x8 | |||
|Not used in events | |||
|- | |||
|TARG_DISPELLER | |||
|0x10 | |||
|Only used in dispel events. The player that dispelled the package that the event was attached to. | |||
|- | |||
|TARG_REQUIRE_NO_FACING | |||
|0x20 | |||
|Not used in events | |||
|- | |||
|TARG_AOE | |||
|0x40 | |||
|Run as an area effect. Max targets will not work with this. | |||
|} | |||
== Tags == | == Tags == | ||
Revision as of 17:24, 28 July 2023
Effects (FX) are the backbone of the game. They are the buffs that you see on your HUD and also used by direct damage and things behind the scenes like cutscenes.
Relevant scripts:
| Script | Description |
|---|---|
| _lib_fx.lsl | Stores all the effect types and explains the effect types. Also stores a list of default values for passive effects (not to be confused with the passives system which is different). Also conditions and tags. |
| classes/got FX.lsl | Has the methods, macros, and building tools for making effects. |
| classes/got FXCompiler.lsl | Compiles effects into cached values and triggers LSL and RLV functions when effects are added or removed. |
The structure of an effect
The effect data is a JSON array with the following spect:
- (array) wrapper. An all or nothing container of multiple effect packages and stacks of packages.
- (int) wrapper_flags - WF_* flags. See below.
- (int) min_packages - Minimum packages to apply (all or nothing).
- (int) max_packages - Max packages to apply (applies the N first viable packages). Use 0 for ALL.
- (...strided) (int) package_stacks, (array) package - After max_packages the remaining elements are two-strided with nr stacks and the package to add said stacks of. Anything below 1 becomes 1.
- (float) Package duration - Duration to apply the package
- (int) Package flags - PF_* flags. See below.
- (str) Package name - Name of the package (unique). If the effect has a 0 duration you can use "" or 0 because it is only used in duration effects.
- (array) Effects - An array of FX arrays
- (int) Effect type - An effect integer from _lib_fx.lsl
- ...effect data - ...followed by data based on that effect.
- (array) Conditions - An array of condition arrays
- (int) Type of condition - Condition identifier from _lib_fx.lsl
- ...condition data - Data based on the condition identifier.
- (array) Events - An array of effect arrays.
- (int) event_type - An event type. You can use any relevant event from any of the header files in got/classes.lsl
- (str) event_script - The name of the script that raised the event. If the event was raised by got FX.lsl then use "" instead.
- (int) targ_flags - A TARG_* flag. See below.
- (int) max_targets - Max nr of targets to apply to. Not very useful. Leave at 0 for all viable.
- (array) wrapper (nested wrapper) - The wrapper to apply when the effect is raised. This is a nested wrapper.
- (array) event_params - An array of values that must match the event values. See below.
- (float) proc_chance - Adds a random chance that the event is raised. Between 0 (no chance) and 1 (100%).
- (int) event_flags - Event flags. See below.
- (float) max_range - Max range of event target from the victim of the package. In whole meters.
- (float) cooldown - Cooldown between procing the event.
- (array) tags - An array of fx$TAG_* constants from _lib_fx.lsl
- (int) min_conditions - Minimum conditions that must be met for the package to apply.
- (int) max_stacks - Max stacks that this package can have.
- (float) tick - When set to anything above 0 it will trigger all the effects this often. In whole seconds.
Here is a JSON encoded version of the above:
[ (int)wrapper_flags, (int)min_packages, (int)max_packages, (int)stacks_package0, [ (float)package_duration, (int)package_flags, (str)package_name, [ [ (int)effect_type, (var)effect_data0, ... ] ... ], [ [ (int)condition_type, (var)condition_data0, ... ] ... ], [ [ (int)event_type, (str)event_script, (int)targ_flags, (int)max_targets, (arr)wrapper, (arr)event_params, (float)proc_chance, (int)event_flags, (float)max_range, (float)cooldown ], ... ], [ (int)tag0, ... ], (int)min_conditions, (int)max_stacks, (float)tick ], (int)stacks_package1, (arr)package1 ... ]
Wrapper flags
| Flag | Value | Description |
|---|---|---|
| WF_DETRIMENTAL | 0x1 | Causes NPCs to become hostile when cast on and players to enter combat when cast on. By default blocked on defeat/grapple/invul. |
| WF_ALLOW_WHEN_DEAD | 0x2 | Allows this wrapper to be used when target is defeated. |
| WF_ALLOW_WHEN_QUICKRAPE | 0x4 | Allows this wrapper to be used when target is grappled. |
| WF_NO_DODGE | 0x8 | Cannot be dodged (only detrimental can be dodged). |
| WF_ALLOW_WHEN_RAPED | 0x10 | Allow while player is in a monster scene. |
| WF_REQUIRE_LOS | 0x20 | Requires sender to have line of sight to target. Useful for AoE. |
| WF_ENEMY_ONLY | 0x40 | Wrapper is ignored unless target has a different team than sender. By default player team is 1 and NPC team is 0. Any team that is not the same as yours is considered hostile. |
Package
A package is a collection of effects, conditions and events. Packages can be instant or happen over time. A package that happens over time typically has an icon that shows on your HUD below the resource bars.
A wrapper can apply multiple packages, and a package can contain multiple effects.
Package flags:
| Flag | Value | Description |
|---|---|---|
| PF_DETRIMENTAL | 0x1 | Sets package as detrimental. Receiving a detrimental package activates the combat timer. Sending a detrimental package to an NPC will make it attack you. Invulnerability block receiving detrimental packages. |
| PF_CANNIBALIZE | 0x2 | If a package with the same name already exists, replace it with this one and add its stacks. Default behavior is to keep the original wrapper and add the incoming package's stacks because it is faster. |
| PF_EVENT_ON_OVERWRITE | 0x4 | Raises the INTEVENT_ON_REMOVE event when PF_CANNIBALIZE is set and a spell is overwritten. |
| PF_ALLOW_WHEN_DEAD | 0x8 | By default a player is not allowed to receive ANY packages when defeated. This flag overrides that. Useful for resurrect. |
| PF_ALLOW_WHEN_QUICKRAPE | 0x10 | By default when caught on a trap or grapple, NPCs cannot apply packages to you. This overrides that. |
| PF_NO_STACK_MULTIPLY | 0x20 | Many effect values are multiplied by nr of stacks of a package a player has. This prevents that multiplication. |
| PF_FULL_UNIQUE | 0x40 | By default, packages are unique by name and by sender. This makes them only unique by name. When set you may only have one package active with this name no matter how many senders. |
| PF_TRIGGER_IMMEDIATE | 0x80 | By default the non-passive effects (like damage) are only triggered when a package with a duration "ticks". Setting this will make it tick instantly when the package is added also. This flag is used a lot. |
| PF_NO_DISPEL | 0x100 | Prevents the package from being dispelled. |
| PF_STACK_TIME | 0x200 | When a package with the same name is received, it adds that package's duration instead of its stacks. Tank mitigation abilities usually use this. |
| PF_FULL_VIS | 0x400 | By default you may only see your own spells on the target bar. This forces the spell icon to show up no matter who cast it. |
Effects
Effects tell the HUD what do to. Such as add HP or play an animation. Each effect is an array where the first value is the effect ID (see _lib_fx.lsl for a list of all effects and what they do) and is followed by any data values relevant to the effect ID.
Examples:
[1,10] // Deal 10 damage
[7,"sit",1] // Start the sitting animation
Conditions
Conditions use a similar syntax to effects. The first value is a condition ID (outlined in _lib_fx.lsl). It may be followed by additional values based on the condition type.
Example:
[0,1] // Only apply the package if the target is not on the player team
[12,4] // Only apply the package if the target has breasts
Events
The event system is advanced. It allows you to apply wrappers when something happens based on XOBJ events that are raised. We can explain it by using an example of an event array. This event will deal 3 damage to your target when you finish casing spell 4 but only if spell 4 is detrimental. Note: In LSL you need to escape the nested JSON array with llList2Json.
[ SpellManEvt$complete, // Event that we are listening for "got SpellMan", // Script that raised that event "<1>", // Target to apply the wrapper to. <1> = event value at index 1 (target of spell) 0, // Max target (0 = ALL) [0,0,0,0,[0,1,0,1,10]], // Wrapper that deals 10 damage directly [ 4, // First value of event (spell index) must be 4 (spell 4). Note that spell 5 is index 0. "", // Ignore the second event value by using "" 1 // Third value of event (deterimental) must be 1. ], 1.0, // Proc chance. 1 = 100% 0, // No flags 0, // Range (0 = unlimited) 5 // Cooldown (5 seconds) ]
TARG_* target constants
| Name | Value | Description |
|---|---|---|
| TARG_CASTER | 0x1 | Target the player that applied the package. |
| TARG_VICTIM | 0x2 | Victim of the package (the person who has the package that the event is attached to) |
| TARG_PC | 0x4 | Not used in events |
| TARG_NPC | 0x8 | Not used in events |
| TARG_DISPELLER | 0x10 | Only used in dispel events. The player that dispelled the package that the event was attached to. |
| TARG_REQUIRE_NO_FACING | 0x20 | Not used in events |
| TARG_AOE | 0x40 | Run as an area effect. Max targets will not work with this. |
Tags
Tags are an array of tag constants (see _lib_fx.lsl). They only contain metadata. The only important one is the fx$TAG_ACTIVE_MITIGATION for tanks.
Examples
It is recommended that you use the FX_build* functions to create your wrappers while you are new to this. Here are some examples:
Wrapper that deals 10 damage to the recipient and triggers the take hit animation and sound:
string wrapper = FX_buildWrapper(
WF_DETRIMENTAL, // Flags
0, // Min packages (ANY)
0, // Max package (ALL)
[
0, // Stacks. Anything below 1 will become 1
FX_buildPackage(
0, // No duration. Fire and forget.
PF_DETRIMENTAL, // Flags
"", // Name of package. Not usually needed when package is instant.
[ // FX arrays
FX_buildFX(fx$DAMAGE_DURABILITY, [10]), // Do 10 HP damage
FX_buildFX(fx$HITFX, [ // Trigger the take hit animation and sound
fxhfColor$phys, // Color the thong briefly to indicate damage
fxhfFlag$PAIN_HEAVY // Flags for RP addons
])
],
[], // Conditions: None used
[], // Events: None used
[], // Tags: none used
0, // Minimum conditions needed
0, // Max stacks: Not used
0 // Ticking: Not used
)
]
);
// Method to send a wrapper to a player or NPC
FX$send(
llGetOwner(), // Target of wrapper
llGetKey(), // Sender of wrapper
wrapper, // Wrapper
TEAM_NPC // Team of sender
);
Add a duration effect for 10 seconds that increases haste by 10% per stack.
string wrapper = FX_buildWrapper(
0, // Flags
0, // Min packages (ANY)
0, // Max package (ALL)
[
0, // Stacks. Anything below 1 will become 1
FX_buildPackage(
10, // Last 10 seconds.
0, // Flags
"testBuff", // Name of package. Unique by sender and name.
[ // FX arrays
FX_buildFX(fx$CASTTIME_MULTI, [-0.1]), // Multiply cast time by 0.9 (1-0.1)
FX_buildFX(fx$COOLDOWN_MULTI, [-0.1]), // Multiply cooldown time by 0.9 (1-0.1)
FX_buildFX(fx$ICON, [ // Add an icon to the HUD
"5dc76285-eabe-9f08-fb7e-70f40ea1db2e", // Icon UUID
"Haste increased by 25%" // Click description
])
],
[], // Conditions: None used
[], // Events: None used
[], // Tags: none used
0, // Minimum conditions needed
3, // Max stacks 3
0 // Ticking: Not used
)
]
);
// Method to send a wrapper to a player or NPC
FX$send(
llGetOwner(), // Target of wrapper
llGetKey(), // Sender of wrapper
wrapper, // Wrapper
TEAM_NPC // Team of sender
);