Skip to content

Commit

Permalink
Merge branch 'dev/feature' into dev/wolf-variants
Browse files Browse the repository at this point in the history
  • Loading branch information
TheAbsolutionism authored Sep 22, 2024
2 parents c09c2db + c4c5560 commit 95be0a6
Show file tree
Hide file tree
Showing 7 changed files with 362 additions and 35 deletions.
11 changes: 9 additions & 2 deletions src/main/java/ch/njol/skript/classes/data/BukkitClasses.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityPotionEffectEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
import org.bukkit.event.entity.EntityTransformEvent.TransformReason;
import org.bukkit.event.inventory.ClickType;
Expand Down Expand Up @@ -1529,8 +1530,14 @@ public String toVariableNameString(EnchantmentOffer eo) {
.name("Transform Reason")
.description("Represents a transform reason of an <a href='events.html#entity transform'>entity transform event</a>.")
.since("2.8.0"));

ClassInfo<?> wolfVariantClassInfo;

Classes.registerClass(new EnumClassInfo<>(EntityPotionEffectEvent.Cause.class, "entitypotioncause", "entity potion causes")
.user("(entity )?potion ?effect ?cause")
.name("Entity Potion Cause")
.description("Represents the cause of the action of a potion effect on an entity, e.g. arrow, command")
.since("INSERT VERSION"));

ClassInfo<?> wolfVariantClassInfo;
if (Skript.classExists("org.bukkit.entity.Wolf$Variant") && BukkitUtils.registryExists("WOLF_VARIANT")) {
wolfVariantClassInfo = new RegistryClassInfo<>(Wolf.Variant.class, Registry.WOLF_VARIANT, "wolfvariant", "wolf variants");
} else {
Expand Down
29 changes: 29 additions & 0 deletions src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
import org.bukkit.event.entity.EntityTeleportEvent;
import org.bukkit.event.entity.EntityTransformEvent;
import org.bukkit.event.entity.EntityTransformEvent.TransformReason;
import org.bukkit.event.entity.EntityPotionEffectEvent;
import org.bukkit.event.entity.FireworkExplodeEvent;
import org.bukkit.event.entity.HorseJumpEvent;
import org.bukkit.event.entity.ItemDespawnEvent;
Expand Down Expand Up @@ -178,6 +179,7 @@
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.Recipe;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionData;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.potion.PotionType;
Expand Down Expand Up @@ -548,6 +550,33 @@ public DamageCause get(final EntityDeathEvent e) {
return ldc == null ? null : ldc.getCause();
}
}, 0);

// Entity Potion Effect
EventValues.registerEventValue(EntityPotionEffectEvent.class, PotionEffect.class, new Getter<PotionEffect, EntityPotionEffectEvent>() {
@Override
public PotionEffect get(EntityPotionEffectEvent event) {
return event.getOldEffect();
}
}, EventValues.TIME_PAST);
EventValues.registerEventValue(EntityPotionEffectEvent.class, PotionEffect.class, new Getter<PotionEffect, EntityPotionEffectEvent>() {
@Override
public PotionEffect get(EntityPotionEffectEvent event) {
return event.getNewEffect();
}
}, EventValues.TIME_NOW);
EventValues.registerEventValue(EntityPotionEffectEvent.class, PotionEffectType.class, new Getter<PotionEffectType, EntityPotionEffectEvent>() {
@Override
public PotionEffectType get(EntityPotionEffectEvent event) {
return event.getModifiedType();
}
}, EventValues.TIME_NOW);
EventValues.registerEventValue(EntityPotionEffectEvent.class, EntityPotionEffectEvent.Cause.class, new Getter<EntityPotionEffectEvent.Cause, EntityPotionEffectEvent>() {
@Override
public EntityPotionEffectEvent.Cause get(EntityPotionEffectEvent event) {
return event.getCause();
}
}, EventValues.TIME_NOW);

// ProjectileHitEvent
// ProjectileHitEvent#getHitBlock was added in 1.11
if (Skript.methodExists(ProjectileHitEvent.class, "getHitBlock"))
Expand Down
74 changes: 74 additions & 0 deletions src/main/java/ch/njol/skript/events/EvtEntityPotion.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* This file is part of Skript.
*
* Skript is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Skript is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Skript. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
package ch.njol.skript.events;

import ch.njol.skript.Skript;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.Literal;
import ch.njol.skript.lang.SkriptEvent;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import org.bukkit.event.Event;
import org.bukkit.event.entity.EntityPotionEffectEvent;
import org.bukkit.potion.PotionEffectType;

import javax.annotation.Nullable;

