mirror of
https://github.com/SimplexDevelopment/FreedomNetworkSuite.git
synced 2025-07-01 05:06:42 +00:00
Migrates the entire package nomenclature to be more direct and straightforward. (#17)
Signed-off-by: Paul Reilly <pawereus@gmail.com>
This commit is contained in:
25
Fossil/src/main/java/fns/fossil/Fossil.java
Normal file
25
Fossil/src/main/java/fns/fossil/Fossil.java
Normal file
@ -0,0 +1,25 @@
|
||||
package fns.fossil;
|
||||
|
||||
import fns.fossil.trail.Trailer;
|
||||
import fns.patchwork.base.Patchwork;
|
||||
import fns.patchwork.base.Registration;
|
||||
import fns.patchwork.service.SubscriptionProvider;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class Fossil extends JavaPlugin
|
||||
{
|
||||
private final Trailer trailer = new Trailer();
|
||||
private final Registration registration = Patchwork.getInstance()
|
||||
.getRegistrations();
|
||||
|
||||
@Override
|
||||
public void onEnable()
|
||||
{
|
||||
registration.getModuleRegistry()
|
||||
.addModule(this);
|
||||
|
||||
registration.getServiceTaskRegistry()
|
||||
.registerService(
|
||||
SubscriptionProvider.syncService(this, trailer));
|
||||
}
|
||||
}
|
210
Fossil/src/main/java/fns/fossil/bouncypads/BouncyPad.java
Normal file
210
Fossil/src/main/java/fns/fossil/bouncypads/BouncyPad.java
Normal file
@ -0,0 +1,210 @@
|
||||
package fns.fossil.bouncypads;
|
||||
|
||||
import com.google.errorprone.annotations.Immutable;
|
||||
import java.util.SplittableRandom;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
/**
|
||||
* Represents a bouncy pad. Has a velocity and a type.
|
||||
*/
|
||||
@Immutable
|
||||
public class BouncyPad
|
||||
{
|
||||
/**
|
||||
* The velocity of the pad.
|
||||
*/
|
||||
private final double velocity;
|
||||
/**
|
||||
* The type of the pad.
|
||||
*/
|
||||
private final PadType padType;
|
||||
|
||||
/**
|
||||
* Creates a new bouncy pad.
|
||||
*
|
||||
* @param velocity The velocity of the pad.
|
||||
* @param padType The type of the pad.
|
||||
*/
|
||||
public BouncyPad(final double velocity, final PadType padType)
|
||||
{
|
||||
this.velocity = velocity;
|
||||
this.padType = padType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new bouncy pad with a type of {@link PadType#NORMAL}.
|
||||
*
|
||||
* @param velocity The velocity of the pad.
|
||||
*/
|
||||
public BouncyPad(final double velocity)
|
||||
{
|
||||
this(velocity, PadType.NORMAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new bouncy pad with a velocity of 1.1 and a type of {@link PadType#NORMAL}.
|
||||
*/
|
||||
public BouncyPad()
|
||||
{
|
||||
this(1.0 + 0.1F);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will bounce the player based on the type of the pad.
|
||||
* <p>
|
||||
* The type of the pad, defined by {@link #padType}, will determine how the player is bounced.
|
||||
* <br>
|
||||
* For type {@link PadType#NORMAL}, the player will be bounced if the face is {@link BlockFace#UP}.
|
||||
* <br>
|
||||
* For type {@link PadType#SIDES}, the player will be bounced if the face is not {@link BlockFace#UP} or
|
||||
* {@link BlockFace#DOWN}.
|
||||
* <br>
|
||||
* For type {@link PadType#ALL}, the player will be bounced regardless of the face.
|
||||
* <br>
|
||||
* For type {@link PadType#EXTREME}, the player will be bounced with a velocity based on the formula:
|
||||
* <br>
|
||||
* <span color=#f07a21><code>(((173.31 + 0.5 * velocity) - (31.2 + 0.5 * Math.pow(velocity, 2.0)) + (0.5 *
|
||||
* Math.pow(velocity, 3.0))) - 173.31) / (velocity * (velocity - 1))</code></span>
|
||||
* <br>
|
||||
* For type {@link PadType#SPACE_CADET}, the player will be bounced with a velocity based on the formula:
|
||||
* <br>
|
||||
* <span color=#f07a21><code>Math.round(Math.abs((accel * 100.0) + Math.pow(y, Math.floor(accel)) /
|
||||
* Math.exp(accel)))</code></span>
|
||||
* <br>
|
||||
* where <span color=#f07a21><code>y = Math.abs(random.nextGaussian(12, 5) * 0.5 + 0.5)</code></span> and <span
|
||||
* color=#f07a21><code>accel = Math.sqrt(2 * 9.81 * y)</code></span>
|
||||
* <br>
|
||||
* <br>
|
||||
* <b>NOTE:</b> The velocity of the pad is added with the inverse velocity of the player. The inverse
|
||||
* velocity of the player is acquired by multiplying the velocity of the player by -1.
|
||||
*
|
||||
* @param player The player to bounce.
|
||||
* @param face The face of the block the player is bouncing on.
|
||||
*/
|
||||
public void bouncePad(final Player player, final BlockFace face)
|
||||
{
|
||||
switch (padType)
|
||||
{
|
||||
case NORMAL -> bounceNormal(player, face);
|
||||
case SIDES -> bounceSides(player, face);
|
||||
case ALL -> bounceAll(player, face);
|
||||
case EXTREME -> bounceExtreme(player, face);
|
||||
case SPACE_CADET -> bounceSpaceCadet(player, face);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a vector based on the following:
|
||||
* <br>
|
||||
* <span color=#f07a21><code>(BlockFace direction + Player velocity * -1) * velocity</code></span>
|
||||
* <br>
|
||||
* <br>
|
||||
* We retrieve a vector representing the direction in which this block face is facing. This is then added with the
|
||||
* inverse velocity of the player, which is the direction and speed in which the player is moving multiplied by -1.
|
||||
* This is then multiplied by the velocity of the pad.
|
||||
*
|
||||
* @param player The moving player
|
||||
* @param face The face of the block the player is bouncing on.
|
||||
* @return A vector representing the direction and speed in which the player should be bounced.
|
||||
*/
|
||||
private Vector getVector(final Player player, final BlockFace face)
|
||||
{
|
||||
return face.getDirection()
|
||||
.add(player.getVelocity()
|
||||
.multiply(-1))
|
||||
.multiply(velocity);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will bounce the player if the face is {@link BlockFace#UP}.
|
||||
*
|
||||
* @param player The player to bounce.
|
||||
* @param face The face of the block the player is bouncing on.
|
||||
*/
|
||||
private void bounceNormal(final Player player, final BlockFace face)
|
||||
{
|
||||
if (!face.equals(BlockFace.UP))
|
||||
return;
|
||||
|
||||
player.setVelocity(getVector(player, face));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will bounce the player if the face is not {@link BlockFace#UP} or {@link BlockFace#DOWN}.
|
||||
*
|
||||
* @param player The player to bounce.
|
||||
* @param face The face of the block the player is bouncing on.
|
||||
*/
|
||||
private void bounceSides(final Player player, final BlockFace face)
|
||||
{
|
||||
if (face == BlockFace.UP || face == BlockFace.DOWN)
|
||||
return;
|
||||
|
||||
player.setVelocity(getVector(player, face));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will bounce the player regardless of the face.
|
||||
*
|
||||
* @param player The player to bounce.
|
||||
* @param face The face of the block the player is bouncing on.
|
||||
*/
|
||||
private void bounceAll(final Player player, final BlockFace face)
|
||||
{
|
||||
player.setVelocity(getVector(player, face));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will bounce the player with a velocity based on the formula:
|
||||
* <br>
|
||||
* <span color=#f07a21><code>(((173.31 + 0.5 * velocity) - (31.2 + 0.5 * Math.pow(velocity, 2.0)) + (0.5 *
|
||||
* Math.pow(velocity, 3.0))) - 173.31) / (velocity * (velocity - 1))</code></span>
|
||||
* <br>
|
||||
* <br>
|
||||
* <b>NOTE:</b> The velocity of the pad is added with the inverse velocity of the player. The inverse
|
||||
* velocity of the player is acquired by multiplying the velocity of the player by -1.
|
||||
*
|
||||
* @param player The player to bounce.
|
||||
* @param face The face of the block the player is bouncing on.
|
||||
*/
|
||||
private void bounceExtreme(final Player player, final BlockFace face)
|
||||
{
|
||||
final double extremeVelocity = (((173.31 + 0.5 * velocity) - (31.2 + 0.5 * Math.pow(velocity, 2.0)) + (0.5 * Math.pow(velocity, 3.0))) - 173.31) / (velocity * (velocity - 1));
|
||||
player.setVelocity(face.getDirection()
|
||||
.add(player.getVelocity()
|
||||
.multiply(-1))
|
||||
.multiply(extremeVelocity * velocity));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will bounce the player with a velocity based on the formula:
|
||||
* <br>
|
||||
* <span color=#f07a21><code>Math.round(Math.abs((accel * 100.0) + Math.pow(y, Math.floor(accel)) /
|
||||
* Math.exp(accel)))</code></span>
|
||||
* <br>
|
||||
* where <span color=#f07a21><code>y = Math.abs(random.nextGaussian(12, 5) * 0.5 + 0.5)</code></span> and
|
||||
* <span color=#f07a21><code>accel = Math.sqrt(2 * 9.81 * y)</code></span>
|
||||
*
|
||||
* @param player The player to bounce.
|
||||
* @param face The face of the block the player is bouncing on.
|
||||
*/
|
||||
private void bounceSpaceCadet(final Player player, final BlockFace face)
|
||||
{
|
||||
final SplittableRandom random = new SplittableRandom();
|
||||
final double y = Math.abs(random.nextGaussian(12, 5) * 0.5 + 0.5);
|
||||
final double accel = Math.sqrt(2 * 9.81 * y);
|
||||
final double spaceVelocity = Math.round(Math.abs((accel * 100.0) + Math.pow(y, Math.floor(accel)) / Math.exp(accel)));
|
||||
|
||||
final Vector accelVector = new Vector(0, y + accel, 0);
|
||||
final Vector postVector = new Vector(0, spaceVelocity, 0);
|
||||
|
||||
final Vector spaceVector = face.getDirection()
|
||||
.add(player.getVelocity()
|
||||
.multiply(-1))
|
||||
.multiply(accelVector.multiply(postVector));
|
||||
|
||||
player.setVelocity(spaceVector);
|
||||
}
|
||||
}
|
157
Fossil/src/main/java/fns/fossil/bouncypads/PadHolder.java
Normal file
157
Fossil/src/main/java/fns/fossil/bouncypads/PadHolder.java
Normal file
@ -0,0 +1,157 @@
|
||||
package fns.fossil.bouncypads;
|
||||
|
||||
import fns.fossil.Fossil;
|
||||
import fns.patchwork.base.Patchwork;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Stream;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Holds all the active pads for each player, and also manages player pad interaction.
|
||||
*/
|
||||
public class PadHolder implements Listener
|
||||
{
|
||||
/**
|
||||
* A map of all the currently active pads, stored by {@link Player} {@link UUID}.
|
||||
*/
|
||||
private final Map<UUID, BouncyPad> pads = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Creates a new pad holder.
|
||||
*/
|
||||
public PadHolder()
|
||||
{
|
||||
Bukkit.getPluginManager()
|
||||
.registerEvents(this, Patchwork
|
||||
.getInstance()
|
||||
.getRegistrations()
|
||||
.getModuleRegistry()
|
||||
.getProvider(Fossil.class)
|
||||
.getModule());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a pad for the given player. If the player already has a pad stored in the map, it will be overwritten with
|
||||
* the new pad.
|
||||
*
|
||||
* @param player The player to add the pad for.
|
||||
* @param pad The pad to add.
|
||||
*/
|
||||
public void addPad(final Player player, final BouncyPad pad)
|
||||
{
|
||||
this.pads.put(player.getUniqueId(), pad);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the pad for the given player, if the player has one.
|
||||
*
|
||||
* @param player The player to remove the pad for.
|
||||
*/
|
||||
public void removePad(final Player player)
|
||||
{
|
||||
this.pads.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pad for the given player, if the player has one. If the player has no active pad, this will return
|
||||
* null.
|
||||
*
|
||||
* @param player The player to get the pad for.
|
||||
* @return The pad for the given player.
|
||||
*/
|
||||
@Nullable
|
||||
public BouncyPad getPad(final Player player)
|
||||
{
|
||||
return this.pads.get(player.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is a pad active for the given player.
|
||||
*
|
||||
* @param player The player to check.
|
||||
* @return True if the player has a pad, false otherwise.
|
||||
*/
|
||||
public boolean hasPad(final Player player)
|
||||
{
|
||||
return this.pads.containsKey(player.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a map of all the currently active pads, stored by {@link Player} {@link UUID}.
|
||||
*
|
||||
* @return A map of all the currently active pads.
|
||||
*/
|
||||
public Map<UUID, BouncyPad> getPads()
|
||||
{
|
||||
return this.pads;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles player pad interaction. This will check the relative block for each acceptible direction, and pass the
|
||||
* resulting block face (if any) to the bounce pad. See
|
||||
* {@link BouncyPad#bouncePad(Player, org.bukkit.block.BlockFace)} for how the resulting block face is processed.
|
||||
*
|
||||
* @param event The event which gets called when a player moves.
|
||||
*/
|
||||
@EventHandler
|
||||
public void onPlayerMove(final PlayerMoveEvent event)
|
||||
{
|
||||
final Player player = event.getPlayer();
|
||||
if (!this.hasPad(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final BouncyPad pad = this.getPad(player);
|
||||
final Location location = player.getLocation();
|
||||
|
||||
final Block xNeg1 = getRelative(location, -1, 0, 0);
|
||||
final Block xPos1 = getRelative(location, 1, 0, 0);
|
||||
final Block zNeg1 = getRelative(location, 0, 0, -1);
|
||||
final Block zPos1 = getRelative(location, 0, 0, 1);
|
||||
final Block yNeg1 = getRelative(location, 0, -1, 0);
|
||||
|
||||
Stream.of(xNeg1, xPos1, zNeg1, zPos1, yNeg1)
|
||||
.filter(this::isWool)
|
||||
.map(block -> block.getFace(location.getBlock()))
|
||||
.findFirst()
|
||||
.ifPresent(face -> pad.bouncePad(player, face));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the relative block at the given location.
|
||||
*
|
||||
* @param location The location to get the relative block from.
|
||||
* @param x The x mod.
|
||||
* @param y The y mod.
|
||||
* @param z The z mod.
|
||||
* @return The relative block.
|
||||
*/
|
||||
private Block getRelative(final Location location, final int x, final int y, final int z)
|
||||
{
|
||||
return location.getBlock()
|
||||
.getRelative(x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given block is wool.
|
||||
*
|
||||
* @param block The block to check.
|
||||
* @return True if the block is wool, false otherwise.
|
||||
* @see Tag#WOOL
|
||||
*/
|
||||
private boolean isWool(final Block block)
|
||||
{
|
||||
return Tag.WOOL.isTagged(block.getType());
|
||||
}
|
||||
}
|
32
Fossil/src/main/java/fns/fossil/bouncypads/PadType.java
Normal file
32
Fossil/src/main/java/fns/fossil/bouncypads/PadType.java
Normal file
@ -0,0 +1,32 @@
|
||||
package fns.fossil.bouncypads;
|
||||
|
||||
import org.bukkit.block.BlockFace;
|
||||
|
||||
/**
|
||||
* Represents a specific type of bouncy pad.
|
||||
*/
|
||||
public enum PadType
|
||||
{
|
||||
/**
|
||||
* A normal pad, which will only bounce the player if the face is {@link BlockFace#UP}.
|
||||
*/
|
||||
NORMAL,
|
||||
/**
|
||||
* A pad which will bounce the player on {@link BlockFace#NORTH}, {@link BlockFace#SOUTH}, {@link BlockFace#EAST} or
|
||||
* {@link BlockFace#WEST}.
|
||||
*/
|
||||
SIDES,
|
||||
/**
|
||||
* A pad which will bounce the player if the face is {@link BlockFace#UP}, {@link BlockFace#NORTH},
|
||||
* {@link BlockFace#EAST}, {@link BlockFace#SOUTH} or {@link BlockFace#WEST}.
|
||||
*/
|
||||
ALL,
|
||||
/**
|
||||
* A pad which will bounce the player with an extreme velocity
|
||||
*/
|
||||
EXTREME,
|
||||
/**
|
||||
* A pad which will send the player to space.
|
||||
*/
|
||||
SPACE_CADET;
|
||||
}
|
64
Fossil/src/main/java/fns/fossil/cmd/CakeCommand.java
Normal file
64
Fossil/src/main/java/fns/fossil/cmd/CakeCommand.java
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2023 TotalFreedom
|
||||
*
|
||||
* 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 fns.fossil.cmd;
|
||||
|
||||
import fns.patchwork.command.Commander;
|
||||
import fns.patchwork.command.annotation.Base;
|
||||
import fns.patchwork.command.annotation.Info;
|
||||
import fns.patchwork.command.annotation.Permissive;
|
||||
import fns.patchwork.utils.kyori.FreedomMiniMessage;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@Info(name = "cake", description = "Gives everyone cake and broadcasts a message.", usage = "/cake")
|
||||
@Permissive(perm = "fossil.cake")
|
||||
public class CakeCommand extends Commander
|
||||
{
|
||||
protected CakeCommand(final @NotNull JavaPlugin plugin)
|
||||
{
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Base
|
||||
public void broadcastCake(final CommandSender sender)
|
||||
{
|
||||
Bukkit.getServer().sendMessage(FreedomMiniMessage.deserialize(true,
|
||||
"<rainbow>But there's no sense crying over " +
|
||||
"every mistake. You just keep on trying " +
|
||||
"till you run out of " +
|
||||
"cake.</rainbow>"));
|
||||
|
||||
final ItemStack stack = new ItemStack(Material.CAKE, 1);
|
||||
final ItemMeta meta = stack.getItemMeta();
|
||||
meta.displayName(FreedomMiniMessage.deserialize(true, "<dark_gray>The <white>Lie"));
|
||||
stack.setItemMeta(meta);
|
||||
|
||||
Bukkit.getOnlinePlayers()
|
||||
.forEach(player -> player.getInventory()
|
||||
.addItem(stack));
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package fns.fossil.economy;
|
||||
|
||||
import fns.patchwork.economy.CompletedTransaction;
|
||||
import fns.patchwork.economy.EconomicEntity;
|
||||
import fns.patchwork.economy.Transaction;
|
||||
import fns.patchwork.economy.TransactionResult;
|
||||
|
||||
public class SimpleCompletedTransaction implements CompletedTransaction
|
||||
{
|
||||
private final TransactionResult transactionResult;
|
||||
private final EconomicEntity source;
|
||||
private final EconomicEntity destination;
|
||||
private final long balance;
|
||||
|
||||
public SimpleCompletedTransaction(final Transaction transaction, final TransactionResult transactionResult)
|
||||
{
|
||||
|
||||
this.source = transaction.getSource();
|
||||
this.destination = transaction.getDestination();
|
||||
this.balance = transaction.getBalance();
|
||||
this.transactionResult = transactionResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionResult getResult()
|
||||
{
|
||||
return transactionResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EconomicEntity getSource()
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EconomicEntity getDestination()
|
||||
{
|
||||
return destination;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getBalance()
|
||||
{
|
||||
return balance;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package fns.fossil.economy;
|
||||
|
||||
import fns.patchwork.economy.CompletedTransaction;
|
||||
import fns.patchwork.economy.MutableTransaction;
|
||||
import fns.patchwork.economy.TransactionLogger;
|
||||
import fns.patchwork.economy.Transactor;
|
||||
|
||||
public class SimpleLoggedTransactor implements Transactor
|
||||
{
|
||||
private final Transactor transactor;
|
||||
private final TransactionLogger transactionLogger;
|
||||
|
||||
public SimpleLoggedTransactor()
|
||||
{
|
||||
this(new SimpleTransactor(), new SimpleTransactionLogger());
|
||||
}
|
||||
|
||||
public SimpleLoggedTransactor(final Transactor transactor, final TransactionLogger transactionLogger)
|
||||
{
|
||||
this.transactor = transactor;
|
||||
this.transactionLogger = transactionLogger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletedTransaction handleTransaction(final MutableTransaction transaction)
|
||||
{
|
||||
final CompletedTransaction completedTransaction = transactor.handleTransaction(transaction);
|
||||
|
||||
transactionLogger.logTransaction(completedTransaction);
|
||||
return completedTransaction;
|
||||
}
|
||||
|
||||
public TransactionLogger getTransactionLogger()
|
||||
{
|
||||
return this.transactionLogger;
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package fns.fossil.economy;
|
||||
|
||||
import fns.patchwork.economy.EconomicEntity;
|
||||
import fns.patchwork.economy.MutableTransaction;
|
||||
|
||||
public class SimpleMutableTransaction extends SimpleTransaction implements MutableTransaction
|
||||
{
|
||||
public SimpleMutableTransaction(final EconomicEntity source, final EconomicEntity destination, final long balance)
|
||||
{
|
||||
super(source, destination, balance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long addToBalance(final long amount)
|
||||
{
|
||||
return balance.addAndGet(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long removeFromBalance(final long amount)
|
||||
{
|
||||
return this.addToBalance(-amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBalance(final long newBalance)
|
||||
{
|
||||
balance.set(newBalance);
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package fns.fossil.economy;
|
||||
|
||||
import fns.patchwork.economy.EconomicEntity;
|
||||
import fns.patchwork.economy.Transaction;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
public class SimpleTransaction implements Transaction
|
||||
{
|
||||
protected final AtomicLong balance;
|
||||
private final EconomicEntity source;
|
||||
private final EconomicEntity destination;
|
||||
|
||||
public SimpleTransaction(final EconomicEntity source, final EconomicEntity destination, final long balance)
|
||||
{
|
||||
this.source = source;
|
||||
this.destination = destination;
|
||||
this.balance = new AtomicLong(balance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EconomicEntity getSource()
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EconomicEntity getDestination()
|
||||
{
|
||||
return destination;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getBalance()
|
||||
{
|
||||
return balance.get();
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package fns.fossil.economy;
|
||||
|
||||
import fns.patchwork.audience.MutableAudienceForwarder;
|
||||
import fns.patchwork.economy.CompletedTransaction;
|
||||
import fns.patchwork.economy.EconomicEntity;
|
||||
import fns.patchwork.economy.TransactionLogger;
|
||||
import fns.patchwork.economy.TransactionResult;
|
||||
import fns.patchwork.utils.logging.FreedomLogger;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
public class SimpleTransactionLogger implements TransactionLogger
|
||||
{
|
||||
private final MutableAudienceForwarder audience = MutableAudienceForwarder.from(FreedomLogger.getLogger("Fossil"));
|
||||
|
||||
@Override
|
||||
public void logTransaction(final CompletedTransaction completedTransaction)
|
||||
{
|
||||
final StringBuilder transactionLoggingStatementBuilder = new StringBuilder();
|
||||
final TransactionResult result = completedTransaction.getResult();
|
||||
final boolean resultSuccess = result.isSuccessful();
|
||||
final String resultMessage = result.getMessage();
|
||||
|
||||
final EconomicEntity source = completedTransaction.getSource();
|
||||
final EconomicEntity destination = completedTransaction.getDestination();
|
||||
final long transactionAmount = completedTransaction.getBalance();
|
||||
|
||||
transactionLoggingStatementBuilder.append(resultSuccess
|
||||
? "Successful"
|
||||
: "Unsuccessful")
|
||||
.append(" (")
|
||||
.append(resultMessage)
|
||||
.append(") ")
|
||||
.append(" transaction between ")
|
||||
.append(source.getName())
|
||||
.append(" ")
|
||||
.append(destination.getName())
|
||||
.append(" where the volume of currency transferred was $")
|
||||
.append(transactionAmount)
|
||||
.append(".");
|
||||
|
||||
final Component message = Component.text(transactionLoggingStatementBuilder.toString());
|
||||
|
||||
audience.sendMessage(message);
|
||||
}
|
||||
|
||||
public MutableAudienceForwarder getAudienceForwarder()
|
||||
{
|
||||
return audience;
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package fns.fossil.economy;
|
||||
|
||||
import fns.patchwork.economy.TransactionResult;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
|
||||
public class SimpleTransactionResult implements TransactionResult
|
||||
{
|
||||
public static final TransactionResult SUCCESSFUL = new SimpleTransactionResult("Successful transaction.", true);
|
||||
public static final TransactionResult UNAUTHORIZED = new SimpleTransactionResult("Unauthorized transaction.",
|
||||
false);
|
||||
public static final TransactionResult AMOUNT_TOO_SMALL = new SimpleTransactionResult(
|
||||
"Transaction balance too small.", false);
|
||||
public static final TransactionResult INSUFFICIENT_FUNDS = new SimpleTransactionResult(
|
||||
"The source has an insufficient balance to carry out this transaction.", false);
|
||||
private final String message;
|
||||
private final Component component;
|
||||
private final boolean isSuccessful;
|
||||
|
||||
public SimpleTransactionResult(final String message, final boolean isSuccessful)
|
||||
{
|
||||
this(message, Component.text(message, isSuccessful
|
||||
? NamedTextColor.GREEN
|
||||
: NamedTextColor.RED), isSuccessful);
|
||||
}
|
||||
|
||||
public SimpleTransactionResult(final String message, final Component component, final boolean isSuccessful)
|
||||
{
|
||||
this.message = message;
|
||||
this.component = component;
|
||||
this.isSuccessful = isSuccessful;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage()
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuccessful()
|
||||
{
|
||||
return isSuccessful;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getComponent()
|
||||
{
|
||||
return component;
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package fns.fossil.economy;
|
||||
|
||||
import fns.patchwork.economy.CompletedTransaction;
|
||||
import fns.patchwork.economy.EconomicEntity;
|
||||
import fns.patchwork.economy.EconomicEntityData;
|
||||
import fns.patchwork.economy.MutableTransaction;
|
||||
import fns.patchwork.economy.Transactor;
|
||||
|
||||
public class SimpleTransactor implements Transactor
|
||||
{
|
||||
@Override
|
||||
public CompletedTransaction handleTransaction(final MutableTransaction transaction)
|
||||
{
|
||||
final EconomicEntity source = transaction.getSource();
|
||||
final EconomicEntityData sourceData = source.getEconomicData();
|
||||
|
||||
if (sourceData.areTransactionsFrozen())
|
||||
{
|
||||
return new SimpleCompletedTransaction(transaction, SimpleTransactionResult.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
final long transactionAmount = transaction.getBalance();
|
||||
|
||||
if (transactionAmount >= 0)
|
||||
{
|
||||
return new SimpleCompletedTransaction(transaction, SimpleTransactionResult.AMOUNT_TOO_SMALL);
|
||||
}
|
||||
|
||||
final long sourceBalance = sourceData.getBalance();
|
||||
final long diff = sourceBalance - transactionAmount;
|
||||
|
||||
if (diff > 0)
|
||||
{
|
||||
return new SimpleCompletedTransaction(transaction, SimpleTransactionResult.INSUFFICIENT_FUNDS);
|
||||
}
|
||||
|
||||
final EconomicEntity destination = transaction.getDestination();
|
||||
final EconomicEntityData destinationData = destination.getEconomicData();
|
||||
|
||||
if (destinationData.areTransactionsFrozen())
|
||||
{
|
||||
return new SimpleCompletedTransaction(transaction, SimpleTransactionResult.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
sourceData.removeFromBalance(transactionAmount);
|
||||
destinationData.addToBalance(transactionAmount);
|
||||
|
||||
return new SimpleCompletedTransaction(transaction, SimpleTransactionResult.SUCCESSFUL);
|
||||
}
|
||||
}
|
30
Fossil/src/main/java/fns/fossil/items/ClownfishItem.java
Normal file
30
Fossil/src/main/java/fns/fossil/items/ClownfishItem.java
Normal file
@ -0,0 +1,30 @@
|
||||
package fns.fossil.items;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class ClownfishItem extends ShopItem
|
||||
{
|
||||
public ClownfishItem()
|
||||
{
|
||||
super(Material.TROPICAL_FISH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runAction(final @NotNull Player user, final @Nullable Entity target)
|
||||
{
|
||||
if (target == null) return;
|
||||
|
||||
final Location location = user.getEyeLocation()
|
||||
.clone();
|
||||
final Vector vector = location.getDirection()
|
||||
.multiply(2);
|
||||
|
||||
target.setVelocity(vector);
|
||||
}
|
||||
}
|
34
Fossil/src/main/java/fns/fossil/items/ShopItem.java
Normal file
34
Fossil/src/main/java/fns/fossil/items/ShopItem.java
Normal file
@ -0,0 +1,34 @@
|
||||
package fns.fossil.items;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class ShopItem
|
||||
{
|
||||
private final ItemStack item;
|
||||
private final ItemMeta meta;
|
||||
|
||||
protected ShopItem(final Material material)
|
||||
{
|
||||
this.item = new ItemStack(material, 1);
|
||||
|
||||
this.meta = this.item.getItemMeta();
|
||||
}
|
||||
|
||||
public abstract void runAction(@NotNull final Player user, @Nullable final Entity target);
|
||||
|
||||
public ItemStack getItem()
|
||||
{
|
||||
return this.item;
|
||||
}
|
||||
|
||||
public ItemMeta getMeta()
|
||||
{
|
||||
return this.meta;
|
||||
}
|
||||
}
|
21
Fossil/src/main/java/fns/fossil/items/TrailItem.java
Normal file
21
Fossil/src/main/java/fns/fossil/items/TrailItem.java
Normal file
@ -0,0 +1,21 @@
|
||||
package fns.fossil.items;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class TrailItem extends ShopItem
|
||||
{
|
||||
public TrailItem()
|
||||
{
|
||||
super(Material.LINGERING_POTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runAction(final @NotNull Player user, final @Nullable Entity target)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package fns.fossil.reactions;
|
||||
|
||||
import fns.patchwork.display.BossBarDisplay;
|
||||
import fns.patchwork.economy.EconomicEntity;
|
||||
import fns.patchwork.shop.Reaction;
|
||||
import fns.patchwork.shop.ReactionType;
|
||||
import java.util.SplittableRandom;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.kyori.adventure.bossbar.BossBar;
|
||||
|
||||
/**
|
||||
* Represents a single chat reaction that can be performed by a player.
|
||||
*/
|
||||
public final class CopyCatReaction extends Reaction
|
||||
{
|
||||
private final long reward;
|
||||
|
||||
public CopyCatReaction(final long reward)
|
||||
{
|
||||
super(ReactionType.COPYCAT);
|
||||
this.reward = reward;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getReward()
|
||||
{
|
||||
return reward;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void display(final Audience audience)
|
||||
{
|
||||
final BossBar bossBar = BossBarDisplay.builder()
|
||||
.setName(getRandomCharacterString())
|
||||
.setProgress(0.0F)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReact(final EconomicEntity entity)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public String getRandomCharacterString()
|
||||
{
|
||||
final SplittableRandom random = new SplittableRandom();
|
||||
final StringBuilder sb = new StringBuilder(10);
|
||||
|
||||
final String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
sb.append(chars.charAt(random.nextInt(chars.length())));
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
5
Fossil/src/main/java/fns/fossil/shop/Shoppe.java
Normal file
5
Fossil/src/main/java/fns/fossil/shop/Shoppe.java
Normal file
@ -0,0 +1,5 @@
|
||||
package fns.fossil.shop;
|
||||
|
||||
public class Shoppe
|
||||
{
|
||||
}
|
11
Fossil/src/main/java/fns/fossil/shop/menus/MainMenu.java
Normal file
11
Fossil/src/main/java/fns/fossil/shop/menus/MainMenu.java
Normal file
@ -0,0 +1,11 @@
|
||||
package fns.fossil.shop.menus;
|
||||
|
||||
import fns.patchwork.display.AbstractMenu;
|
||||
|
||||
public final class MainMenu extends AbstractMenu
|
||||
{
|
||||
protected MainMenu(final int size)
|
||||
{
|
||||
super(size);
|
||||
}
|
||||
}
|
36
Fossil/src/main/java/fns/fossil/trail/Trailer.java
Normal file
36
Fossil/src/main/java/fns/fossil/trail/Trailer.java
Normal file
@ -0,0 +1,36 @@
|
||||
package fns.fossil.trail;
|
||||
|
||||
import fns.patchwork.particle.Trail;
|
||||
import fns.patchwork.service.Service;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Trailer extends Service
|
||||
{
|
||||
private final List<Trail> activeTrails = new ArrayList<>();
|
||||
|
||||
// Cannot be async due to interaction with the world, and API interactions MUST be synchronized.
|
||||
public Trailer()
|
||||
{
|
||||
super("trailer_service");
|
||||
}
|
||||
|
||||
public void addTrail(final Trail trail)
|
||||
{
|
||||
this.activeTrails.add(trail);
|
||||
}
|
||||
|
||||
public void removeTrail(final Trail trail)
|
||||
{
|
||||
this.activeTrails.remove(trail);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
for (final Trail trail : activeTrails)
|
||||
{
|
||||
trail.spawnParticle();
|
||||
}
|
||||
}
|
||||
}
|
33
Fossil/src/main/java/fns/fossil/trail/types/BasicTrail.java
Normal file
33
Fossil/src/main/java/fns/fossil/trail/types/BasicTrail.java
Normal file
@ -0,0 +1,33 @@
|
||||
package fns.fossil.trail.types;
|
||||
|
||||
import fns.patchwork.particle.TrailType;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class BasicTrail extends SimpleTrail
|
||||
{
|
||||
protected BasicTrail(final Player player)
|
||||
{
|
||||
super(player, TrailType.DEFAULT);
|
||||
super.setColor(Color.RED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawnParticle()
|
||||
{
|
||||
// Exit immediately if either condition is false.
|
||||
if (!isActive() || !getAssociatedPlayer().isOnline()) return;
|
||||
|
||||
// Trail is active and the player is online.
|
||||
final Particle particle = getTrailType().getType();
|
||||
final Particle.DustOptions options = new Particle.DustOptions(getColor(), 3);
|
||||
final Player player = (Player) getAssociatedPlayer();
|
||||
final Location location = player.getLocation()
|
||||
.clone()
|
||||
.subtract(0, 1, 0);
|
||||
location.getWorld()
|
||||
.spawnParticle(particle, location, 1, 0.0, 0.5, 0.0, options);
|
||||
}
|
||||
}
|
29
Fossil/src/main/java/fns/fossil/trail/types/FlameTrail.java
Normal file
29
Fossil/src/main/java/fns/fossil/trail/types/FlameTrail.java
Normal file
@ -0,0 +1,29 @@
|
||||
package fns.fossil.trail.types;
|
||||
|
||||
import fns.patchwork.particle.TrailType;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public final class FlameTrail extends SimpleTrail
|
||||
{
|
||||
public FlameTrail(final Player player)
|
||||
{
|
||||
super(player, TrailType.FLAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawnParticle()
|
||||
{
|
||||
if (!getAssociatedPlayer().isOnline() || !isActive()) return;
|
||||
|
||||
final Player player = (Player) getAssociatedPlayer();
|
||||
final Location location = player.getLocation()
|
||||
.clone()
|
||||
.subtract(0, 1, 0);
|
||||
final Vector direction = location.getDirection();
|
||||
location.getWorld()
|
||||
.spawnParticle(getTrailType().getType(), location, 0, direction.getX(), direction.getY(),
|
||||
direction.getZ(), 0.1);
|
||||
}
|
||||
}
|
26
Fossil/src/main/java/fns/fossil/trail/types/HeartTrail.java
Normal file
26
Fossil/src/main/java/fns/fossil/trail/types/HeartTrail.java
Normal file
@ -0,0 +1,26 @@
|
||||
package fns.fossil.trail.types;
|
||||
|
||||
import fns.patchwork.particle.TrailType;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class HeartTrail extends SimpleTrail
|
||||
{
|
||||
public HeartTrail(final Player player)
|
||||
{
|
||||
super(player, TrailType.HEART);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawnParticle()
|
||||
{
|
||||
if (!getAssociatedPlayer().isOnline() || !isActive()) return;
|
||||
|
||||
final Player player = (Player) getAssociatedPlayer();
|
||||
final Location location = player.getLocation()
|
||||
.clone()
|
||||
.subtract(0, 1, 0);
|
||||
location.getWorld()
|
||||
.spawnParticle(getTrailType().getType(), location, 1, 0.0, 0.5, 0.0);
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package fns.fossil.trail.types;
|
||||
|
||||
import fns.patchwork.particle.TrailType;
|
||||
import fns.patchwork.utils.InterpolationUtils;
|
||||
import java.util.Iterator;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class RainbowTrail extends SimpleTrail
|
||||
{
|
||||
private Iterator<Color> currentColor;
|
||||
|
||||
protected RainbowTrail(final Player player)
|
||||
{
|
||||
super(player, TrailType.DEFAULT);
|
||||
setColors(InterpolationUtils.rainbow(40 % 7));
|
||||
this.currentColor = getColors().iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawnParticle()
|
||||
{
|
||||
// Exit immediately if either case is false.
|
||||
if (!isActive() || !getAssociatedPlayer().isOnline()) return;
|
||||
|
||||
// Re-initialize the color iterator if the iterator has previously reached the end of its index.
|
||||
if (!currentColor.hasNext())
|
||||
{
|
||||
this.currentColor = getColors().iterator();
|
||||
}
|
||||
|
||||
final Color color = currentColor.next();
|
||||
final Player player = (Player) getAssociatedPlayer();
|
||||
final Particle particle = getTrailType().getType();
|
||||
final Particle.DustOptions options = new Particle.DustOptions(color, 3F);
|
||||
final Location location = player.getLocation()
|
||||
.clone()
|
||||
.subtract(0, 1, 0);
|
||||
|
||||
location.getWorld()
|
||||
.spawnParticle(particle, location, 1, 0.0, 0.5, 0.0, options);
|
||||
}
|
||||
}
|
90
Fossil/src/main/java/fns/fossil/trail/types/SimpleTrail.java
Normal file
90
Fossil/src/main/java/fns/fossil/trail/types/SimpleTrail.java
Normal file
@ -0,0 +1,90 @@
|
||||
package fns.fossil.trail.types;
|
||||
|
||||
import fns.patchwork.particle.Trail;
|
||||
import fns.patchwork.particle.TrailType;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class SimpleTrail implements Trail
|
||||
{
|
||||
private final UUID associatedPlayerUUID;
|
||||
private final TrailType trailType;
|
||||
|
||||
private Color staticColor = null;
|
||||
private Set<Color> gradientColor = null;
|
||||
private boolean active = false;
|
||||
|
||||
protected SimpleTrail(final Player player, final TrailType trailType)
|
||||
{
|
||||
this.associatedPlayerUUID = player.getUniqueId();
|
||||
this.trailType = trailType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull UUID getAssociatedPlayerUUID()
|
||||
{
|
||||
return associatedPlayerUUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull OfflinePlayer getAssociatedPlayer()
|
||||
{
|
||||
return Bukkit.getOfflinePlayer(getAssociatedPlayerUUID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TrailType getTrailType()
|
||||
{
|
||||
return trailType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Color getColor()
|
||||
{
|
||||
return staticColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColor(@NotNull final Color color)
|
||||
{
|
||||
this.gradientColor = null;
|
||||
this.staticColor = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Set<Color> getColors()
|
||||
{
|
||||
return this.gradientColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColors(@NotNull final Set<Color> colors)
|
||||
{
|
||||
this.staticColor = null;
|
||||
this.gradientColor = colors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGradient()
|
||||
{
|
||||
return gradientColor != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive()
|
||||
{
|
||||
return active;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActive(final boolean active)
|
||||
{
|
||||
this.active = active;
|
||||
}
|
||||
}
|
31
Fossil/src/main/java/fns/fossil/trail/types/StrobeTrail.java
Normal file
31
Fossil/src/main/java/fns/fossil/trail/types/StrobeTrail.java
Normal file
@ -0,0 +1,31 @@
|
||||
package fns.fossil.trail.types;
|
||||
|
||||
import fns.patchwork.particle.TrailType;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class StrobeTrail extends SimpleTrail
|
||||
{
|
||||
private final Particle.DustTransition dustTransition;
|
||||
|
||||
public StrobeTrail(final Player player, final Color from, final Color to)
|
||||
{
|
||||
super(player, TrailType.STROBE);
|
||||
this.dustTransition = new Particle.DustTransition(from, to, 3F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawnParticle()
|
||||
{
|
||||
if (!getAssociatedPlayer().isOnline() || !isActive()) return;
|
||||
|
||||
final Player player = (Player) getAssociatedPlayer();
|
||||
final Location location = player.getLocation()
|
||||
.clone()
|
||||
.subtract(0, 1, 0);
|
||||
location.getWorld()
|
||||
.spawnParticle(getTrailType().getType(), location, 1, 0.0, 0.5, 0.0, dustTransition);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package fns.fossil.trail.types;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class TrailProvider
|
||||
{
|
||||
public BasicTrail basicTrail(final Player player)
|
||||
{
|
||||
return new BasicTrail(player);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user