wip: cinematic system
This commit is contained in:
parent
41ae6a2572
commit
05d32c63f5
9 changed files with 289 additions and 8 deletions
|
@ -1,5 +1,8 @@
|
|||
package me.unurled.sacredrealms.sr.components.cutscene;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import me.unurled.sacredrealms.sr.SR;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.recording.Recording;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.tasks.ReplayTask;
|
||||
|
@ -12,10 +15,12 @@ public class Replay {
|
|||
private final Player viewer;
|
||||
private final Recording recording;
|
||||
private final BukkitTask replayTask;
|
||||
private final Map<UUID, Integer> spawnedEntities;
|
||||
|
||||
public Replay(Recording recording, @NotNull Player viewer) {
|
||||
this.recording = recording;
|
||||
this.viewer = viewer;
|
||||
spawnedEntities = new HashMap<>();
|
||||
|
||||
viewer.getInventory().clear();
|
||||
// TODO: control cutscene replay
|
||||
|
@ -42,4 +47,8 @@ public class Replay {
|
|||
replayTask.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
public Map<UUID, Integer> spawnedEntities() {
|
||||
return spawnedEntities;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package me.unurled.sacredrealms.sr.components.cutscene.recording;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.Replay;
|
||||
|
||||
public abstract class Recordable {
|
||||
private long tick;
|
||||
|
||||
public abstract void replay();
|
||||
public abstract void replay(Replay replay, User user) throws Exception;
|
||||
|
||||
public long tick() {
|
||||
return tick;
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
package me.unurled.sacredrealms.sr.components.cutscene.recording.recordables;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDestroyEntities;
|
||||
import java.util.UUID;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.Replay;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.recording.Recordable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class DespawnEntityRecordable extends Recordable {
|
||||
|
||||
|
@ -14,8 +18,11 @@ public class DespawnEntityRecordable extends Recordable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void replay() {
|
||||
// TODO: fake spawn entity
|
||||
public void replay(@NotNull Replay replay, @NotNull User user) throws Exception {
|
||||
WrapperPlayServerDestroyEntities destroyEntities =
|
||||
new WrapperPlayServerDestroyEntities(replay.spawnedEntities().get(entityId));
|
||||
user.sendPacket(destroyEntities);
|
||||
replay.spawnedEntities().remove(entityId);
|
||||
}
|
||||
|
||||
public UUID entityId() {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package me.unurled.sacredrealms.sr.components.cutscene.recording.recordables;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import java.util.UUID;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.Replay;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.recording.Recordable;
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
@ -17,7 +19,7 @@ public class LocationChangeRecordable extends Recordable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void replay() {}
|
||||
public void replay(Replay replay, User user) throws Exception {}
|
||||
|
||||
public UUID entityId() {
|
||||
return entityId;
|
||||
|
|
|
@ -1,8 +1,20 @@
|
|||
package me.unurled.sacredrealms.sr.components.cutscene.recording.recordables;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import com.github.retrooper.packetevents.protocol.player.UserProfile;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnEntity;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnPlayer;
|
||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.EnumSet;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.Replay;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.recording.Recordable;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
@ -33,8 +45,49 @@ public class SpawnEntityRecordable extends Recordable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void replay() {
|
||||
// TODO: fake spawn entity
|
||||
public void replay(Replay replay, User user) throws Exception { // TODO: check everything
|
||||
|
||||
Class<?> entityClass = Class.forName("net.minecraft.world.entity.Entity");
|
||||
Field field = entityClass.getDeclaredField("ENTITY_COUNTER");
|
||||
field.setAccessible(true);
|
||||
AtomicInteger ENTITY_COUNTER = (AtomicInteger) field.get(null);
|
||||
int id = ENTITY_COUNTER.incrementAndGet();
|
||||
|
||||
if (entityType == EntityType.PLAYER) {
|
||||
WrapperPlayServerPlayerInfoUpdate.PlayerInfo data =
|
||||
new WrapperPlayServerPlayerInfoUpdate.PlayerInfo(
|
||||
new UserProfile(entityId, name.toString()),
|
||||
false,
|
||||
0,
|
||||
SpigotConversionUtil.fromBukkitGameMode(GameMode.SURVIVAL),
|
||||
name,
|
||||
null);
|
||||
|
||||
user.sendPacket(
|
||||
new WrapperPlayServerPlayerInfoUpdate(
|
||||
EnumSet.of(WrapperPlayServerPlayerInfoUpdate.Action.ADD_PLAYER), data));
|
||||
user.sendPacket(
|
||||
new WrapperPlayServerSpawnPlayer(
|
||||
id, entityId, SpigotConversionUtil.fromBukkitLocation(location)));
|
||||
|
||||
replay.spawnedEntities().put(entityId, id);
|
||||
} else {
|
||||
com.github.retrooper.packetevents.protocol.entity.type.EntityType entityType1 =
|
||||
EntityTypes.getByName(entityType.getKey().toString());
|
||||
|
||||
WrapperPlayServerSpawnEntity spawnEntityPacket =
|
||||
new WrapperPlayServerSpawnEntity(
|
||||
id,
|
||||
UUID.randomUUID(),
|
||||
entityType1,
|
||||
SpigotConversionUtil.fromBukkitLocation(location),
|
||||
0,
|
||||
0,
|
||||
null);
|
||||
|
||||
user.sendPacket(spawnEntityPacket);
|
||||
replay.spawnedEntities().put(entityId, id);
|
||||
}
|
||||
}
|
||||
|
||||
public EntityType entityType() {
|
||||
|
|
|
@ -3,20 +3,25 @@ package me.unurled.sacredrealms.sr.components.cutscene.tasks;
|
|||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||
import static me.unurled.srcore.utils.Component.textComp;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.Replay;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.ReplayManager;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.recording.Recordable;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ReplayTask implements Runnable {
|
||||
|
||||
private final Replay replay;
|
||||
private final ReplayManager rm;
|
||||
private final User user;
|
||||
private long currentTick = 0;
|
||||
|
||||
public ReplayTask(Replay replay) {
|
||||
public ReplayTask(@NotNull Replay replay) {
|
||||
this.replay = replay;
|
||||
rm = Manager.getInstance(ReplayManager.class);
|
||||
this.user = PacketEvents.getAPI().getPlayerManager().getUser(replay.viewer());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -38,7 +43,7 @@ public class ReplayTask implements Runnable {
|
|||
|
||||
for (Recordable r : recordables) {
|
||||
// figure out how to replay a recordable
|
||||
r.replay();
|
||||
r.replay(replay, user);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
error("Tick: " + currentTick);
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
package me.unurled.sacredrealms.sr.components.pointer;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMetadata;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnEntity;
|
||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
// TODO: test this
|
||||
public class DisplayForPlayer implements Runnable {
|
||||
|
||||
private static final int RENDER_DISTANCE_BLOCKS = 128;
|
||||
|
||||
private final Pointer pointer;
|
||||
private final Player player;
|
||||
private final User user;
|
||||
|
||||
public DisplayForPlayer(Pointer pointer, Player player) {
|
||||
this.pointer = pointer;
|
||||
this.player = player;
|
||||
this.user = PacketEvents.getAPI().getPlayerManager().getUser(player);
|
||||
}
|
||||
|
||||
public static Location getLocationInRange(@NotNull Player player, Location targetLocation) {
|
||||
Location playerLocation = player.getLocation();
|
||||
|
||||
// Calculate the distance between player and target location
|
||||
double distance = playerLocation.distance(targetLocation);
|
||||
|
||||
// If the location is within the render distance, return the original location
|
||||
if (distance <= RENDER_DISTANCE_BLOCKS) {
|
||||
return targetLocation;
|
||||
}
|
||||
|
||||
// If the location is out of range, calculate a new location within the render distance
|
||||
// Calculate the direction vector from the player to the target
|
||||
Location direction =
|
||||
targetLocation
|
||||
.clone()
|
||||
.subtract(playerLocation)
|
||||
.toVector()
|
||||
.normalize()
|
||||
.toLocation(player.getWorld());
|
||||
|
||||
// Create a new location within the render distance pointing towards the target location
|
||||
return playerLocation.clone().add(direction.multiply(RENDER_DISTANCE_BLOCKS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// get difference between player loc and pointer loc, if it is too large then set pointer
|
||||
// blockdisplay's location to in range of player
|
||||
|
||||
Location location = getLocationInRange(player, pointer.location());
|
||||
|
||||
WrapperPlayServerSpawnEntity packet =
|
||||
new WrapperPlayServerSpawnEntity(
|
||||
pointer.entityId(),
|
||||
pointer.entityUUID(),
|
||||
SpigotConversionUtil.fromBukkitEntityType(EntityType.BLOCK_DISPLAY),
|
||||
SpigotConversionUtil.fromBukkitLocation(location),
|
||||
0,
|
||||
0,
|
||||
null);
|
||||
|
||||
user.sendPacket(packet);
|
||||
|
||||
List<EntityData> list = new ArrayList<>();
|
||||
|
||||
BlockState ironBar =
|
||||
player
|
||||
.getWorld()
|
||||
.getBlockAt(new Location(player.getWorld(), 0, 0, 0))
|
||||
.getState()
|
||||
.getBlockData()
|
||||
.createBlockState();
|
||||
ironBar.setType(Material.IRON_BARS);
|
||||
|
||||
// make it iron bars
|
||||
EntityData data = new EntityData(23, EntityDataTypes.BLOCK_STATE, ironBar);
|
||||
list.add(data);
|
||||
|
||||
// scale
|
||||
EntityData data2 = new EntityData(12, EntityDataTypes.VECTOR3F, new Vector3f(2, 150, 2));
|
||||
list.add(data2);
|
||||
|
||||
// glowing
|
||||
EntityData glowing = new EntityData(0, EntityDataTypes.BYTE, (byte) 0x40);
|
||||
list.add(glowing);
|
||||
|
||||
WrapperPlayServerEntityMetadata packet1 =
|
||||
new WrapperPlayServerEntityMetadata(pointer.entityId(), list);
|
||||
|
||||
user.sendPacket(packet1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package me.unurled.sacredrealms.sr.components.pointer;
|
||||
|
||||
import java.util.UUID;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.BlockDisplay;
|
||||
|
||||
public class Pointer {
|
||||
|
||||
private final Location location;
|
||||
private final int entityId;
|
||||
private BlockDisplay display;
|
||||
private UUID entityUUID;
|
||||
private Location entityLocation;
|
||||
|
||||
public Pointer(int entityId, Location location) {
|
||||
this.entityId = entityId;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public Location location() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public int entityId() {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
public BlockDisplay display() {
|
||||
return display;
|
||||
}
|
||||
|
||||
public Pointer setDisplay(BlockDisplay display) {
|
||||
this.display = display;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UUID entityUUID() {
|
||||
return entityUUID;
|
||||
}
|
||||
|
||||
public Pointer setEntityUUID(UUID entityUUID) {
|
||||
this.entityUUID = entityUUID;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Location entityLocation() {
|
||||
return entityLocation;
|
||||
}
|
||||
|
||||
public Pointer setEntityLocation(Location entityLocation) {
|
||||
this.entityLocation = entityLocation;
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package me.unurled.sacredrealms.sr.components.pointer;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import me.unurled.sacredrealms.sr.SR;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
public class PointerManager extends Manager {
|
||||
|
||||
private final Map<UUID, BukkitTask> tasks = new HashMap<>();
|
||||
|
||||
public void startPointing(Player player, Location location) {
|
||||
int id = -1;
|
||||
try {
|
||||
Class<?> entityClass = Class.forName("net.minecraft.world.entity.Entity");
|
||||
Field field = entityClass.getDeclaredField("ENTITY_COUNTER");
|
||||
field.setAccessible(true);
|
||||
AtomicInteger ENTITY_COUNTER = (AtomicInteger) field.get(null);
|
||||
id = ENTITY_COUNTER.incrementAndGet();
|
||||
} catch (Exception e) {
|
||||
error("Failed to find Entity counter field in nms.");
|
||||
}
|
||||
if (id == -1) {
|
||||
return;
|
||||
}
|
||||
Pointer pointer = new Pointer(id, location);
|
||||
DisplayForPlayer task = new DisplayForPlayer(pointer, player);
|
||||
BukkitTask btask =
|
||||
Bukkit.getScheduler().runTaskTimerAsynchronously(SR.getPlugin(), task, 0, 5L);
|
||||
tasks.put(player.getUniqueId(), btask);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue