mirror of
https://github.com/SimplexDevelopment/FreedomNetworkSuite.git
synced 2025-06-26 19:44:27 +00:00
Documentation, Add BouncyPads
This commit is contained in:
@ -18,7 +18,7 @@ public class Fossil extends JavaPlugin
|
||||
registration.getModuleRegistry()
|
||||
.addModule(this);
|
||||
|
||||
registration.getServiceRegistry()
|
||||
registration.getServiceTaskRegistry()
|
||||
.registerService(
|
||||
SubscriptionProvider.syncService(this, trailer));
|
||||
}
|
||||
|
@ -0,0 +1,211 @@
|
||||
package me.totalfreedom.fossil.bouncypads;
|
||||
|
||||
import com.google.errorprone.annotations.Immutable;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.SplittableRandom;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
@ -0,0 +1,156 @@
|
||||
package me.totalfreedom.fossil.bouncypads;
|
||||
|
||||
import me.totalfreedom.base.CommonsBase;
|
||||
import me.totalfreedom.fossil.Fossil;
|
||||
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;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 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, CommonsBase
|
||||
.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());
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package me.totalfreedom.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;
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package me.totalfreedom.fossil.reactions;
|
||||
|
||||
import me.totalfreedom.display.BossBarDisplay;
|
||||
import me.totalfreedom.economy.EconomicEntity;
|
||||
import me.totalfreedom.shop.Reaction;
|
||||
import me.totalfreedom.shop.ReactionType;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.kyori.adventure.bossbar.BossBar;
|
||||
|
||||
import java.util.SplittableRandom;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* 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 onReact(final Consumer<EconomicEntity> entity)
|
||||
{
|
||||
entity.accept(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void display(final Audience audience)
|
||||
{
|
||||
final BossBar bossBar = BossBarDisplay.builder().setName(getRandomCharacterString())
|
||||
.setProgress(0.0F)
|
||||
.build();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user