Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 32 additions & 13 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
name: Publish

on:
release:
types: [ published ]
push:
tags:
- "*.*.*"

jobs:
publish:
env:
TAG: ${{ github.ref_name }}
name: Publish
runs-on: ubuntu-latest
permissions:
Expand All @@ -22,36 +25,52 @@ jobs:
distribution: 'temurin'
cache: maven

- name: Verify Release Notes Exist
run: test -f "docs/release-notes/$TAG.md"

- name: Set version from release tag
run: mvn -B versions:set -DnewVersion=${{ github.event.release.tag_name }} -DgenerateBackupPoms=false
run: mvn -B versions:set -DnewVersion=$TAG -DgenerateBackupPoms=false

- name: Build and package with Maven
run: mvn -B clean package --file pom.xml

- name: Upload to GitHub Release
- name: Create GitHub Release
env:
GH_TOKEN: ${{secrets.GITHUB_TOKEN}}
run: |
TAG="${{ github.event.release.tag_name }}"

gh release upload "$TAG" \
gh release create "$TAG" \
"plugin/target/displayentityutils-$TAG.jar" \
--clobber
--verify-tag \
--title "DEU $TAG" \
--notes-file "docs/release-notes/$TAG.md" \
--generate-notes

- name: Get Release body
id: release_notes
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
{
echo "body<<RELEASE_BODY"
gh release view "$TAG" --json body --jq '.body'
echo "RELEASE_BODY"
} >> "$GITHUB_OUTPUT"

- name: Upload to Modrinth
uses: cloudnode-pro/modrinth-publish@v2
with:
token: ${{ secrets.MODRINTH_TOKEN }}
project: ${{ vars.MODRINTH_ID }}
name: ${{ github.event.release.name }}
version: ${{ github.event.release.tag_name }}
changelog: ${{ github.event.release.body }}
name: DEU ${{ env.TAG }}
version: ${{ env.TAG }}
changelog: ${{ steps.release_notes.outputs.body }}
loaders: |-
paper
game-versions: |-
1.20.x
1.20.4
1.20.5
1.20.6
1.21.x
26.1.x
26.2
files: plugin/target/displayentityutils-${{ github.event.release.tag_name }}.jar
files: plugin/target/displayentityutils-${{ env.TAG }}.jar
2 changes: 1 addition & 1 deletion api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>net.donnypz.displayentityutils</groupId>
<artifactId>deu</artifactId>
<version>3.6.0</version>
<version>3.7.0</version>
</parent>

<artifactId>api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
package net.donnypz.displayentityutils;

import org.bukkit.NamespacedKey;
import org.jetbrains.annotations.ApiStatus;