public class EvtEntityPotion extends SkriptEvent {

static {
Skript.registerEvent("Entity Potion Effect", EvtEntityPotion.class, EntityPotionEffectEvent.class,
"entity potion effect [modif[y|ication]] [[of] %-potioneffecttypes%] [due to %-entitypotioncause%]")
.description("Called when an entity's potion effect is modified.", "This modification can include adding, removing or changing their potion effect.")
.examples(
"on entity potion effect modification:",
"\t\tbroadcast \"A potion effect was added to %event-entity%!\" ",
"",
"on entity potion effect modification of night vision:")
.since("INSERT VERSION");
}

@SuppressWarnings("unchecked")
private Expression<PotionEffectType> potionEffects;
private Expression<EntityPotionEffectEvent.Cause> cause;

@Override
public boolean init(Literal<?>[] args, int matchedPattern, ParseResult parseResult) {
potionEffects = (Expression<PotionEffectType>) args[0];
cause = (Expression<EntityPotionEffectEvent.Cause>) args[1];
return true;
}

@Override
public boolean check(Event event) {
EntityPotionEffectEvent potionEvent = (EntityPotionEffectEvent) event;
boolean effectMatches = potionEffects == null ||
(potionEvent.getOldEffect() != null && potionEffects.check(event, effectType -> effectType.equals(potionEvent.getOldEffect().getType()))) ||
(potionEvent.getNewEffect() != null && potionEffects.check(event, effectType -> effectType.equals(potionEvent.getNewEffect().getType())));

boolean causeMatches = cause == null || cause.check(event, cause -> cause.equals(potionEvent.getCause()));

return effectMatches && causeMatches;
}


@Override
public String toString(@Nullable Event event, boolean debug) {
return "on entity potion effect modification";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package ch.njol.skript.expressions;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;

import ch.njol.skript.Skript;
import ch.njol.skript.classes.Changer.ChangeMode;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.RequiredPlugins;
import ch.njol.skript.doc.Since;
import ch.njol.skript.expressions.base.SimplePropertyExpression;
import ch.njol.util.coll.CollectionUtils;

@Name("Player Chat Completions")
@Description({
"The custom chat completion suggestions. You can add, set, remove, and clear them. Removing the names of online players with this expression is ineffective.",
"This expression will not return anything due to Bukkit limitations."
})
@Examples({
"add \"Skript\" and \"Njol\" to chat completions of all players",
"remove \"text\" from {_p}'s chat completions",
"clear player's chat completions"
})
@RequiredPlugins("Spigot 1.19+")
@Since("INSERT VERSION")
public class ExprPlayerChatCompletions extends SimplePropertyExpression<Player, String> {

static {
if (Skript.methodExists(Player.class, "addCustomChatCompletions", Collection.class))
register(ExprPlayerChatCompletions.class, String.class, "[custom] chat completion[s]", "players");
}

@Override
public @Nullable String convert(Player player) {
return null; // Due to Bukkit limitations
}

@Override
public @Nullable Class<?>[] acceptChange(ChangeMode mode) {
return switch (mode) {
case ADD, SET, REMOVE, DELETE, RESET -> CollectionUtils.array(String[].class);
default -> null;
};
}

@Override
public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
Player[] players = getExpr().getArray(event);
if (players.length == 0)
return;
List<String> completions = new ArrayList<>();
if (delta != null && (mode == ChangeMode.ADD || mode == ChangeMode.REMOVE || mode == ChangeMode.SET)) {
completions = Arrays.stream(delta)
.filter(String.class::isInstance)
.map(String.class::cast)
.collect(Collectors.toList());
}
switch (mode) {
case DELETE, RESET, SET -> {
for (Player player : players)
player.setCustomChatCompletions(completions);
}
case ADD -> {
for (Player player : players)
player.addCustomChatCompletions(completions);
}
case REMOVE -> {
for (Player player : players)
player.removeCustomChatCompletions(completions);
}
}
}

@Override
public Class<? extends String> getReturnType() {
return String.class;
}

@Override
protected String getPropertyName() {
return "custom chat completions";
}

}
92 changes: 59 additions & 33 deletions src/main/java/ch/njol/skript/expressions/ExprRandomNumber.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
*/
package ch.njol.skript.expressions;

import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

import ch.njol.skript.lang.Literal;
import ch.njol.util.Math2;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;
Expand All @@ -36,62 +38,90 @@
import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.util.Kleenean;

@Name("Random Number")
@Name("Random Numbers")
@Description({
"A random number or integer between two given numbers. Use 'number' if you want any number with decimal parts, or use use 'integer' if you only want whole numbers.",
"Please note that the order of the numbers doesn't matter, i.e. <code>random number between 2 and 1</code> will work as well as <code>random number between 1 and 2</code>."
"A given amount of random numbers or integers between two given numbers. Use 'number' if you want any number with decimal parts, or use use 'integer' if you only want whole numbers.",
"Please note that the order of the numbers doesn't matter, i.e. <code>random number between 2 and 1</code> will work as well as <code>random number between 1 and 2</code>."
})
@Examples({
"set the player's health to a random number between 5 and 10",
"send \"You rolled a %random integer from 1 to 6%!\" to the player"
"set the player's health to a random number between 5 and 10",
"send \"You rolled a %random integer from 1 to 6%!\" to the player",
"set {_chances::*} to 5 random integers between 5 and 96",
"set {_decimals::*} to 3 random numbers between 2.7 and -1.5"
})
@Since("1.4")
@Since("1.4, INSERT VERSION (Multiple random numbers)")
public class ExprRandomNumber extends SimpleExpression<Number> {

static {
Skript.registerExpression(ExprRandomNumber.class, Number.class, ExpressionType.COMBINED,
"[a] random (:integer|number) (from|between) %number% (to|and) %number%");
"[a|%-integer%] random (:integer|number)[s] (from|between) %number% (to|and) %number%");
}

private Expression<Number> from, to;
@Nullable
private Expression<Integer> amount;
private Expression<Number> lower, upper;
private boolean isInteger;

@Override
@SuppressWarnings("unchecked")
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parser) {
from = (Expression<Number>) exprs[0];
to = (Expression<Number>) exprs[1];
isInteger = parser.hasTag("integer");
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
amount = (Expression<Integer>) exprs[0];
lower = (Expression<Number>) exprs[1];
upper = (Expression<Number>) exprs[2];
isInteger = parseResult.hasTag("integer");
return true;
}

