Compare commits
No commits in common. "master" and "1.19.4-5" have entirely different histories.
14 changed files with 155 additions and 343 deletions
27
.github/workflows/build.yml
vendored
27
.github/workflows/build.yml
vendored
|
|
@ -1,27 +0,0 @@
|
||||||
name: Build JAR
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Set up JDK 17
|
|
||||||
uses: actions/setup-java@v4
|
|
||||||
with:
|
|
||||||
java-version: '17'
|
|
||||||
distribution: 'adopt'
|
|
||||||
- name: Grant execute permission for gradlew
|
|
||||||
run: chmod +x gradlew
|
|
||||||
- name: Get project version
|
|
||||||
run: echo "version=$(grep '^version' build.gradle | cut -d' ' -f3 | tr -d '\"')" >> $GITHUB_ENV
|
|
||||||
- name: Build with Gradle
|
|
||||||
run: ./gradlew build -x test
|
|
||||||
- name: Publish artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: FoliaFlow-${{ env.version }}-${{ github.sha }}
|
|
||||||
path: build/libs/FoliaFlow-${{ env.version }}.jar
|
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -116,4 +116,3 @@ run/
|
||||||
|
|
||||||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||||
!gradle-wrapper.jar
|
!gradle-wrapper.jar
|
||||||
niri-rpc/
|
|
||||||
|
|
|
||||||
44
README.md
44
README.md
|
|
@ -1,51 +1,19 @@
|
||||||
# THIS IS NOT MY PLUGIN, I JUST EDITED ONE SINGLE LINE IN PLUGIN.YML, THE ORIGINAL IS AT: https://github.com/MidnightTale/FoliaFlow
|
# FoliaFlow
|
||||||
|

|
||||||
|
|
||||||
FoliaFlow is a Minecraft plugin that allows players to using gravity block duplication glitch again in Paper and Folia
|
FoliaFlow is a Minecraft plugin that allows players to using gravity block duplication glitch again in folia (paper soon)
|
||||||
|
|
||||||
## How is work?
|
## How is work?
|
||||||
Whenever a falling sand entity comes close to or hits the end portal, a new falling sand entity is summoned with a velocity that shoots it straight into the portal. However, we encountered a problem when the entity got reset by the safe teleport Paper patch - it lose its velocity. To fix this, we added the velocity back when the entity was in the end.
|
Whenever a falling sand entity comes close to or hits the end portal, a new falling sand entity is summoned with a velocity that shoots it straight into the portal. However, we encountered a problem when the entity got reset by the safe teleport paper patch - it lost its velocity. To fix this, we added the velocity back when the entity was in the end. Another issue we faced was that the entity would instantly turn into a block upon teleportation because it have block below. To solve this, we made the center block of the spawn platform a slab, ensuring that the entity stays in its falling state.
|
||||||
|
|
||||||
## ⚠️If you using folia
|
|
||||||
And type of concreate factory collector that use piston full block to stop falling blocks. You should change to slab to prevent block early break follow picture below
|
|
||||||
### Top View
|
|
||||||

