Skip to content

Improve Item Frames #5604

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
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
1 change: 1 addition & 0 deletions src/main/java/ch/njol/skript/Skript.java
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,7 @@ public void onEnable() {
try {
getAddonInstance().loadClasses("ch.njol.skript",
"conditions", "effects", "events", "expressions", "entity", "sections", "structures");
getAddonInstance().loadClasses("org.skriptlang.skript", "elements");
} catch (final Exception e) {
exception(e, "Could not load required .class files: " + e.getLocalizedMessage());
setEnabled(false);
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/ch/njol/skript/classes/data/BukkitClasses.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.Rotation;
import org.bukkit.Registry;
import org.bukkit.SoundCategory;
import org.bukkit.World;
Expand All @@ -55,6 +56,7 @@
import org.bukkit.entity.Cat;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Panda.Gene;
import org.bukkit.entity.Player;
Expand Down Expand Up @@ -100,6 +102,7 @@
import ch.njol.skript.localization.Language;
import ch.njol.skript.registrations.Classes;
import ch.njol.skript.util.BlockUtils;
import ch.njol.skript.util.EnchantmentType;
import ch.njol.skript.util.PotionEffectUtils;
import ch.njol.skript.util.StringMode;
import ch.njol.util.StringUtils;
Expand Down Expand Up @@ -1525,6 +1528,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"));

Classes.registerClass(new ClassInfo<>(ItemFrame.class, "itemframe")
.user("item ?frames?")
.name("Item Frame")
.description("Represents the itemframe entity. This classinfo is used to manipulate settings of itemframes in syntaxes.")
.since("INSERT VERSION")
.defaultExpression(new EventValueExpression<>(ItemFrame.class)));

}

}
21 changes: 20 additions & 1 deletion src/main/java/ch/njol/skript/classes/data/SkriptClasses.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.regex.Pattern;

import org.bukkit.Material;
import org.bukkit.Rotation;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.eclipse.jdt.annotation.Nullable;
Expand All @@ -36,6 +37,7 @@
import ch.njol.skript.bukkitutil.ItemUtils;
import ch.njol.skript.classes.Changer;
import ch.njol.skript.classes.ClassInfo;
import ch.njol.skript.classes.EnumClassInfo;
import ch.njol.skript.classes.EnumSerializer;
import ch.njol.skript.classes.Parser;
import ch.njol.skript.classes.Serializer;
Expand Down Expand Up @@ -691,6 +693,23 @@ public String toVariableNameString(VisualEffect e) {
.since("2.5")
.serializer(new YggdrasilSerializer<GameruleValue>())
);

/**
* TODO fix loading structure for allowing classinfos used in the default.lang file.
*
* Due to the loading structure of Skript. Aliases load the default.lang file.
* ClassInfos that are used within that file need to be registered in this class.
* SkriptClasses.class loads before loading Aliases.
*
* So the bukkit classes below must be present here.
*/
Classes.registerClass(new EnumClassInfo<>(Rotation.class, "rotation", "rotations")
.user("rotations?")
.name("Rotation")
.description(
"Specify a rotation based orientation, like that on a clock. Used in item frames.",
"It represents how something is viewed, as opposed to cardinal directions.")
.since("INSERT VERSION"));
}

}
134 changes: 134 additions & 0 deletions src/main/java/ch/njol/skript/effects/EffRotate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/**
* 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.effects;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import org.bukkit.Rotation;
import org.bukkit.entity.ItemFrame;
import org.bukkit.event.Event;
import org.eclipse.jdt.annotation.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.Since;
import ch.njol.skript.lang.Effect;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.Literal;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.util.Kleenean;

@Name("Rotate")
@Description("Rotate rotations or itemframes an amount of times based on the provided rotation.")
@Examples({
"rotate the event-item frame clockwise 2 times",
"rotate the event-item frame by 225 degrees"
})
@Since("INSERT VERSION")
public class EffRotate extends Effect {

static {
Skript.registerEffect(EffRotate.class, "rotate %~rotations% [:counter] clockwise %*number% times");
Skript.registerEffect(EffRotate.class, "rotate %itemframes% [by] %rotation%");
}

@Nullable
private Expression<ItemFrame> itemFrames;
private Expression<Rotation> rotations;
private boolean counter;
private int amount;

@Override
@SuppressWarnings("unchecked")
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
rotations = (Expression<Rotation>) exprs[matchedPattern ^ 0];
if (matchedPattern == 0) {
amount = Optional.ofNullable(((Literal<Number>) exprs[1]))
.map(Literal::getSingle)
.map(Number::intValue)
.orElse(1);
} else {
itemFrames = (Expression<ItemFrame>) exprs[0];
}
counter = parseResult.hasTag("counter");
return true;
}

@Override
protected void execute(Event event) {
if (itemFrames != null) {
Rotation rotation = rotations.getOptionalSingle(event).orElse(Rotation.NONE);
if (rotation == Rotation.NONE)
return;
itemFrames.stream(event).forEach(itemFrame ->
itemFrame.setRotation(rotate(itemFrame.getRotation(), rotation)));
return;
}
rotations.change(event, rotations.stream(event).map(this::rotate).toArray(Rotation[]::new), ChangeMode.SET);
}

/**
* The amount of times to rotate clockwise to get to the matched degree.
*/
private static final Map<Rotation, Integer> order = new HashMap<>();

static {
order.put(Rotation.CLOCKWISE_45, 1);
order.put(Rotation.CLOCKWISE, 2);
order.put(Rotation.CLOCKWISE_135, 3);
order.put(Rotation.FLIPPED, 4);
order.put(Rotation.FLIPPED_45, 5);
order.put(Rotation.COUNTER_CLOCKWISE, 6);
order.put(Rotation.COUNTER_CLOCKWISE_45, 7);
}

private Rotation rotate(Rotation relative, Rotation rotation) {
for (int i = 0; i < order.get(relative); i++)
rotation.rotateClockwise();
return rotation;
}

private Rotation rotate(Rotation rotation) {
for (int i = 0; i < amount; i++) {
if (counter) {
rotation.rotateCounterClockwise();
} else {
rotation.rotateClockwise();
}
}
return rotation;
}

@Override
public String toString(@Nullable Event event, boolean debug) {
String string;
if (itemFrames != null) {
string = "rotate " + itemFrames.toString(event, debug) + " " + rotations.toString(event, debug);
} else {
string = "rotate " + rotations.toString(event, debug) + (counter ? " counter " : "") + " clockwise";
}
return string + " " + amount + " time" + (amount <= 1 ? "" : "s");
}

}
132 changes: 132 additions & 0 deletions src/main/java/ch/njol/skript/entity/ItemFrameData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/**
* 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.entity;

import org.bukkit.Rotation;
import org.bukkit.entity.ItemFrame;
import org.bukkit.inventory.ItemStack;
import org.eclipse.jdt.annotation.Nullable;

import ch.njol.skript.aliases.ItemType;
import ch.njol.skript.lang.Literal;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.localization.Noun;
import ch.njol.skript.registrations.Classes;

public class ItemFrameData extends EntityData<ItemFrame> {

static {
EntityData.register(ItemFrameData.class, "item frame", ItemFrame.class, "item frame");
}

@Nullable
private ItemType type;

private Rotation rotation = Rotation.NONE;

public ItemFrameData() {}

public ItemFrameData(@Nullable ItemType type, @Nullable Rotation rotation) {
this.rotation = rotation;
this.type = type;
}

@Override
protected boolean init(Literal<?>[] exprs, int matchedPattern, ParseResult parseResult) {
if (exprs[0] != null)
type = (ItemType) exprs[0].getSingle();
if (exprs[1] != null)
rotation = (Rotation) exprs[1].getSingle();
return true;
}

@Override
protected boolean init(@Nullable Class<? extends ItemFrame> c, @Nullable ItemFrame itemframe) {
if (itemframe != null) {
ItemStack item = itemframe.getItem();
type = new ItemType(item);
rotation = itemframe.getRotation();
}
return true;
}

@Override
protected boolean match(ItemFrame itemframe) {
if (type == null)
return true;
return type.isOfType(itemframe.getItem()) && itemframe.getRotation() == rotation;
}

@Override
public void set(ItemFrame itemframe) {
assert type != null;
ItemStack item = type.getItem().getRandom();
if (item != null)
itemframe.setItem(item);
itemframe.setRotation(rotation);
}

@Override
public boolean isSupertypeOf(EntityData<?> entityData) {
if (!(entityData instanceof ItemFrameData))
return false;
ItemFrameData itemFrameData = (ItemFrameData) entityData;
if (type != null)
return itemFrameData.type != null && type.equals(itemFrameData.type) && rotation == itemFrameData.rotation;
return true;
}

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

@Override
public EntityData<?> getSuperType() {
return new ItemFrameData(type, rotation);
}

@Override
public String toString(int flags) {
if (type == null)
return super.toString(flags);
StringBuilder builder = new StringBuilder();
builder.append(Noun.getArticleWithSpace(type.getTypes().get(0).getGender(), flags));
builder.append("item frame " + type == null ? "" : "of " + type.toString(flags));
builder.append("rotated " + Classes.toString(rotation));
return builder.toString();
}

@Override
protected boolean equals_i(EntityData<?> entityData) {
if (!(entityData instanceof ItemFrameData))
return false;
return type == null ? true : type.equals(((ItemFrameData) entityData).type) && rotation == ((ItemFrameData) entityData).rotation;
}

@Override
protected int hashCode_i() {
int prime = 31;
int result = 1;
result = prime * result + (type == null ? 0 : type.hashCode());
result = prime * result + rotation.hashCode();
return result;
}

}
Loading
Loading