1. Welcome to skUnity!

    Welcome to skUnity! This is a forum where members of the Skript community can communicate and interact. Skript Resource Creators can post their Resources for all to see and use.

    If you haven't done so already, feel free to join our official Discord server to expand your level of interaction with the comminuty!

    Now, what are you waiting for? Join the community now!

Dismiss Notice
This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Creating an Effect

Feb 19, 2020
Creating an Effect
  • Creating an Effect

    Lets get into it shall we. Effects are basically methods that are void. It's like taking the setting part from the expression of the last expression tutorial. In my opinion they're the easiest syntax to make in the Skript API.

    Some things that should be effect are like titles, actonbars, spawning entities and other objects that cant be returned.

    Some things can be made into effects but should be made into expressions with changeable options, some would include setting player name, setting player location or setting player's sneak state. Why are using these as effects not recommended? The answer is because they should be expressions rather than effects, because they can have returnable states which may be useful.

    So lets get into making the effect. In this tutorial of creating an effect, I will be making a kick effect.

    Lets copy Skript's already existing syntax and make it.
    Code (Skript):
    1. kick %players% [(by reason of|because [of]|on account of|due to) %-string%]

    First we need to extend the Effect class.
    Code (Java):
    1. package me.limeglass.addon.elements.effects;
    2.  
    3. import org.bukkit.event.Event;
    4. import org.eclipse.jdt.annotation.Nullable;
    5.  
    6. import ch.njol.Skript.lang.Effect;
    7. import ch.njol.Skript.lang.Expression;
    8. import ch.njol.Skript.lang.SkriptParser.ParseResult;
    9. import ch.njol.util.Kleenean;
    10.  
    11. public class EffKickPlayer extends Effect {
    12.  
    13.     @Override
    14.     public boolean init(Expression<?>[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parser) {
    15.         //Explaining this still below in the tutorial
    16.         return false;
    17.     }
    18.  
    19.     @Override
    20.     public String toString(@Nullable Event event, boolean debug) {
    21.         //Explaining this still below in the tutorial
    22.         return null;
    23.     }
    24.  
    25.     @Override
    26.     protected void execute(Event event) {
    27.         //Explaining this still below in the tutorial
    28.  
    29.     }
    30. }
    So this is a basic Effect class. Lets get into explaining what the methods do:

    Code (Java):
    1. @Override
    2. public boolean init(Expression<?>[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parser) {
    3.     //Explaining this still below in the tutorial
    4.     return false;
    5. }
    This is a main method that almost all syntax classes uses, it basically gets all the expressions and data used in the users syntax.

    This abstract method calls the expressions of the syntax, the matched patterns if there are any (These are explained in Tip ands Tricks area), if the syntax is delayed and the parser of the whole syntax

    So because of our syntax we know that will can have two Variables one being optional because it can be null. When an expression is in the optional parameters [these] it's best to keep the optional expression of it null. We can add - to it to make it null by default, like %-string%

    So now we know that one of our expressions could be null.

    For this method it needs to return true or false. true meaning it did succeed and false if it didn't.

    So now our class should look similar to this:
    Code (Java):
    1. package me.limeglass.addon.elements.effects;
    2.  
    3. import org.bukkit.entity.Player;
    4. import org.bukkit.event.Event;
    5. import org.eclipse.jdt.annotation.Nullable;
    6.  
    7. import ch.njol.Skript.Skript;
    8. import ch.njol.Skript.lang.Effect;
    9. import ch.njol.Skript.lang.Expression;
    10. import ch.njol.Skript.lang.SkriptParser.ParseResult;
    11. import ch.njol.util.Kleenean;
    12.  
    13. public class EffKickPlayer extends Effect {
    14.  
    15.     static {
    16.         Skript.registerEffect(EffKickPlayer.class, "kick %players% [(by reason of|because [of]|on account of|due to) %-string%]");
    17.     }
    18.  
    19.     private Expression<Player> player;
    20.     private Expression<String> reason;
    21.  
    22.     @SuppressWarnings("unchecked")
    23.     @Override
    24.     public boolean init(Expression<?>[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parser) {
    25.         this.player = (Expression<Player>) expressions[0];
    26.         this.reason = (Expression<String>) expressions[1];
    27.         return true;
    28.     }
    29.  
    30.     @Override
    31.     public String toString(@Nullable Event event, boolean debug) {
    32.         //Explaining this still below in the tutorial
    33.         return null;
    34.     }
    35.  
    36.     @Override
    37.     protected void execute(Event event) {
    38.         //Explaining this still below in the tutorial
    39.     }
    40. }
    Now for example, let's say we want to make this effect only work in a sneak event. This is what we would have to add to the init method, in order to execute that.

    Code (Java):
    1.     @SuppressWarnings("unchecked")
    2.     @Override
    3.     public boolean init(Expression<?>[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parser) {
    4.         if (!ScriptLoader.isCurrentEvent(PlayerToggleSneakEvent.class)) {
    5.             Skript.error("You can only use the kick effect in the Sneak toggle event.", ErrorQuality.SEMANTIC_ERROR);
    6.             return false;
    7.         }
    8.         this.player = (Expression<Player>) expressions[0];
    9.         this.reason = (Expression<String>) expressions[1];
    10.         return true;
    11.     }
    The toString is basically a way to make your effect become a string, it's not used to get the effect back into it's state so what you can return in it is some useful information like the expressions etc. These will appear in any errors that may come from your addon and it makes other developers or yourself understand what is going on. So I will just add a generic toString and move on.

    The next is the execute method. This is where we can put the actual thing we want to do. So in our case we want to get the player and string if it's not null and then kick the player.

    And our final product should look like this
    Code (Java):
    1. package me.limeglass.addon.elements.effects;
    2.  
    3. import org.bukkit.entity.Player;
    4. import org.bukkit.event.Event;
    5. import org.eclipse.jdt.annotation.Nullable;
    6.  
    7. import ch.njol.Skript.Skript;
    8. import ch.njol.Skript.lang.Effect;
    9. import ch.njol.Skript.lang.Expression;
    10. import ch.njol.Skript.lang.SkriptParser.ParseResult;
    11. import ch.njol.util.Kleenean;
    12.  
    13. public class EffKickPlayer extends Effect {
    14.  
    15.     static {
    16.         Skript.registerEffect(EffKickPlayer.class, "kick %players% [(by reason of|because [of]|on account of|due to) %-string%]");
    17.     }
    18.  
    19.     private Expression<Player> player;
    20.     private Expression<String> reason;
    21.  
    22.     @SuppressWarnings("unchecked")
    23.     @Override
    24.     public boolean init(Expression<?>[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parser) {
    25.         this.player = (Expression<Player>) expressions[0];
    26.         this.reason = (Expression<String>) expressions[1];
    27.         return true;
    28.     }
    29.  
    30.     @Override
    31.     public String toString(@Nullable Event event, boolean debug) {
    32.         return "Kick player effect with expression player: " + player.toString(event, debug) + " and string expression: " + reason.toString(event, debug);
    33.     }
    34.  
    35.     @Override
    36.     protected void execute(Event event) {
    37.         if (player == null)  return;
    38.         for (Player user : player.getAll(event)) {
    39.             if (reason != null || reason.getSingle(event) != null) {
    40.                 user.kickPlayer(reason.getSingle(event));
    41.             } else {
    42.                 user.kickPlayer("You have been kicked.");
    43.             }
    44.         }
    45.     }
    46. }
    47.  
    To look at more examples you can check out Skript's effects from Bensku's fork here https://github.com/bensku/Skript/tree/master/src/main/java/ch/njol/skript/effects


    Addon tutorial
    Back | Next