Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/main/java/ch/njol/skript/aliases/ItemType.java
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ public void setTo(ItemType i) {
for (final ItemData d : i) {
types.add(d.clone());
}
isRandom = i.isRandom;
}

public ItemType(Block block) {
Expand Down Expand Up @@ -669,6 +670,8 @@ public ItemType clone() {

private final static Random random = new Random();

public boolean isRandom = false;

/**
* @return One random ItemStack that this ItemType represents. If you have a List or an Inventory, use {@link #addTo(Inventory)} or {@link #addTo(List)} respectively.
* @see #addTo(Inventory)
Expand All @@ -680,6 +683,11 @@ public ItemType clone() {
* @see #removeFrom(List...)
*/
public @Nullable ItemStack getRandom() {
if (isRandom) {
ItemStack stack = types.getFirst().getStack();
stack.setAmount(getAmount());
return stack;
}
List<ItemData> datas = types.stream()
.filter(data -> data.stack != null)
.collect(Collectors.toList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
import org.bukkit.inventory.*;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.potion.PotionType;
import org.skriptlang.skript.bukkit.item.book.elements.expressions.ExprBookPages;
import org.skriptlang.skript.bukkit.item.book.BookUtils;
import org.skriptlang.skript.bukkit.lang.eventvalue.EventValue;
import org.skriptlang.skript.bukkit.lang.eventvalue.EventValue.Time;
import org.skriptlang.skript.bukkit.lang.eventvalue.EventValueRegistry;
Expand Down Expand Up @@ -577,11 +577,11 @@ else if (hand == EquipmentSlot.OFF_HAND)
return book;
}));
registry.register(EventValue.builder(PlayerEditBookEvent.class, Component[].class)
.getter(event -> ExprBookPages.getPages(event.getPreviousBookMeta()).toArray(new Component[0]))
.getter(event -> BookUtils.getPages(event.getPreviousBookMeta()).toArray(new Component[0]))
.time(Time.PAST)
.build());
registry.register(EventValue.simple(PlayerEditBookEvent.class, Component[].class, event ->
ExprBookPages.getPages(event.getNewBookMeta()).toArray(new Component[0])));
BookUtils.getPages(event.getNewBookMeta()).toArray(new Component[0])));
//ItemDespawnEvent
registry.register(EventValue.simple(ItemDespawnEvent.class, Item.class, ItemDespawnEvent::getEntity));
registry.register(EventValue.simple(ItemDespawnEvent.class, ItemStack.class, event -> event.getEntity().getItemStack()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ public DefaultConverters() {}
ItemStack i = s.getItem();
return new ItemType(i != null ? i : new ItemStack(Material.AIR, 1));
});
// Slot - ItemStack
Converters.registerConverter(Slot.class, ItemStack.class, slot -> {
ItemStack item = slot.getItem();
return item == null ? new ItemStack(Material.AIR, 1) : item;
});