@ApiStatus.Internal
public final class DisplayKeys {

private DisplayKeys(){}

public static final class Group{
public static final NamespacedKey GROUP_TAG = new NamespacedKey(DisplayAPI.getPlugin(), "groupTag");
public static final NamespacedKey CHUNK_PACKET_GROUP = new NamespacedKey(DisplayAPI.getPlugin(), "chunkpacketgroups");
public static final NamespacedKey GROUP_ROTATION = new NamespacedKey(DisplayAPI.getPlugin(), "group_rotation");
public static final NamespacedKey CREATION_TIME = new NamespacedKey(DisplayAPI.getPlugin(), "creationtime");
public static final NamespacedKey SCALE_MULTIPLIER = new NamespacedKey(DisplayAPI.getPlugin(), "scale");
public static final NamespacedKey PERSISTENCE_OVERRIDE = new NamespacedKey(DisplayAPI.getPlugin(), "persistence_override");
}

public static final class Part{
Expand Down
57 changes: 57 additions & 0 deletions api/src/main/java/net/donnypz/displayentityutils/utils/Axis.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package net.donnypz.displayentityutils.utils;

import org.jetbrains.annotations.NotNull;
import org.joml.Quaternionf;

public enum Axis {
X,
Y,
Z;

/**
* Rotate a quaternion on this {@link Axis}'s axis
* @param quaternionf the quaternion
* @param angleInDegrees the angle in degrees
* @return a new {@link Quaternionf} with the rotation applied
*/
public @NotNull Quaternionf rotate(@NotNull Quaternionf quaternionf, float angleInDegrees){
Quaternionf newRot = new Quaternionf(quaternionf);
float angleDeg = (float) Math.toRadians(angleInDegrees);
switch(this){
case X -> newRot.rotateX(angleDeg);
case Y -> newRot.rotateY(angleDeg);
case Z -> newRot.rotateZ(angleDeg);
}
return newRot;
}

/**
* Set a quaternion's axis to a given angle
* @param quaternionf the quaternion
* @param angleInDegrees the angle in degrees
* @return a new {@link Quaternionf} with the axis representative of this set
*/
public @NotNull Quaternionf set(@NotNull Quaternionf quaternionf, float angleInDegrees){
float angleRad = (float) Math.toRadians(angleInDegrees);

Quaternionf q = new Quaternionf();
switch (this){
case X -> {
q.rotateX(angleRad);
q.rotateY(quaternionf.y);
q.rotateZ(quaternionf.z);
}
case Y -> {
q.rotateX(quaternionf.x);
q.rotateY(angleRad);
q.rotateZ(quaternionf.z);
}
case Z -> {
q.rotateX(quaternionf.x);
q.rotateY(quaternionf.y);
q.rotateZ(angleRad);
}
}
return q;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package net.donnypz.displayentityutils.utils.DisplayEntities;

import net.donnypz.displayentityutils.utils.Direction;
import net.donnypz.displayentityutils.utils.PivotAxis;
import net.donnypz.displayentityutils.utils.Axis;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.entity.Display;
Expand Down Expand Up @@ -60,18 +60,18 @@ public interface Active {

void setYaw(float yaw, boolean pivot);

default void setRotation(float pitch, float yaw){
setRotation(pitch, yaw, false, false);
default void setEntityRotation(float pitch, float yaw){
setEntityRotation(pitch, yaw, false, false);
}

void setRotation(float pitch, float yaw, boolean pivotPitch, boolean pivotYaw);
void setEntityRotation(float pitch, float yaw, boolean pivotPitch, boolean pivotYaw);

/**
* @param angleInDegrees the pivot angle
* @param pivotAxis the axis to perform the pivot on
* @param axis the axis to perform the pivot on
* @param worldSpace whether the pivot should occur on world space axis
*/
void pivot(float angleInDegrees, @NotNull PivotAxis pivotAxis, boolean worldSpace);
void pivot(float angleInDegrees, @NotNull Axis axis, boolean worldSpace);

/**
* @param rotation the rotation
Expand All @@ -80,6 +80,18 @@ default void setRotation(float pitch, float yaw){
*/
void pivot(@NotNull Quaternionf rotation, @NotNull Location pivotLocation, boolean worldSpace);

/**
* Rotate display transformation
* @param angleInDegrees the rotation angle
* @param axis the axis to rotate on
* @param worldSpace whether the rotation should occur on world space axis
*/
default void rotate(float angleInDegrees, @NotNull Axis axis, boolean worldSpace){
Quaternionf q = new Quaternionf();
axis.rotate(q, angleInDegrees);
this.rotate(q, worldSpace);
}

/**
* @param rotation the rotation
* @param worldSpace whether the rotation should occur on world space axis
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@
import net.donnypz.displayentityutils.managers.DEUUser;
import net.donnypz.displayentityutils.managers.DisplayAnimationManager;
import net.donnypz.displayentityutils.managers.LoadMethod;
import net.donnypz.displayentityutils.utils.Direction;
import net.donnypz.displayentityutils.utils.*;
import net.donnypz.displayentityutils.utils.DisplayEntities.concurrent.GroupTeleportCompletableFuture;
import net.donnypz.displayentityutils.utils.DisplayEntities.machine.DisplayStateMachine;
import net.donnypz.displayentityutils.utils.DisplayEntities.machine.MachineState;
import net.donnypz.displayentityutils.utils.FollowType;
import net.donnypz.displayentityutils.utils.PacketUtils;
import net.donnypz.displayentityutils.utils.controller.GroupFollowProperties;
import org.bukkit.Bukkit;
import org.bukkit.Color;
Expand All @@ -23,8 +21,10 @@
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.joml.Quaternionf;
import org.joml.Vector3f;

import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
Expand All @@ -49,13 +49,13 @@ public abstract class ActiveGroup<T extends ActivePart> extends ActivePartHolder

protected MachineState currentMachineState;

protected Quaternionf rotation = new Quaternionf();
private volatile float scaleMultiplier = 1;
private volatile Vector rideOffset = new Vector();
private volatile int lastAnimatedTick = -1;

private boolean isSelectable = true;


/**
* Get this group's unique ID created during the current game session
* @return the group's ID
Expand Down Expand Up @@ -175,6 +175,111 @@ public void removeCulling(){
}
}

/**
* Set the transformation rotation of this group, optionally pivoting non-display entities as well
* @param axis the axis to rotate on
* @param pivotNonDisplays whether non-displays should be pivoted
*/
public void setRotation(float angleInDegrees, @NotNull Axis axis, boolean pivotNonDisplays){
Quaternionf newRotation = new Quaternionf(this.rotation);
newRotation = axis.set(newRotation, angleInDegrees);
setRotation(newRotation, pivotNonDisplays);
}

/**
* Set the transformation rotation of this group, optionally pivoting non-display entities as well
* @param rotation the local space rotation to set the group's orientation to
* @param pivotNonDisplays whether non-displays should be pivoted
*/
public void setRotation(@NotNull Quaternionf rotation, boolean pivotNonDisplays){
Quaternionf delta = new Quaternionf(this.rotation)
.invert()
.mul(rotation);

this.rotate(delta, false);

if (pivotNonDisplays){
this.pivot(delta, getLocation(), false);
}
}

@Override
public void rotateAround(@NotNull Quaternionf rotation, @NotNull Location pivotLocation, boolean worldSpace) {
if (!worldSpace) {
this.rotation.mul(rotation);
} else {
Location groupLoc = getLocation();
Quaternionf worldSpaceRot = MathUtils.applyWorldSpaceRotation(rotation, groupLoc.getPitch(), groupLoc.getYaw());
worldSpaceRot.mul(this.rotation, this.rotation);
}
super.rotateAround(rotation, pivotLocation, worldSpace);
this.saveGroupRotation();
}

@Override
public void pivotOrRotateAround(@NotNull Quaternionf rotation, @NotNull Location pivotLocation, boolean worldSpace) {
if (!worldSpace) {
this.rotation.mul(rotation);
} else {
Location groupLoc = getLocation();
Quaternionf worldSpaceRot = MathUtils.applyWorldSpaceRotation(rotation, groupLoc.getPitch(), groupLoc.getYaw());
worldSpaceRot.mul(this.rotation, this.rotation);
}
super.pivotOrRotateAround(rotation, pivotLocation, worldSpace);
this.saveGroupRotation();
}

protected abstract void saveGroupRotation();

protected static byte @NotNull[] getRotationByteArray(@NotNull Quaternionf rotation){
Quaternionf q = new Quaternionf(rotation);

ByteBuffer buf = ByteBuffer.allocate(16); //4 bytes per quaternion val
buf.putFloat(q.x);
buf.putFloat(q.y);
buf.putFloat(q.z);
buf.putFloat(q.w);
return buf.array();
}

protected @NotNull Quaternionf getRotation(byte[] quaternionBytes){
if (quaternionBytes == null || quaternionBytes.length != 16) return new Quaternionf();

ByteBuffer buf = ByteBuffer.wrap(quaternionBytes);
return new Quaternionf(
buf.getFloat(),
buf.getFloat(),
buf.getFloat(),
buf.getFloat()
);
}

protected void setRotation(PersistentDataContainer pdc){
byte[] rotation = pdc.get(DisplayKeys.Group.GROUP_ROTATION, PersistentDataType.BYTE_ARRAY);
this.rotation = getRotation(rotation);
}


public @NotNull Quaternionf getRotation(){
return new Quaternionf(this.rotation);
}

/**
* Reset the group's rotation to its default orientation
* @param pivotNonDisplays whether non-displays should be pivoted
*/
public void resetRotation(boolean pivotNonDisplays){
setRotation(new Quaternionf(), pivotNonDisplays);
}

/**
* Make the group's current rotation its default orientation, resetting the group's
* stored rotation but retaining the current orientation
*/
public void rebaseRotation(){
this.rotation = new Quaternionf();
}

/**
* Change the scale of all parts in this group by the given scale multiplier
* @param newScaleMultiplier the scale multiplier to apply to this group
Expand Down
Loading
Loading