|
|
||||||
### Side View
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
To install FoliaFlow, follow these steps:
|
To install FoliaFlow, follow these steps:
|
||||||
|
|
||||||
1. Download the plugin JAR file from the [Modrinth](https://modrinth.com/plugin/foliaflow).
|
1. Download the plugin JAR file from the [releases page](https://github.com/Hynse/FoliaFlow/releases).
|
||||||
2. Copy the JAR file to the `plugins` folder of your Minecraft server.
|
2. Copy the JAR file to the `plugins` folder of your Minecraft server.
|
||||||
3. Restart your server to load the plugin.
|
3. Restart your server to enable the plugin.
|
||||||
|
|
||||||
## Config flies (config.yml)
|
|
||||||
```yml
|
|
||||||
# Don't touch this file unless you know what you're doing
|
|
||||||
# Default values seems vanilla.
|
|
||||||
# If you find values that seems more vanilla please create a PR
|
|
||||||
# https://github.com/Hynse/FoliaFlow
|
|
||||||
|
|
||||||
# Default value for horizontal_coefficient
|
|
||||||
# - Folia (1.499)
|
|
||||||
# - Paper (2)
|
|
||||||
horizontal_coefficient: 1.499
|
|
||||||
# -----------------------------------------
|
|
||||||
|
|
||||||
vertical_coefficient: -1.7
|
|
||||||
spawn_height: 0.08
|
|
||||||
|
|
||||||
# Default value for teleport_offset
|
|
||||||
# - Folia (0.5)
|
|
||||||
# - Paper (2.4)
|
|
||||||
teleport_offset: 0.5
|
|
||||||
# -----------------------------------------
|
|
||||||
```
|
|
||||||
|
|
||||||
## Permissions
|
|
||||||
`foliaflow.reload` for using command `/flowreload` to reload config flies
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
|
|
||||||
10
build.gradle
10
build.gradle
|
|
@ -2,8 +2,10 @@ plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def loader = 'folia'
|
||||||
|
def server = '1.19.4'
|
||||||
group = 'xyz.hynse'
|
group = 'xyz.hynse'
|
||||||
version = "3.0"
|
version = "1.5-${server}-${loader}"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
|
@ -11,10 +13,14 @@ repositories {
|
||||||
name = "papermc-repo"
|
name = "papermc-repo"
|
||||||
url = "https://repo.papermc.io/repository/maven-public/"
|
url = "https://repo.papermc.io/repository/maven-public/"
|
||||||
}
|
}
|
||||||
|
maven {
|
||||||
|
name = "sonatype"
|
||||||
|
url = "https://oss.sonatype.org/content/groups/public/"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly "dev.folia:folia-api:1.20.4-R0.1-SNAPSHOT"
|
compileOnly "dev.folia:folia-api:1.19.4-R0.1-SNAPSHOT"
|
||||||
}
|
}
|
||||||
|
|
||||||
def targetJavaVersion = 17
|
def targetJavaVersion = 17
|
||||||
|
|
|
||||||
0
gradlew
vendored
Executable file → Normal file
0
gradlew
vendored
Executable file → Normal file
|
|
@ -1,73 +1,154 @@
|
||||||
package xyz.hynse.foliaflow;
|
package xyz.hynse.foliaflow;
|
||||||
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import io.papermc.paper.threadedregions.scheduler.AsyncScheduler;
|
||||||
|
import io.papermc.paper.threadedregions.scheduler.GlobalRegionScheduler;
|
||||||
|
import io.papermc.paper.threadedregions.scheduler.RegionScheduler;
|
||||||
|
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.data.type.Slab;
|
||||||
|
import org.bukkit.command.CommandException;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.entity.FallingBlock;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import xyz.hynse.foliaflow.command.ReloadCommand;
|
import java.util.*;
|
||||||
import xyz.hynse.foliaflow.util.CheckSafeTeleportation;
|
import java.util.concurrent.TimeUnit;
|
||||||
import xyz.hynse.foliaflow.watcher.PortalWatcher;
|
|
||||||
|
|
||||||
import java.io.File;
|
import static org.bukkit.Bukkit.getScheduler;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
|
|
||||||
public class FoliaFlow extends JavaPlugin {
|
public class FoliaFlow extends JavaPlugin implements Listener {
|
||||||
private boolean isFirstEnable = true;
|
private final double vh = 0.2;
|
||||||
//public boolean isUnSafeTeleport = false;
|
private final double vt = 0.8;
|
||||||
public static FoliaFlow instance;
|
private final Vector velocity1 = new Vector(0, vh, vt);
|
||||||
public static double horizontalCoefficient;
|
private final Vector velocity2 = new Vector(vt, vh, 0);
|
||||||
public static double verticalCoefficient;
|
private final Vector velocity3 = new Vector(0, vh, -vt);
|
||||||
public static double spawnHeight;
|
private final Vector velocity4 = new Vector(-vt, vh, 0);
|
||||||
public static double TeleportOffset;
|
|
||||||
//public static CheckSafeTeleportation checkSafeTeleportation;
|
private final Vector[] velocities = {velocity1, velocity2, velocity3, velocity4};
|
||||||
|
private int counter = 0;
|
||||||
|
private final Set<Location> movingBlocks = new HashSet<>();
|
||||||
|
private final Map<Entity, Vector> velocitiesMap = new HashMap<>();
|
||||||
|
private ScheduledTask task;
|
||||||
|
private ScheduledTask blockktask;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
instance = this;
|
super.onEnable();
|
||||||
register();
|
|
||||||
if (isFirstEnable) {
|
|
||||||
isFirstEnable = false;
|
|
||||||
copyDefaultConfig();
|
|
||||||
setInitialConfigValues();
|
|
||||||
}
|
|
||||||
reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void copyDefaultConfig() {
|
|
||||||
File configFile = new File(getDataFolder(), "config.yml");
|
|
||||||
if (!configFile.exists()) {
|
|
||||||
saveResource("config.yml", false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setInitialConfigValues() {
|
|
||||||
File configFile = new File(getDataFolder(), "config.yml");
|
|
||||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
|
|
||||||
InputStream defaultConfigStream = getResource("config.yml");
|
|
||||||
YamlConfiguration defaultConfig = YamlConfiguration.loadConfiguration(new InputStreamReader(defaultConfigStream));
|
|
||||||
config.options().copyDefaults(true);
|
|
||||||
config.setDefaults(defaultConfig);
|
|
||||||
try {
|
try {
|
||||||
config.save(configFile);
|
RegionScheduler schedulerblock = getServer().getRegionScheduler();
|
||||||
} catch (IOException e) {
|
blockktask = schedulerblock.runAtFixedRate(this, Objects.requireNonNull(Bukkit.getWorld("world_the_end")), 1, 1, (schedulerTask) -> {
|
||||||
e.printStackTrace();
|
Block block = Objects.requireNonNull(Bukkit.getWorld("world_the_end")).getBlockAt(100, 48, 0);
|
||||||
|
if (block.getType() == Material.OBSIDIAN) {
|
||||||
|
block.setType(Material.COBBLED_DEEPSLATE_SLAB);
|
||||||
|
Slab slab = (Slab) block.getBlockData();
|
||||||
|
slab.setType(Slab.Type.BOTTOM);
|
||||||
|
block.setBlockData(slab);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}, 1L, 1L);
|
||||||
|
} catch (NullPointerException block) {
|
||||||
|
getServer().getLogger().info("Region Scheduler erorr (likly chunky it not load)");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
AsyncScheduler scheduler = getServer().getAsyncScheduler();
|
||||||
|
task = scheduler.runAtFixedRate(this, (scheduledTask) -> getScheduler().runTask(this, () -> {
|
||||||
|
for (World world : Bukkit.getWorlds()) {
|
||||||
|
for (Entity entity : world.getEntities()) {
|
||||||
|
if (entity.getType() == EntityType.FALLING_BLOCK && entity.getWorld().getEnvironment() == World.Environment.THE_END) {
|
||||||
|
Location centerLoc = new Location(entity.getWorld(), 100, 48.5, 0);
|
||||||
|
Location loc = entity.getLocation();
|
||||||
|
if (loc.distance(centerLoc) <= 1) {
|
||||||
|
if (!velocitiesMap.containsKey(entity)) {
|
||||||
|
int index = counter % 4;
|
||||||
|
counter++;
|
||||||
|
Vector velocity = velocities[index];
|
||||||
|
entity.setVelocity(velocity);
|
||||||
|
velocitiesMap.put(entity, velocity);
|
||||||
|
movingBlocks.add(entity.getLocation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}), 0L, 1L, TimeUnit.MILLISECONDS);
|
||||||
|
} catch (UnsupportedOperationException ignored) {
|
||||||
|
}
|
||||||
|
getServer().getPluginManager().registerEvents(this, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
try {
|
||||||
|
task.cancel();
|
||||||
|
blockktask.cancel();
|
||||||
|
} catch (UnsupportedOperationException ignored) {
|
||||||
|
}
|
||||||
|
super.onDisable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onFallingBlockToBlock(EntityChangeBlockEvent e){
|
||||||
|
if(e.getEntityType() == EntityType.FALLING_BLOCK){
|
||||||
|
Entity entity = e.getEntity();
|
||||||
|
Location loc = entity.getLocation();
|
||||||
|
Vector vel = entity.getVelocity();
|
||||||
|
Block movingTo = getBlockMovingTo(loc, vel);
|
||||||
|
try {
|
||||||
|
|
||||||
|
if(movingTo != null && movingTo.getType() == Material.END_PORTAL){
|
||||||
|
Location spawnLoc = movingTo.getLocation();
|
||||||
|
spawnLoc.setX(spawnLoc.getX()+0.5);
|
||||||
|
spawnLoc.setY(spawnLoc.getY()-0.25);
|
||||||
|
spawnLoc.setZ(spawnLoc.getZ()+0.5);
|
||||||
|
|
||||||
|
FallingBlock dummy = loc.getWorld().spawnFallingBlock(spawnLoc, ((FallingBlock) entity).getBlockData());
|
||||||
|
dummy.setDropItem(true);
|
||||||
|
dummy.setHurtEntities(true);
|
||||||
|
dummy.setGravity(true);
|
||||||
|
Vector dummyVel = vel.clone();
|
||||||
|
dummyVel.setY(-dummyVel.getY());
|
||||||
|
dummyVel.multiply(new Vector(2, 1, 2));
|
||||||
|
|
||||||
|
dummyVel.add(new Vector(0, 1, 0));
|
||||||
|
|
||||||
|
dummy.setVelocity(dummyVel);
|
||||||
|
}
|
||||||
|
} catch (NullPointerException dummy) {
|
||||||
|
getServer().getLogger().info("onFallingBlockToBlock erorr (likly chunky it not load)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reload() {
|
Block getBlockMovingTo(Location loc, Vector vel) {
|
||||||
saveDefaultConfig();
|
double absMax = 0, max = 0;
|
||||||
reloadConfig();
|
char dir = ' ';
|
||||||
horizontalCoefficient = getConfig().getDouble("horizontal_coefficient");
|
Block relative = null;
|
||||||
verticalCoefficient = getConfig().getDouble("vertical_coefficient");
|
if (Math.abs(vel.getX()) > absMax) {
|
||||||
spawnHeight = getConfig().getDouble("spawn_height");
|
max = vel.getX();
|
||||||
TeleportOffset = getConfig().getDouble("teleport_offset");
|
absMax = Math.abs(vel.getX());
|
||||||
|
dir = 'x';
|
||||||
|
}
|
||||||
|
if (Math.abs(vel.getY()) > absMax) {
|
||||||
|
max = vel.getY();
|
||||||
|
absMax = Math.abs(vel.getY());
|
||||||
|
dir = 'y';
|
||||||
|
}
|
||||||
|
if (Math.abs(vel.getZ()) > absMax) {
|
||||||
|
max = vel.getZ();
|
||||||
|
dir = 'z';
|
||||||
|
}
|
||||||
|
switch (dir) {
|
||||||
|
case 'x' -> relative = loc.getBlock().getRelative((int) Math.signum(max), 0, 0);
|
||||||
|
case 'y' -> relative = loc.getBlock().getRelative(0, (int) Math.signum(max), 0);
|
||||||
|
case 'z' -> relative = loc.getBlock().getRelative(0, 0, (int) Math.signum(max));
|
||||||
|
}
|
||||||
|
return relative;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private void register() {
|
|
||||||
getCommand("flowreload").setExecutor(new ReloadCommand());
|
|
||||||
// checkSafeTeleportation = new CheckSafeTeleportation();
|
|
||||||
// checkSafeTeleportation.updateSafeTeleportation();
|
|
||||||
getServer().getPluginManager().registerEvents(new PortalWatcher(), this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
package xyz.hynse.foliaflow.command;
|
|
||||||
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandExecutor;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
|
|
||||||
import xyz.hynse.foliaflow.FoliaFlow;
|
|
||||||
|
|
||||||
public class ReloadCommand implements CommandExecutor {
|
|
||||||
@Override
|
|
||||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
|
||||||
if (!sender.hasPermission("foliaflow.reload")) return true;
|
|
||||||
try {
|
|
||||||
FoliaFlow.instance.reload();
|
|
||||||
sender.sendMessage(ChatColor.YELLOW + "FoliaFlow reloaded.");
|
|
||||||
} catch (Exception e) {
|
|
||||||
sender.sendMessage(ChatColor.RED + "Something went wrong reloading FoliaFlow, see the console for more.");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
package xyz.hynse.foliaflow.util;
|
|
||||||
|
|
||||||
import org.yaml.snakeyaml.Yaml;
|
|
||||||
import xyz.hynse.foliaflow.FoliaFlow;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.bukkit.Bukkit.getServer;
|
|
||||||
|
|
||||||
public class CheckSafeTeleportation {
|
|
||||||
|
|
||||||
public boolean checkUnsafeEndPortalTeleportation() {
|
|
||||||
File configFile = new File(getServer().getWorldContainer(), "config/paper-global.yml");
|
|
||||||
if (!configFile.exists()) {
|
|
||||||
FoliaFlow.instance.getLogger().warning("paper-global.yml not found!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try (FileInputStream fis = new FileInputStream(configFile)) {
|
|
||||||
Yaml yaml = new Yaml();
|
|
||||||
Map<String, Object> config = yaml.load(fis);
|
|
||||||
|
|
||||||
Map<String, Object> unsupportedSettings = (Map<String, Object>) config.get("unsupported-settings");
|
|
||||||
if (unsupportedSettings != null) {
|
|
||||||
Boolean setting = (Boolean) unsupportedSettings.get("allow-unsafe-end-portal-teleportation");
|
|
||||||
return setting != null && setting;
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
FoliaFlow.instance.getLogger().severe("Failed to read paper-global.yml: " + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// public void updateSafeTeleportation() {
|
|
||||||
// boolean safeTeleportation = checkUnsafeEndPortalTeleportation();
|
|
||||||
// if (safeTeleportation) {
|
|
||||||
// FoliaFlow.instance.isUnSafeTeleport = true;
|
|
||||||
// FoliaFlow.instance.getLogger().info("Unsafe End Portal Teleportation is true.");
|
|
||||||
// } else {
|
|
||||||
// FoliaFlow.instance.isUnSafeTeleport = false;
|
|
||||||
// FoliaFlow.instance.getLogger().info("Unsafe End Portal Teleportation is false.");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
package xyz.hynse.foliaflow.util;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
|
|
||||||
public class SchedulerUtil {
|
|
||||||
|
|
||||||
private static Boolean IS_FOLIA = null;
|
|
||||||
|
|
||||||
private static boolean tryFolia() {
|
|
||||||
try {
|
|
||||||
Class.forName("io.papermc.paper.threadedregions.RegionizedServer");
|
|
||||||
return true;
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean isFolia() {
|
|
||||||
if (IS_FOLIA == null) IS_FOLIA = tryFolia();
|
|
||||||
return IS_FOLIA;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void runLaterEntity(Entity entity, Plugin plugin, Runnable runnable, int ticks) {
|
|
||||||
if (isFolia()) {
|
|
||||||
entity.getScheduler().runDelayed(plugin, (task) -> runnable.run(), null, ticks);
|
|
||||||
} else {
|
|
||||||
Bukkit.getScheduler().runTaskLater(plugin, runnable, ticks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
package xyz.hynse.foliaflow.util;
|
|
||||||
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
public class VelocityUtil {
|
|
||||||
public static Block getBlockMovingTo(Location loc, Vector vel) {
|
|
||||||
double absX = Math.abs(vel.getX());
|
|
||||||
double absY = Math.abs(vel.getY());
|
|
||||||
double absZ = Math.abs(vel.getZ());
|
|
||||||
if (absX > absY && absX > absZ) {
|
|
||||||
return loc.getBlock().getRelative((int) Math.signum(vel.getX()), 0, 0);
|
|
||||||
} else if (absY > absZ) {
|
|
||||||
return loc.getBlock().getRelative(0, (int) Math.signum(vel.getY()), 0);
|
|
||||||
}
|
|
||||||
return loc.getBlock().getRelative(0, 0, (int) Math.signum(vel.getZ()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
package xyz.hynse.foliaflow.watcher;
|
|
||||||
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.entity.FallingBlock;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
|
||||||
import org.bukkit.event.entity.EntityPortalEnterEvent;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import xyz.hynse.foliaflow.FoliaFlow;
|
|
||||||
import xyz.hynse.foliaflow.util.SchedulerUtil;
|
|
||||||
|
|
||||||
import static xyz.hynse.foliaflow.util.VelocityUtil.getBlockMovingTo;
|
|
||||||
|
|
||||||
public class PortalWatcher implements Listener {
|
|
||||||
|
|
||||||
private static final String DUPE_TAG = "foliaflow_dupe";
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onFallingBlockToBlock(EntityChangeBlockEvent e){
|
|
||||||
if(e.getEntityType() != EntityType.FALLING_BLOCK) return;
|
|
||||||
Entity entity = e.getEntity();
|
|
||||||
if(entity.getScoreboardTags().contains(DUPE_TAG)) return;
|
|
||||||
Location loc = entity.getLocation();
|
|
||||||
Vector vel = entity.getVelocity();
|
|
||||||
Block movingTo = getBlockMovingTo(loc, vel);
|
|
||||||
|
|
||||||
if(movingTo.getType() == Material.END_PORTAL){
|
|
||||||
spawnDupe(entity, movingTo, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPortalEnter(EntityPortalEnterEvent e){
|
|
||||||
if(e.getEntityType() != EntityType.FALLING_BLOCK) return;
|
|
||||||
Entity entity = e.getEntity();
|
|
||||||
if(entity.getScoreboardTags().contains(DUPE_TAG)) return;
|
|
||||||
Block portal = e.getLocation().getBlock();
|
|
||||||
|
|
||||||
if(portal.getType() == Material.END_PORTAL && portal.getRelative(0, -1, 0).getType().name().endsWith("_FENCE")){
|
|
||||||
spawnDupe(entity, portal, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void spawnDupe(Entity entity, Block portal, boolean passThrough){
|
|
||||||
Location spawnLoc = portal.getLocation();
|
|
||||||
spawnLoc.add(0.5, FoliaFlow.spawnHeight, 0.5);
|
|
||||||
|
|
||||||
FallingBlock dummy = entity.getWorld().spawnFallingBlock(spawnLoc, ((FallingBlock) entity).getBlockData());
|
|
||||||
dummy.addScoreboardTag(DUPE_TAG);
|
|
||||||
Vector dummyVel = entity.getVelocity().clone();
|
|
||||||
dummyVel.multiply(FoliaFlow.horizontalCoefficient);
|
|
||||||
if(passThrough){
|
|
||||||
dummyVel.setY(entity.getVelocity().getY());
|
|
||||||
} else {
|
|
||||||
dummyVel.setY(entity.getVelocity().getY() * FoliaFlow.verticalCoefficient);
|
|
||||||
}
|
|
||||||
dummy.setVelocity(dummyVel);
|
|
||||||
|
|
||||||
SchedulerUtil.runLaterEntity(dummy, FoliaFlow.instance, () -> {
|
|
||||||
// Portal teleportation is a bit below vanilla, so we teleport it above
|
|
||||||
dummy.teleportAsync(dummy.getLocation().add(0, FoliaFlow.TeleportOffset, 0));
|
|
||||||
dummy.setVelocity(dummyVel);
|
|
||||||
},
|
|
||||||
2
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
# Don't touch this file unless you know what you're doing
|
|
||||||
# Default values seems vanilla.
|
|
||||||
# If you find values that seems more vanilla please create a PR
|
|
||||||
# https://github.com/Hynse/FoliaFlow
|
|
||||||
|
|
||||||
# Default value for horizontal_coefficient
|
|
||||||
# - Folia (1.499)
|
|
||||||
# - Paper (2)
|
|
||||||
horizontal_coefficient: 1.499
|
|
||||||
# -----------------------------------------
|
|
||||||
|
|
||||||
vertical_coefficient: -1.7
|
|
||||||
spawn_height: 0.08
|
|
||||||
|
|
||||||
# Default value for teleport_offset
|
|
||||||
# - Folia (0.5)
|
|
||||||
# - Paper (2.4)
|
|
||||||
teleport_offset: 0.5
|
|
||||||
# -----------------------------------------
|
|
||||||
5
src/main/resources/paper-plugin.yml
Normal file
5
src/main/resources/paper-plugin.yml
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
name: FoliaFlow
|
||||||
|
version: '${version}'
|
||||||
|
main: xyz.hynse.foliaflow.FoliaFlow
|
||||||
|
api-version: 1.19
|
||||||
|
folia-supported: true
|
||||||
|
|
@ -1,10 +1,5 @@
|
||||||
name: FoliaFlow
|
name: FoliaFlow
|
||||||
version: '${version}'
|
version: '${version}'
|
||||||
main: xyz.hynse.foliaflow.FoliaFlow
|
main: xyz.hynse.foliaflow.FoliaFlow
|
||||||
api-version: 26.1.2
|
api-version: 1.19
|
||||||
folia-supported: true
|
folia-supported: true
|
||||||
commands:
|
|
||||||
flowreload:
|
|
||||||
description: Reload FoliaFlow
|
|
||||||
usage: /<command>
|
|
||||||
permission: foliaflow.reload
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue