Skip to content
93 changes: 93 additions & 0 deletions core/src/main/java/dev/triumphteam/gui/animations/Animation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* MIT License
*
* Copyright (c) 2021 TriumphTeam
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package dev.triumphteam.gui.animations;

import dev.triumphteam.gui.animations.impl.SimpleAnimation;
import dev.triumphteam.gui.animations.impl.InfiniteAnimation;
import dev.triumphteam.gui.guis.BaseGui;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Arrays;

public interface Animation {

/**
* Reset to the initial frame
*/
void reset();

/**
* Go to the next frame
* @return the next frame or null if it is the last frame
*/
@Nullable Frame nextFrame();

/**
* Start the animation
* @param gui The gui to apply the animation to
*/
void start(BaseGui gui);

/**
* Stops the animation
*/
void stop();

/**
* @return the delay between frames
*/
int getDelay();

/**
* @return the bukkit runnable that handles frame updates
*/
AnimationRunner getRunnable();

/**
* @return the gui that this animation is applyed to
*/
BaseGui getGui();

/**
* Create a simple animation that stop at the end of the frames
* @param delay the delay between frames
* @param frames the frames
* @return the animation
*/
static @NotNull Animation of(int delay, Frame... frames) {
return new SimpleAnimation(delay, Arrays.asList(frames));
}

/**
* Create a loop animation
* @param delay the delay between frames
* @param frames the frames
* @return the animation
*/
static @NotNull Animation infinite(int delay, Frame... frames) {
return new InfiniteAnimation(delay, Arrays.asList(frames));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* MIT License
*
* Copyright (c) 2021 TriumphTeam
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package dev.triumphteam.gui.animations;

import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull;

public class AnimationRunner extends BukkitRunnable {
private static final Plugin plugin = JavaPlugin.getProvidingPlugin(AnimationRunner.class);
private final Animation animation;

public AnimationRunner(@NotNull Animation animation) {
this.animation = animation;

this.runTaskTimerAsynchronously(plugin,animation.getDelay(),animation.getDelay());
}

@Override
public void run() {
Frame frame = animation.nextFrame();
if (frame == null) {
this.cancel();
}
}

}
98 changes: 98 additions & 0 deletions core/src/main/java/dev/triumphteam/gui/animations/Frame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* MIT License
*
* Copyright (c) 2021 TriumphTeam
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package dev.triumphteam.gui.animations;

import dev.triumphteam.gui.guis.BaseGui;
import dev.triumphteam.gui.guis.GuiItem;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;

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

public class Frame {
private boolean saved = false;
private final Map<Integer, GuiItem> defaultItems;
private final Map<Integer, GuiItem> items;

/**
* @param items A map with the slot and the item to display in this frame
*/
public Frame(Map<Integer, GuiItem> items) {
this.items = items;
this.defaultItems = new HashMap<>();
}

/**
* @param gui The gui to display this frame
* @return The same frame instance
*/
public Frame apply(@NotNull BaseGui gui) {
if (!saved) {
for (Map.Entry<Integer, GuiItem> entry : items.entrySet()) {
defaultItems.put(entry.getKey(), gui.getGuiItem(entry.getKey()));
}

saved = true;
}

items.forEach(gui::updateItem);
return this;
}

public void fallback(@NotNull BaseGui gui) {
defaultItems.forEach(gui::updateItem);
}

public Map<Integer, GuiItem> getItems() {
return items;
}

@Override
public String toString() {
return "Frame{" +
"items=" + items +
'}';
}

@Contract(value = " -> new", pure = true)
public static @NotNull Builder builder() {
return new Builder();
}

public static class Builder {
private final Map<Integer,GuiItem> items = new HashMap<>();

public Builder addItem(int slot, GuiItem item) {
items.put(slot, item);
return this;
}

@Contract(value = " -> new", pure = true)
public @NotNull Frame build() {
return new Frame(items);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* MIT License
*
* Copyright (c) 2021 TriumphTeam
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package dev.triumphteam.gui.animations.impl;

import dev.triumphteam.gui.animations.Animation;
import dev.triumphteam.gui.animations.AnimationRunner;
import dev.triumphteam.gui.animations.Frame;
import dev.triumphteam.gui.guis.BaseGui;
import org.apache.commons.lang3.Validate;
import org.jetbrains.annotations.Nullable;

import java.util.List;

public abstract class BaseAnimation implements Animation {
protected int current;
protected BaseGui gui;
protected AnimationRunner runner;
protected final int delay;
protected List<Frame> frames;

public BaseAnimation(int delay, List<Frame> frames) {
this.delay = delay;
this.frames = frames;

this.reset();
}

@Override
public void reset() {
current = 0;
}

@Override
public @Nullable Frame nextFrame() {
Validate.notNull(gui, "Gui has not been linked to this animation.");
current++;

if (frames.size() == current) {
return this.onFinish();
}

return frames.get(current).apply(gui);
}

@Override
public void start(BaseGui gui) {
Validate.notNull(gui, "Gui cannot be null.");
this.gui = gui;

this.reset();
frames.get(current).apply(gui);

if (runner != null) {
runner.cancel();
runner = null;
}

this.runner = new AnimationRunner(this);
}

@Override
public int getDelay() {
return delay;
}

@Override
public BaseGui getGui() {
return gui;
}

@Override
public AnimationRunner getRunnable() {
return runner;
}

@Override
public void stop() {
Validate.notNull(gui, "Gui has not been linked to this animation. Please link it by calling the to(BaseGui) method");

if (this.runner != null && !this.runner.isCancelled()) {
this.runner.cancel();
}
frames.get(0).fallback(gui);
}

/**
* @return The frame to return when the animation is finished
*/
public abstract Frame onFinish();
}
Loading