// Block - InventoryHolder
Converters.registerConverter(Block.class, InventoryHolder.class, b -> {
Expand Down
66 changes: 0 additions & 66 deletions src/main/java/ch/njol/skript/effects/EffOpenBook.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.skriptlang.skript.addon.AddonModule;
import org.skriptlang.skript.addon.HierarchicalAddonModule;
import org.skriptlang.skript.addon.SkriptAddon;
import org.skriptlang.skript.bukkit.item.book.elements.effects.*;
import org.skriptlang.skript.bukkit.item.book.elements.expressions.*;

public class BookModule extends HierarchicalAddonModule {
Expand All @@ -14,6 +15,7 @@ public BookModule(AddonModule parentModule) {
@Override
protected void loadSelf(SkriptAddon addon) {
register(addon,
EffOpenBook::register,
ExprBookAuthor::register,
ExprBookPages::register,
ExprBookTitle::register
Expand Down
102 changes: 102 additions & 0 deletions src/main/java/org/skriptlang/skript/bukkit/item/book/BookUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package org.skriptlang.skript.bukkit.item.book;

import io.papermc.paper.datacomponent.DataComponentTypes;
import io.papermc.paper.datacomponent.item.WritableBookContent;
import io.papermc.paper.datacomponent.item.WrittenBookContent;
import io.papermc.paper.text.Filtered;
import net.kyori.adventure.inventory.Book;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;
import org.jetbrains.annotations.Unmodifiable;

import java.util.List;
import java.util.function.Consumer;

@SuppressWarnings("UnstableApiUsage")
public final class BookUtils {

private BookUtils() { }

public static WrittenBookContent modifyWrittenContent(WrittenBookContent content, Consumer<WrittenBookContent.Builder> modifier) {
return modifyWrittenContent(content, modifier, true);
}

public static WrittenBookContent modifyWrittenContent(WrittenBookContent content, Consumer<WrittenBookContent.Builder> modifier, boolean preservePages) {
WrittenBookContent.Builder builder = WrittenBookContent.writtenBookContent(content.title(), content.author())
.generation(content.generation())
.resolved(content.resolved());
if (preservePages) {
//noinspection unchecked, rawtypes
builder.addFilteredPages((List) content.pages());
}
modifier.accept(builder);
return builder.build();
}

public static List<? extends Component> getPages(ItemStack book) {
if (book.hasData(DataComponentTypes.WRITTEN_BOOK_CONTENT)) {
//noinspection ConstantConditions - checked via hasData
return book.getData(DataComponentTypes.WRITTEN_BOOK_CONTENT).pages().stream()
.map(Filtered::raw)
.toList();
}
if (book.hasData(DataComponentTypes.WRITABLE_BOOK_CONTENT)) {
//noinspection ConstantConditions - checked via hasData
return book.getData(DataComponentTypes.WRITABLE_BOOK_CONTENT).pages().stream()
.map(filtered -> Component.text(filtered.raw()))
.toList();
}
return List.of();
}

public static void setPages(ItemStack book, List<? extends Component> pages) {
boolean hasWrittenBookContent = book.hasData(DataComponentTypes.WRITTEN_BOOK_CONTENT);
if (hasWrittenBookContent || book.getType() == Material.WRITTEN_BOOK) {
WrittenBookContent newContent;
if (hasWrittenBookContent) {
//noinspection ConstantConditions - checked via hasData
newContent = modifyWrittenContent(book.getData(DataComponentTypes.WRITTEN_BOOK_CONTENT),
content -> content.addPages(pages), false);
} else {
newContent = WrittenBookContent.writtenBookContent(getDefaultTitle(book), getDefaultAuthor(book))
.addPages(pages)
.build();
}
book.setData(DataComponentTypes.WRITTEN_BOOK_CONTENT, newContent);
return;
}

if (book.hasData(DataComponentTypes.WRITABLE_BOOK_CONTENT) || book.getType() == Material.WRITABLE_BOOK) {
LegacyComponentSerializer serializer = LegacyComponentSerializer.legacySection();
List<String> stringPages = pages.stream()
.map(serializer::serialize)
.toList();
book.setData(DataComponentTypes.WRITABLE_BOOK_CONTENT, WritableBookContent.writeableBookContent()
.addPages(stringPages)
.build());
}
}

public static String getDefaultTitle(ItemStack book) {
return LegacyComponentSerializer.legacySection().serialize(book.effectiveName());
}

public static String getDefaultAuthor(ItemStack book) {
return "Unknown";
}

@SuppressWarnings("ConstantValue") // true on 26.1 and older
private static final boolean EXTENDS_ADVENTURE_BOOK = Book.class.isAssignableFrom(BookMeta.class);

public static @Unmodifiable List<Component> getPages(BookMeta bookMeta) {
if (EXTENDS_ADVENTURE_BOOK) {
//noinspection ConstantConditions
return ((Book) (Object) bookMeta).pages();
}
return bookMeta.pages();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package org.skriptlang.skript.bukkit.item.book.elements.effects;

import ch.njol.skript.lang.SyntaxStringBuilder;
import io.papermc.paper.datacomponent.DataComponentTypes;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;

import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Example;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.lang.Effect;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.util.Kleenean;
import org.skriptlang.skript.registration.SyntaxInfo;
import org.skriptlang.skript.registration.SyntaxRegistry;

@Name("Open Book")
@Description("Opens a written book to a player.")
@Example("open book player's tool to player")
@Since("2.5.1")
public class EffOpenBook extends Effect {

public static void register(SyntaxRegistry syntaxRegistry) {
syntaxRegistry.register(SyntaxRegistry.EFFECT, SyntaxInfo.simple(EffOpenBook.class, EffOpenBook::new,
"(open|show) book %itemstack% (to|for) %players%"));
}

private Expression<ItemStack> book;
private Expression<Player> players;

@Override
public boolean init(Expression<?>[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
//noinspection unchecked
book = (Expression<ItemStack>) expressions[0];
//noinspection unchecked
players = (Expression<Player>) expressions[1];
return true;
}

@Override
protected void execute(Event event) {
ItemStack book = this.book.getSingle(event);
if (book == null || !book.hasData(DataComponentTypes.WRITTEN_BOOK_CONTENT)) {
return;
}
for (Player player : players.getArray(event)) {
player.openBook(book);
}
}

@Override
public String toString(@Nullable Event event, boolean debug) {
return new SyntaxStringBuilder(event, debug)
.append("open book", book, "to", players)
.toString();
}

}
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package org.skriptlang.skript.bukkit.item.book.elements.expressions;

import ch.njol.skript.aliases.ItemType;
import ch.njol.skript.classes.Changer.ChangeMode;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Example;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.expressions.base.SimplePropertyExpression;
import ch.njol.util.coll.CollectionUtils;
import io.papermc.paper.datacomponent.DataComponentTypes;
import io.papermc.paper.datacomponent.item.WrittenBookContent;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Material;
import org.bukkit.event.Event;
import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import org.skriptlang.skript.bukkit.item.book.BookUtils;
import org.skriptlang.skript.registration.SyntaxRegistry;

@Name("Book Author")
Expand All @@ -21,19 +25,21 @@
broadcast "A new book has been created by %author of event-item%"
""")
@Since("2.2-dev31")
public class ExprBookAuthor extends SimplePropertyExpression<ItemType, Component> {
public class ExprBookAuthor extends SimplePropertyExpression<ItemStack, Component> {

public static void register(SyntaxRegistry syntaxRegistry) {
syntaxRegistry.register(SyntaxRegistry.EXPRESSION, infoBuilder(ExprBookAuthor.class, Component.class,
"[book] (author|writer|publisher)", "itemtypes", false)
"[book] (author|writer|publisher)", "itemstacks", false)
.supplier(ExprBookAuthor::new)
.build());
}

@Override
public @Nullable Component convert(ItemType item) {
if (item.getItemMeta() instanceof BookMeta bookMeta && bookMeta.hasAuthor()) {
return bookMeta.author();
public @Nullable Component convert(ItemStack book) {
if (book.hasData(DataComponentTypes.WRITTEN_BOOK_CONTENT)) {
//noinspection ConstantConditions - checked via hasData
return LegacyComponentSerializer.legacySection()
.deserialize(book.getData(DataComponentTypes.WRITTEN_BOOK_CONTENT).author());
}
return null;
}
Expand All @@ -48,12 +54,20 @@ public static void register(SyntaxRegistry syntaxRegistry) {

@Override
public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
Component author = delta == null ? null : (Component) delta[0];
for (ItemType item : getExpr().getArray(event)) {
if (item.getItemMeta() instanceof BookMeta bookMeta) {
bookMeta.author(author);
item.setItemMeta(bookMeta);
String author = delta == null ? "" : LegacyComponentSerializer.legacySection().serialize(((Component) delta[0]));
for (ItemStack book : getExpr().getArray(event)) {
boolean hasContent = book.hasData(DataComponentTypes.WRITTEN_BOOK_CONTENT);
if (!hasContent && book.getType() != Material.WRITTEN_BOOK) {
continue;
}
WrittenBookContent newContent;
if (hasContent) {
newContent = BookUtils.modifyWrittenContent(book.getData(DataComponentTypes.WRITTEN_BOOK_CONTENT),
content -> content.author(author));
} else {
newContent = WrittenBookContent.writtenBookContent(BookUtils.getDefaultTitle(book), author).build();
}
book.setData(DataComponentTypes.WRITTEN_BOOK_CONTENT, newContent);
}
}

Expand Down
Loading
Loading