@Override
@Nullable
protected Number[] get(Event event) {
Number from = this.from.getSingle(event);
Number to = this.to.getSingle(event);
Number lowerNumber = lower.getSingle(event);
Number upperNumber = upper.getSingle(event);
if (upperNumber == null || lowerNumber == null || !Double.isFinite(lowerNumber.doubleValue()) || !Double.isFinite(upperNumber.doubleValue()))
return new Number[0];

if (to == null || from == null || !Double.isFinite(from.doubleValue()) || !Double.isFinite(to.doubleValue()))
Integer amount = this.amount == null ? Integer.valueOf(1) : this.amount.getSingle(event);
if (amount == null || amount <= 0)
return new Number[0];

double lower = Math.min(lowerNumber.doubleValue(), upperNumber.doubleValue());
double upper = Math.max(lowerNumber.doubleValue(), upperNumber.doubleValue());
Random random = ThreadLocalRandom.current();
double min = Math.min(from.doubleValue(), to.doubleValue());
double max = Math.max(from.doubleValue(), to.doubleValue());

if (isInteger) {
long inf = Math2.ceil(min);
long sup = Math2.floor(max);
if (max - min < 1 && inf - sup <= 1) {
if (sup == inf || min == inf)
return new Long[] {inf};
if (max == sup)
return new Long[] {sup};
Long[] longs = new Long[amount];
long floored_upper = Math2.floor(upper);
long ceiled_lower = Math2.ceil(lower);

// catch issues like `integer between 0.5 and 0.6`
if (upper - lower < 1 && ceiled_lower - floored_upper <= 1) {
if (floored_upper == ceiled_lower || lower == ceiled_lower) {
Arrays.fill(longs, ceiled_lower);
return longs;
}
if (upper == floored_upper) {
Arrays.fill(longs, floored_upper);
return longs;
}
return new Long[0];
}
return new Long[] {inf + Math2.mod(random.nextLong(), sup - inf + 1)};

for (int i = 0; i < amount; i++)
longs[i] = Math2.ceil(lower) + Math2.mod(random.nextLong(), floored_upper - ceiled_lower + 1);
return longs;
// non-integers
} else {
Double[] doubles = new Double[amount];
for (int i = 0; i < amount; i++)
doubles[i] = Math.min(lower + random.nextDouble() * (upper - lower), upper);
return doubles;
}
}

return new Double[] {min + random.nextDouble() * (max - min)};
@Override
public boolean isSingle() {
if (amount instanceof Literal)
return ((Literal<Integer>) amount).getSingle() == 1;
return amount == null;
}

@Override
Expand All @@ -101,12 +131,8 @@ public Class<? extends Number> getReturnType() {

@Override
public String toString(@Nullable Event event, boolean debug) {
return "a random " + (isInteger ? "integer" : "number") + " between " + from.toString(event, debug) + " and " + to.toString(event, debug);
}

@Override
public boolean isSingle() {
return true;
return (amount == null ? "a" : amount.toString(event, debug)) + " random " + (isInteger ? "integer" : "number") +
(amount == null ? "" : "s") + " between " + lower.toString(event, debug) + " and " + upper.toString(event, debug);
}

}
Loading

0 comments on commit 95be0a6

Please sign in to comment.