diff --git a/README.md b/README.md index 903a547..e09b3ed 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ You can add the library by inserting the following in your `build.gradle` : ```gradle repositories { - maven { - name = 'Ladysnake Libs' - url = 'https://dl.bintray.com/ladysnake/libs' + maven { + name = "Ladysnake Libs" + url = 'https://dl.bintray.com/ladysnake/libs' } } @@ -37,6 +37,9 @@ You can find the current version of PAL in the [releases](https://github.com/Lad You can find a couple examples in the [Test Mod](https://github.com/Ladysnake/PlayerAbilityLib/tree/master/src/testmod/java/io/github/ladysnake/paltest). +Note that player abilities can only accessed serverside. If you want to store more complex data, or to synchronize it between server and client, +you should take a look at [Cardinal Components API](https://github.com/OnyxStudios/Cardinal-Components-API). + [Item that toggles an ability](https://github.com/Ladysnake/PlayerAbilityLib/blob/master/src/testmod/java/io/github/ladysnake/paltest/AbilityToggleItem.java) : ```java public static final AbilitySource FLIGHT_CHARM = Pal.getAbilitySource("mymod", "flight_charm"); // works like an identifier diff --git a/build.gradle b/build.gradle index 9bda730..cb55eb8 100644 --- a/build.gradle +++ b/build.gradle @@ -36,7 +36,7 @@ dependencies { mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - api "org.jetbrains:annotations:17.0.0" + api "org.jetbrains:annotations:19.0.0" testmodCompile sourceSets.main.output } diff --git a/src/main/java/io/github/ladysnake/pal/AbilitySource.java b/src/main/java/io/github/ladysnake/pal/AbilitySource.java index 8513f91..838a88d 100644 --- a/src/main/java/io/github/ladysnake/pal/AbilitySource.java +++ b/src/main/java/io/github/ladysnake/pal/AbilitySource.java @@ -80,13 +80,21 @@ public boolean grants(PlayerEntity player, PlayerAbility ability) { return ability.getTracker(player).isGrantedBy(this); } + /** + * Returns the identifier used to create this {@code AbilitySource}. + * + *
The returned identifier is unique and can be passed to {@link Pal#getAbilitySource(Identifier)}
+ * to retrieve this instance.
+ *
+ * @return the identifier wrapped by this {@code AbilitySource}
+ */
public Identifier getId() {
return this.id;
}
@Override
public String toString() {
- return "AbilitySource[" + this.id + "]";
+ return "AbilitySource@" + this.id;
}
}
diff --git a/src/main/java/io/github/ladysnake/pal/AbilityTracker.java b/src/main/java/io/github/ladysnake/pal/AbilityTracker.java
index cc25587..5bfea40 100644
--- a/src/main/java/io/github/ladysnake/pal/AbilityTracker.java
+++ b/src/main/java/io/github/ladysnake/pal/AbilityTracker.java
@@ -18,9 +18,13 @@
package io.github.ladysnake.pal;
import net.minecraft.nbt.CompoundTag;
+import org.jetbrains.annotations.Contract;
/**
* A tracker for a player ability that can be turned on or off.
+ *
+ * @apiNote this interface is intended to be implemented by API consumers that
+ * provide new {@linkplain PlayerAbility abilities}.
*/
public interface AbilityTracker {
@@ -32,6 +36,7 @@ public interface AbilityTracker {
*
* @param abilitySource the source granting the ability
*/
+ @Contract(mutates = "this")
void addSource(AbilitySource abilitySource);
/**
@@ -42,6 +47,7 @@ public interface AbilityTracker {
*
* @param abilitySource the source granting the ability
*/
+ @Contract(mutates = "this")
void removeSource(AbilitySource abilitySource);
/**
@@ -50,6 +56,7 @@ public interface AbilityTracker {
* @param abilitySource the source granting the ability
* @return {@code true} if this tracker's ability is provided by {@code abilitySource}
*/
+ @Contract(pure = true)
boolean isGrantedBy(AbilitySource abilitySource);
/**
@@ -60,6 +67,7 @@ public interface AbilityTracker {
*
* @return {@code true} if this ability is enabled
*/
+ @Contract(pure = true)
boolean isEnabled();
/**
@@ -78,6 +86,7 @@ public interface AbilityTracker {
*
* @param tag the tag to write to
*/
+ @Contract(mutates = "param")
void save(CompoundTag tag);
/**
@@ -85,5 +94,6 @@ public interface AbilityTracker {
*
* @param tag the tag to read from
*/
+ @Contract(mutates = "this")
void load(CompoundTag tag);
}
diff --git a/src/main/java/io/github/ladysnake/pal/PlayerAbility.java b/src/main/java/io/github/ladysnake/pal/PlayerAbility.java
index ad29de1..81c1d2c 100644
--- a/src/main/java/io/github/ladysnake/pal/PlayerAbility.java
+++ b/src/main/java/io/github/ladysnake/pal/PlayerAbility.java
@@ -22,6 +22,8 @@
import net.fabricmc.fabric.api.event.Event;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Identifier;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract;
import java.util.function.BiFunction;
@@ -41,6 +43,7 @@
* @see AbilityTracker
*/
public final class PlayerAbility {
+ @ApiStatus.Internal
final Event This method is called for every registered {@code PlayerAbility}
+ * when a new player is instantiated. It is not intended to be called from consumer code.
+ *
+ * @param player the player to create a tracker for.
+ * @return a new {@code AbilityTracker} for {@code player}.
+ */
+ @Contract("_ -> new")
+ @ApiStatus.Internal
public AbilityTracker createTracker(PlayerEntity player) {
return this.trackerFactory.apply(this, player);
}
+ /**
+ * Returns the identifier used to register this {@code PlayerAbility}.
+ *
+ * The returned identifier is unique and can be passed to {@link Pal#provideRegisteredAbility(Identifier)}
+ * to retrieve this instance.
+ *
+ * @return the identifier wrapped by this {@code PlayerAbility}
+ */
public Identifier getId() {
return this.id;
}
@Override
public String toString() {
- return "PlayerAbility[" + this.id + "]";
+ return "PlayerAbility@" + this.id;
}
}
diff --git a/src/main/java/io/github/ladysnake/pal/PlayerAbilityEnableCallback.java b/src/main/java/io/github/ladysnake/pal/PlayerAbilityEnableCallback.java
index ae1f525..a315d7d 100644
--- a/src/main/java/io/github/ladysnake/pal/PlayerAbilityEnableCallback.java
+++ b/src/main/java/io/github/ladysnake/pal/PlayerAbilityEnableCallback.java
@@ -21,9 +21,13 @@
import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.entity.player.PlayerEntity;
+/**
+ * Callback interface for receiving ability enabling events.
+ *
+ * @see PlayerAbilityUpdatedCallback
+ */
@FunctionalInterface
public interface PlayerAbilityEnableCallback {
-
Event The callback may return {@code false} to reject the activation,
+ * keeping the ability in its previous activation state.
+ * Some abilities may stay {@linkplain PlayerAbility#isEnabledFor(PlayerEntity) enabled}
+ * despite all sources of activation being rejected, because of intrinsic providers like the player's gamemode.
+ *
+ * @param player the affected player
+ * @param ability the ability being enabled
+ * @param abilitySource the source of the ability
+ * @return {@code true} to let {@code abilitySource} enable the ability on {@code player},
+ * and {@code false} to prevent the ability from being enabled.
+ */
+ boolean allow(PlayerEntity player, PlayerAbility ability, AbilitySource abilitySource);
}
diff --git a/src/main/java/io/github/ladysnake/pal/PlayerAbilityUpdatedCallback.java b/src/main/java/io/github/ladysnake/pal/PlayerAbilityUpdatedCallback.java
index 90f0451..9a14fd9 100644
--- a/src/main/java/io/github/ladysnake/pal/PlayerAbilityUpdatedCallback.java
+++ b/src/main/java/io/github/ladysnake/pal/PlayerAbilityUpdatedCallback.java
@@ -20,12 +20,22 @@
import net.fabricmc.fabric.api.event.Event;
import net.minecraft.entity.player.PlayerEntity;
+/**
+ * Callback interface for receiving ability update events.
+ *
+ * @see PlayerAbilityEnableCallback
+ */
@FunctionalInterface
public interface PlayerAbilityUpdatedCallback {
-
static Event This is independent of the actual value returned by {@link #isEnabled()}
+ * and may be used to update the latter.
+ *
+ * @return {@code true} if the tracked ability should currently be enabled
+ */
protected boolean shouldBeEnabled() {
- boolean enabled = false;
for (AbilitySource abilitySource : this.abilitySources) {
if (PlayerAbilityEnableCallback.EVENT.invoker().allow(this.player, this.ability, abilitySource)) {
- enabled = true;
- break;
+ return true;
}
}
- return enabled;
+ return false;
}
@Override
diff --git a/src/main/java/io/github/ladysnake/pal/VanillaAbilities.java b/src/main/java/io/github/ladysnake/pal/VanillaAbilities.java
index 59cc58f..0120aad 100644
--- a/src/main/java/io/github/ladysnake/pal/VanillaAbilities.java
+++ b/src/main/java/io/github/ladysnake/pal/VanillaAbilities.java
@@ -29,7 +29,7 @@ public final class VanillaAbilities {
/**
* If enabled, players become invulnerable* to all damage, like in creative and spectator mode.
*
- * Note", " Damage sources that {@link DamageSource#isOutOfWorld() bypass invulnerability}
+ * Note: Damage sources that {@link DamageSource#isOutOfWorld() bypass invulnerability}
* can still damage players with this ability enabled.
*
* @see PlayerAbilities#invulnerable
diff --git a/src/main/java/io/github/ladysnake/pal/impl/VanillaAbilityTracker.java b/src/main/java/io/github/ladysnake/pal/impl/VanillaAbilityTracker.java
index f49d6d7..84d8373 100644
--- a/src/main/java/io/github/ladysnake/pal/impl/VanillaAbilityTracker.java
+++ b/src/main/java/io/github/ladysnake/pal/impl/VanillaAbilityTracker.java
@@ -25,6 +25,7 @@
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.world.GameMode;
+import org.jetbrains.annotations.Contract;
import java.util.Objects;
import java.util.function.Predicate;
@@ -83,6 +84,7 @@ private static GameMode getGamemode(PlayerEntity player) {
@FunctionalInterface
public interface AbilitySetter {
+ @Contract(mutates = "param2")
void set(GameMode g, PlayerAbilities abilities, boolean enabled);
}
}
diff --git a/src/main/java/io/github/ladysnake/pal/impl/package-info.java b/src/main/java/io/github/ladysnake/pal/impl/package-info.java
new file mode 100644
index 0000000..f9124d5
--- /dev/null
+++ b/src/main/java/io/github/ladysnake/pal/impl/package-info.java
@@ -0,0 +1,4 @@
+@ApiStatus.Internal
+package io.github.ladysnake.pal.impl;
+
+import org.jetbrains.annotations.ApiStatus;