9
0
mirror of https://gitlab.com/SamB440/rpgregions-2.git synced 2026-01-04 15:31:38 +00:00

Mostly finish fauna

This commit is contained in:
SamB440
2023-11-22 21:26:06 +00:00
parent c2e1e77bbf
commit b941c0e7be
17 changed files with 433 additions and 26 deletions

View File

@@ -0,0 +1,55 @@
package net.islandearth.rpgregions.api.events;
import net.islandearth.rpgregions.fauna.FaunaInstance;
import net.islandearth.rpgregions.managers.data.region.Discovery;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class FaunaDiscoverEvent extends Event {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Player player;
private final FaunaInstance<?> fauna;
private final Discovery discovery;
public FaunaDiscoverEvent(Player player, FaunaInstance<?> fauna, Discovery discovery) {
this.player = player;
this.fauna = fauna;
this.discovery = discovery;
}
/**
* The player involved in this event.
* @return the player involved
*/
public Player getPlayer() {
return player;
}
/**
* Gets the fauna that has been discovered.
* @return {@link FaunaInstance} that was discovered
*/
public FaunaInstance<?> getFauna() {
return fauna;
}
/**
* Gets the discovery involved. Contains useful information such as the date.
* @return the fauna {@link Discovery}
*/
public Discovery getDiscovery() {
return discovery;
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}

View File

@@ -1,19 +1,30 @@
package net.islandearth.rpgregions.fauna;
import net.islandearth.rpgregions.api.IRPGRegionsAPI;
import net.islandearth.rpgregions.api.RPGRegionsAPI;
import net.islandearth.rpgregions.fauna.trigger.FaunaTrigger;
import net.kyori.adventure.inventory.Book;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
public abstract class FaunaInstance<M> {
private final String identifier;
private final String name;
private final List<String> description;
private final M type;
private final List<FaunaTrigger> triggers;
public FaunaInstance(String identifier, String name, M type, List<FaunaTrigger> triggers) {
public FaunaInstance(String identifier, String name, List<String> description, M type, List<FaunaTrigger> triggers) {
this.identifier = identifier;
this.name = name;
this.description = description;
this.type = type;
this.triggers = triggers;
}
@@ -22,10 +33,38 @@ public abstract class FaunaInstance<M> {
return identifier;
}
public String getName() {
public String getDisplayName() {
return name;
}
public List<String> getDescription() {
return description;
}
public void openDescription(Player player) {
player.playSound(player.getEyeLocation(), Sound.ITEM_BOOK_PAGE_TURN, 1f, 1f);
final IRPGRegionsAPI plugin = RPGRegionsAPI.getAPI();
final Book.Builder builder = Book.builder();
builder.title(Component.text("Bestiary", NamedTextColor.DARK_PURPLE));
// Lol, I wonder if some redistribution sites will auto-remove this line?
// Would cause errors.
builder.author(Component.text("RPGRegions %%__USER__%%"));
List<Component> pages = new ArrayList<>();
TextComponent.Builder pageBuilder = Component.text();
for (String line : description) {
if (line.equals("<newpage>")) {
pages.add(pageBuilder.build());
pageBuilder = Component.text();
continue;
}
pageBuilder.append(plugin.miniMessage().deserialize(line));
pageBuilder.appendNewline();
}
pages.add(pageBuilder.build());
builder.pages(pages);
plugin.adventure().player(player).openBook(builder.build());
}
public M getType() {
return type;
}
@@ -33,4 +72,8 @@ public abstract class FaunaInstance<M> {
public List<FaunaTrigger> getTriggers() {
return triggers;
}
public boolean hasTrigger(Class<? extends FaunaTrigger> type) {
return triggers.stream().anyMatch(trigger -> trigger.getClass().isAssignableFrom(type));
}
}

View File

@@ -3,10 +3,15 @@ package net.islandearth.rpgregions.managers.data.fauna;
import net.islandearth.rpgregions.fauna.FaunaInstance;
import java.util.List;
import java.util.Optional;
public interface IFaunaCache {
void reload();
List<FaunaInstance<?>> getFauna();
Optional<FaunaInstance<?>> getFauna(String id);
void addFauna(FaunaInstance<?> instance);
}

View File

@@ -48,7 +48,9 @@ public enum Translations {
COORDINATES(TranslationKey.of("coordinates")),
// Fauna
FAUNA_DISCOVER_TITLE(TranslationKey.of("fauna_discover_title")),
FAUNA_DISCOVER_SUBTITLE(TranslationKey.of("fauna_discover_subtitle"));
FAUNA_DISCOVER_SUBTITLE(TranslationKey.of("fauna_discover_subtitle")),
BESTIARY_DEFAULT_HOVER(TranslationKey.of("bestiary_default_hover")),
BESTIARY_PAGE_HEADER(TranslationKey.of("bestiary_page_header"));
private final TranslationKey key;
private final boolean isList;

View File

@@ -30,6 +30,13 @@ discovering_area_placeholder: "<gold>Discovering a new area (%d%)..."
requirement_met: "<gradient:dark_green:green>✔ %s"
requirement_not_met: "<gradient:dark_red:red>✘ %s"
coordinates: "<gray>Coordinates: %d, %d"
# Fauna related settings
# Fauna/flora related settings
fauna_discover_title: "<#F5AF2F>Bestiary Updated"
fauna_discover_subtitle: "<white>%s <#04DB64>indexed"
fauna_discover_subtitle: "<#04DB64>%s indexed"
bestiary_default_hover:
- "<gradient:gold:yellow>Click to find out more!"
bestiary_page_header:
- " <gradient:gold:yellow>A compendium of fauna and flora"
- " ------------------"
- " <#04DB64>Explore the world to discover entries."
- " "

View File

@@ -25,6 +25,7 @@ import net.islandearth.rpgregions.gson.ItemStackAdapter;
import net.islandearth.rpgregions.gson.LocationAdapter;
import net.islandearth.rpgregions.gson.PotionEffectAdapter;
import net.islandearth.rpgregions.listener.ConnectionListener;
import net.islandearth.rpgregions.listener.FaunaListener;
import net.islandearth.rpgregions.listener.MoveListener;
import net.islandearth.rpgregions.listener.RegionListener;
import net.islandearth.rpgregions.listener.ServerReloadListener;
@@ -208,6 +209,7 @@ public final class RPGRegions extends JavaPlugin implements IRPGRegionsAPI {
pm.registerEvents(new ServerReloadListener(this), this);
pm.registerEvents(new ConnectionListener(this), this);
pm.registerEvents(new RegionListener(this), this);
pm.registerEvents(new FaunaListener(this), this);
pm.registerEvents(new MoveListener(this), this);
if (Bukkit.getPluginManager().getPlugin("CustomStructures") != null) {
pm.registerEvents(new CustomStructuresListener(this), this);

View File

@@ -11,6 +11,7 @@ import cloud.commandframework.meta.CommandMeta;
import cloud.commandframework.minecraft.extras.MinecraftExceptionHandler;
import cloud.commandframework.paper.PaperCommandManager;
import com.google.common.collect.ImmutableList;
import io.leangen.geantyref.TypeFactory;
import io.leangen.geantyref.TypeToken;
import net.islandearth.rpgregions.RPGRegions;
import net.islandearth.rpgregions.api.integrations.rpgregions.RPGRegionsIntegration;
@@ -18,7 +19,9 @@ import net.islandearth.rpgregions.api.integrations.rpgregions.region.RPGRegionsR
import net.islandearth.rpgregions.commands.caption.RPGRegionsCaptionRegistry;
import net.islandearth.rpgregions.commands.caption.RPGRegionsCaptionRegistryFactory;
import net.islandearth.rpgregions.commands.parser.ConfiguredRegionArgument;
import net.islandearth.rpgregions.commands.parser.FaunaArgument;
import net.islandearth.rpgregions.commands.parser.IntegrationRegionArgument;
import net.islandearth.rpgregions.fauna.FaunaInstance;
import net.islandearth.rpgregions.managers.data.region.ConfiguredRegion;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
@@ -102,6 +105,8 @@ public class Commands {
final ParserRegistry<CommandSender> parserRegistry = manager.parserRegistry();
parserRegistry.registerParserSupplier(TypeToken.get(ConfiguredRegion.class), parserParameters ->
new ConfiguredRegionArgument.ConfiguredRegionParser<>());
parserRegistry.registerParserSupplier(TypeToken.get(TypeFactory.parameterizedClass(FaunaInstance.class, TypeFactory.unboundWildcard())), parserParameters ->
new FaunaArgument.FaunaParser<>());
parserRegistry.registerParserSupplier(TypeToken.get(RPGRegionsRegion.class), parserParameters ->
new IntegrationRegionArgument.IntegrationRegionParser<>());

View File

@@ -5,17 +5,35 @@ import cloud.commandframework.annotations.CommandDescription;
import cloud.commandframework.annotations.CommandMethod;
import cloud.commandframework.annotations.CommandPermission;
import net.islandearth.rpgregions.RPGRegions;
import net.islandearth.rpgregions.api.IRPGRegionsAPI;
import net.islandearth.rpgregions.api.RPGRegionsAPI;
import net.islandearth.rpgregions.api.events.FaunaDiscoverEvent;
import net.islandearth.rpgregions.api.events.RegionDiscoverEvent;
import net.islandearth.rpgregions.fauna.FaunaInstance;
import net.islandearth.rpgregions.gui.DiscoveryGUI;
import net.islandearth.rpgregions.managers.data.fauna.IFaunaCache;
import net.islandearth.rpgregions.managers.data.region.ConfiguredRegion;
import net.islandearth.rpgregions.managers.data.region.WorldDiscovery;
import net.islandearth.rpgregions.translation.Translations;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.inventory.Book;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.JoinConfiguration;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.Sound;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
public class DiscoveriesCommand {
@@ -32,9 +50,67 @@ public class DiscoveriesCommand {
new DiscoveryGUI(plugin, player).open();
}
@CommandDescription("Opens the bestiary book")
@CommandPermission("rpgregions.bestiary")
@CommandMethod("bestiary|flora|fauna")
public void onBestiary(Player player) {
openBestiary(player);
}
@CommandDescription("Shows a specific bestiary entry")
@CommandPermission("rpgregions.bestiary")
@CommandMethod("bestiary|flora|fauna show <fauna>")
public void onBestiaryShow(Player player,
@Argument(value = "fauna") FaunaInstance<?> fauna) {
fauna.openDescription(player);
}
private static final Component BULLET_POINT = Component.text("");
public static void openBestiary(Player player) {
player.playSound(player.getEyeLocation(), Sound.ITEM_BOOK_PAGE_TURN, 1f, 1f);
final IRPGRegionsAPI plugin = RPGRegionsAPI.getAPI();
final Audience audience = plugin.adventure().player(player);
final Book.Builder builder = Book.builder();
builder.title(Component.text("Bestiary", NamedTextColor.DARK_PURPLE));
// Lol, I wonder if some redistribution sites will auto-remove this line?
// Would cause errors.
builder.author(Component.text("RPGRegions %%__USER__%%"));
List<Component> pages = new ArrayList<>();
int index = 0;
index += Translations.BESTIARY_PAGE_HEADER.get(player).size();
TextComponent.Builder pageBuilder = Component.text();
pageBuilder.append(Component.join(JoinConfiguration.newlines(), Translations.BESTIARY_PAGE_HEADER.get(player)));
if (index != 0) pageBuilder.appendNewline();
final IFaunaCache faunaCache = plugin.getManagers().getFaunaCache();
for (FaunaInstance<?> fauna : faunaCache.getFauna()) {
if (index > 12) {
if (!PlainTextComponentSerializer.plainText().serialize(pageBuilder.build()).isEmpty()) pages.add(pageBuilder.build());
pageBuilder = Component.text();
index = 0;
}
Component displayName = BULLET_POINT.append(plugin.miniMessage().deserialize(fauna.getDisplayName()));
// If there is no configured hover, set our own
if (displayName.hoverEvent() == null) {
displayName = displayName.hoverEvent(HoverEvent.showText(Component.join(JoinConfiguration.newlines(), Translations.BESTIARY_DEFAULT_HOVER.get(player))));
}
pageBuilder.append(displayName.clickEvent(ClickEvent.runCommand("/bestiary show " + fauna.getIdentifier())));
pageBuilder.appendNewline();
index++;
}
if (!PlainTextComponentSerializer.plainText().serialize(pageBuilder.build()).isEmpty()) {
pages.add(pageBuilder.build());
}
builder.pages(pages);
audience.openBook(builder.build());
}
@CommandDescription("Discovers a region for a player")
@CommandPermission("rpgregions.discover")
@CommandMethod("discoveries|discovery discover <region> <player>")
@CommandMethod("discoveries|discovery discover region <region> <player>")
public void onDiscover(CommandSender sender,
@Argument("region") ConfiguredRegion configuredRegion,
@Argument("player") OfflinePlayer target) {
@@ -52,4 +128,26 @@ public class DiscoveriesCommand {
sender.sendMessage(ChatColor.GREEN + "The player " + target.getName() + " has had the discovery added.");
});
}
@CommandDescription("Discovers fauna for a player")
@CommandPermission("rpgregions.discover")
@CommandMethod("discoveries|discovery discover fauna <fauna> <player>")
public void onDiscover(CommandSender sender,
@Argument("fauna") FaunaInstance<?> fauna,
@Argument("player") OfflinePlayer target) {
plugin.getManagers().getStorageManager().getAccount(target.getUniqueId()).thenAccept(account -> {
LocalDateTime date = LocalDateTime.now();
final WorldDiscovery worldDiscovery = new WorldDiscovery(date, fauna.getIdentifier());
account.addDiscovery(worldDiscovery);
if (target.getPlayer() != null) {
Player player = target.getPlayer();
final FaunaDiscoverEvent event = new FaunaDiscoverEvent(player, fauna, worldDiscovery);
Bukkit.getPluginManager().callEvent(event);
player.sendMessage(ChatColor.GREEN + "An administrator added a discovery to your account.");
}
plugin.getManagers().getStorageManager().removeCachedAccount(target.getUniqueId());
sender.sendMessage(ChatColor.GREEN + "The player " + target.getName() + " has had the discovery added.");
});
}
}

View File

@@ -12,6 +12,7 @@ public class RPGRegionsCaptionKeys {
private static final Collection<Caption> RECOGNIZED_CAPTIONS = new LinkedList<>();
public static final Caption ARGUMENT_PARSE_FAILURE_REGION_NOT_FOUND = of("argument.parse.failure.region_not_found");
public static final Caption ARGUMENT_PARSE_FAILURE_FAUNA_NOT_FOUND = of("argument.parse.failure.fauna_not_found");
private RPGRegionsCaptionKeys() { }

View File

@@ -0,0 +1,96 @@
package net.islandearth.rpgregions.commands.parser;
import cloud.commandframework.arguments.CommandArgument;
import cloud.commandframework.arguments.parser.ArgumentParseResult;
import cloud.commandframework.arguments.parser.ArgumentParser;
import cloud.commandframework.captions.CaptionVariable;
import cloud.commandframework.context.CommandContext;
import cloud.commandframework.exceptions.parsing.NoInputProvidedException;
import cloud.commandframework.exceptions.parsing.ParserException;
import com.google.common.collect.ImmutableList;
import net.islandearth.rpgregions.api.RPGRegionsAPI;
import net.islandearth.rpgregions.commands.caption.RPGRegionsCaptionKeys;
import net.islandearth.rpgregions.fauna.FaunaInstance;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.List;
import java.util.Optional;
import java.util.Queue;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
public final class FaunaArgument<C> extends CommandArgument<C, FaunaInstance> {
public FaunaArgument(
final boolean required,
final @NonNull String name,
final @NonNull String defaultValue,
final @Nullable BiFunction<@NonNull CommandContext<C>, @NonNull String, @NonNull List<@NonNull String>> suggestionsProvider) {
super(required, name, new FaunaArgument.FaunaParser<>(), defaultValue, FaunaInstance.class, suggestionsProvider);
}
public static <C> FaunaArgument.Builder<C> newBuilder(final @NonNull String name) {
return new FaunaArgument.Builder<>(name);
}
public static final class Builder<C> extends CommandArgument.Builder<C, FaunaInstance> {
private Builder(final @NonNull String name) {
super(FaunaInstance.class, name);
}
@Override
public @NonNull CommandArgument<C, FaunaInstance> build() {
return new FaunaArgument<>(
this.isRequired(),
this.getName(),
this.getDefaultValue(),
this.getSuggestionsProvider()
);
}
}
public static final class FaunaParser<C> implements ArgumentParser<C, FaunaInstance> {
@Override
public @NonNull ArgumentParseResult<FaunaInstance> parse(
@NonNull CommandContext<@NonNull C> commandContext,
@NonNull Queue<@NonNull String> inputQueue) {
final String input = inputQueue.peek();
if (input == null) {
return ArgumentParseResult.failure(new NoInputProvidedException(
FaunaArgument.class,
commandContext
));
}
final Optional<FaunaInstance<?>> fauna = RPGRegionsAPI.getAPI().getManagers().getFaunaCache().getFauna(input);
if (fauna.isPresent()) {
inputQueue.remove();
return ArgumentParseResult.success(fauna.get());
}
return ArgumentParseResult.failure(new FaunaParserException(input, commandContext));
}
@Override
public @NonNull List<@NonNull String> suggestions(@NonNull CommandContext<C> commandContext, @NonNull String input) {
return ImmutableList.copyOf(RPGRegionsAPI.getAPI().getManagers().getFaunaCache().getFauna().stream().map(FaunaInstance::getIdentifier).collect(Collectors.toList()));
}
}
public static final class FaunaParserException extends ParserException {
public FaunaParserException(
final @NonNull String input,
final @NonNull CommandContext<?> context
) {
super(
FaunaParser.class,
context,
RPGRegionsCaptionKeys.ARGUMENT_PARSE_FAILURE_FAUNA_NOT_FOUND,
CaptionVariable.of("input", input)
);
}
}
}

View File

@@ -3,6 +3,8 @@ package net.islandearth.rpgregions.fauna;
import com.google.common.base.Enums;
import net.islandearth.rpgregions.RPGRegions;
import net.islandearth.rpgregions.fauna.trigger.FaunaTrigger;
import net.islandearth.rpgregions.fauna.trigger.KillFaunaTrigger;
import net.islandearth.rpgregions.fauna.trigger.NearbyFaunaTrigger;
import net.islandearth.rpgregions.managers.data.fauna.IFaunaCache;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
@@ -11,20 +13,30 @@ import org.bukkit.entity.EntityType;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class FaunaCache implements IFaunaCache {
private final RPGRegions plugin;
private final List<FaunaInstance<?>> fauna = new ArrayList<>();
public FaunaCache(RPGRegions plugin) {
this.plugin = plugin;
this.reload();
}
@Override
public void reload() {
fauna.clear();
plugin.saveResource("fauna/goat.yml", false);
File faunaFolder = new File(plugin.getDataFolder() + File.separator + "fauna");
for (File file : faunaFolder.listFiles()) {
if (!file.getName().endsWith(".yml")) continue;
final YamlConfiguration config = YamlConfiguration.loadConfiguration(file);
if (!config.getBoolean("enabled", true)) continue;
final String typeName = config.getString("type", "");
final String identifier = config.getString("identifier", "");
final String name = config.getString("name", "");
final String name = config.getString("display_name", "");
List<FaunaTrigger> triggers = new ArrayList<>();
final ConfigurationSection triggersSection = config.getConfigurationSection("triggers");
@@ -33,13 +45,14 @@ public class FaunaCache implements IFaunaCache {
if (triggerId.equals("nearby")) {
final double radius = triggerSection.getDouble("radius");
triggers.add(new NearbyFaunaTrigger(radius));
continue;
} else if (triggerId.equals("kill")) {
triggers.add(new KillFaunaTrigger());
}
}
final EntityType entityType = Enums.getIfPresent(EntityType.class, typeName).orNull();
if (entityType != null) {
this.addFauna(new VanillaMobFaunaInstance(identifier, name, entityType, triggers));
this.addFauna(new VanillaMobFaunaInstance(identifier, name, config.getStringList("description"), entityType, triggers));
}
}
}
@@ -49,6 +62,11 @@ public class FaunaCache implements IFaunaCache {
return fauna;
}
@Override
public Optional<FaunaInstance<?>> getFauna(String id) {
return fauna.stream().filter(instance -> instance.getIdentifier().equals(id)).findFirst();
}
@Override
public void addFauna(FaunaInstance<?> instance) {
fauna.add(instance);

View File

@@ -1,36 +1,40 @@
package net.islandearth.rpgregions.fauna;
import net.islandearth.rpgregions.RPGRegions;
import net.islandearth.rpgregions.api.events.FaunaDiscoverEvent;
import net.islandearth.rpgregions.fauna.trigger.FaunaTrigger;
import net.islandearth.rpgregions.fauna.trigger.KillFaunaTrigger;
import net.islandearth.rpgregions.managers.data.account.RPGRegionsAccount;
import net.islandearth.rpgregions.managers.data.region.WorldDiscovery;
import net.islandearth.rpgregions.translation.Translations;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.title.Title;
import org.bukkit.Bukkit;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
import java.time.LocalDateTime;
public class FaunaDiscoverer implements Runnable {
public class FaunaDiscoverer implements Runnable, Listener {
private final RPGRegions plugin;
public FaunaDiscoverer(RPGRegions plugin) {
this.plugin = plugin;
Bukkit.getPluginManager().registerEvents(this, plugin);
}
@Override
public void run() {
for (Player player : Bukkit.getOnlinePlayers()) {
final Audience audience = plugin.adventure().player(player);
if (!player.hasPermission("rpgregions.bestiary")) continue;
plugin.getManagers().getStorageManager().getAccount(player.getUniqueId()).thenAccept(account -> {
for (FaunaInstance<?> fauna : plugin.getManagers().getFaunaCache().getFauna()) {
if (account.hasDiscovered(fauna.getIdentifier())) continue;
for (FaunaTrigger trigger : fauna.getTriggers()) {
if (trigger.testRepeatable(player, fauna)) {
WorldDiscovery discovery = new WorldDiscovery(LocalDateTime.now(), fauna.getIdentifier());
account.addDiscovery(discovery);
audience.showTitle(Title.title(Translations.FAUNA_DISCOVER_TITLE.get(player, fauna.getName()).get(0), Translations.FAUNA_DISCOVER_SUBTITLE.get(player, fauna.getName()).get(0)));
discover(player, account, fauna);
break;
}
}
@@ -38,4 +42,29 @@ public class FaunaDiscoverer implements Runnable {
});
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onKill(EntityDeathEvent event) {
final LivingEntity entity = event.getEntity();
final Player killer = entity.getKiller();
if (killer == null || !killer.hasPermission("rpgregions.bestiary")) return;
plugin.getManagers().getStorageManager().getAccount(killer.getUniqueId()).thenAccept(account -> {
for (FaunaInstance<?> fauna : plugin.getManagers().getFaunaCache().getFauna()) {
if (fauna instanceof VanillaMobFaunaInstance vanillaInstance) {
if (vanillaInstance.getType() != entity.getType()) continue;
if (account.hasDiscovered(fauna.getIdentifier())) continue;
if (!fauna.hasTrigger(KillFaunaTrigger.class)) continue;
discover(killer, account, fauna);
return;
}
}
});
}
private void discover(Player player, RPGRegionsAccount account, FaunaInstance<?> fauna) {
WorldDiscovery discovery = new WorldDiscovery(LocalDateTime.now(), fauna.getIdentifier());
account.addDiscovery(discovery);
Bukkit.getPluginManager().callEvent(new FaunaDiscoverEvent(player, fauna, discovery));
}
}

View File

@@ -7,7 +7,7 @@ import java.util.List;
public class VanillaMobFaunaInstance extends FaunaInstance<EntityType> {
public VanillaMobFaunaInstance(String identifier, String name, EntityType type, List<FaunaTrigger> triggers) {
super(identifier, name, type, triggers);
public VanillaMobFaunaInstance(String identifier, String name, List<String> description, EntityType type, List<FaunaTrigger> triggers) {
super(identifier, name, description, type, triggers);
}
}

View File

@@ -0,0 +1,12 @@
package net.islandearth.rpgregions.fauna.trigger;
import net.islandearth.rpgregions.fauna.FaunaInstance;
import org.bukkit.entity.Player;
public class KillFaunaTrigger extends FaunaTrigger {
@Override
public boolean testRepeatable(Player player, FaunaInstance<?> instance) {
return false;
}
}

View File

@@ -1,6 +1,7 @@
package net.islandearth.rpgregions.fauna;
package net.islandearth.rpgregions.fauna.trigger;
import net.islandearth.rpgregions.fauna.trigger.FaunaTrigger;
import net.islandearth.rpgregions.fauna.FaunaInstance;
import net.islandearth.rpgregions.fauna.VanillaMobFaunaInstance;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;

View File

@@ -0,0 +1,28 @@
package net.islandearth.rpgregions.listener;
import net.islandearth.rpgregions.RPGRegions;
import net.islandearth.rpgregions.api.events.FaunaDiscoverEvent;
import net.islandearth.rpgregions.api.events.RPGRegionsReloadEvent;
import net.islandearth.rpgregions.fauna.FaunaInstance;
import net.islandearth.rpgregions.translation.Translations;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.title.Title;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public record FaunaListener(RPGRegions plugin) implements Listener {
@EventHandler
public void onDiscover(FaunaDiscoverEvent event) {
final Player player = event.getPlayer();
final Audience audience = plugin.adventure().player(player);
final FaunaInstance<?> fauna = event.getFauna();
audience.showTitle(Title.title(Translations.FAUNA_DISCOVER_TITLE.get(player, fauna.getDisplayName()).get(0), Translations.FAUNA_DISCOVER_SUBTITLE.get(player, fauna.getDisplayName()).get(0)));
}
@EventHandler
public void onReload(RPGRegionsReloadEvent event) {
plugin.getManagers().getFaunaCache().reload();
}
}

View File

@@ -1,16 +1,21 @@
# Whether this is enabled. Mostly for if you want to disable default files RPGRegions comes with.
enabled: true
# The type can either be of a vanilla entity type, or a MythicMob
type: GOAT
# A unique identifier for this fauna. Must not be the same name as a region, either.
identifier: goat
# Name shown in placeholder
display_name: "Goat"
# Name shown in placeholder. You can use MiniMessage formatting here, especially hover events for inside the bestiary book.
display_name: "<gradient:dark_aqua:aqua>Goat"
# Description shown in bestiary book
description:
- "The Goat is a fluffy, cute mob found in cold mountainous areas."
- "Goats are well-known for their milk that they produce."
- " <gold>Bestiary - Goat</gold>"
- "<gold>The Goat</gold> is a fluffy, cute mob found in <aqua>cold mountainous areas</aqua>."
- "Goats are well-known for the milk that they produce."
- " "
- "But beware! Turn your back, and out of spite you shall find yourself rammed into the air."
- "<red>But beware!</red> Turn your back, and out of spite you shall find yourself rammed into the air."
- "<newpage>" # Make a new page using the <newpage> tag. This is not MiniMessage, but a custom tag by RPGRegions.
- "Example text on page two."
# Triggers that define when this entity is discovered
triggers: