Optimized entity teleportation
This commit is contained in:
parent
7aa441171c
commit
b36c4777c5
5 changed files with 17 additions and 127 deletions
|
@ -1,5 +1,6 @@
|
||||||
package ru.betterend.blocks;
|
package ru.betterend.blocks;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
|
@ -31,9 +32,7 @@ import ru.betterend.registry.EndParticles;
|
||||||
|
|
||||||
public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable {
|
public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable {
|
||||||
public EndPortalBlock() {
|
public EndPortalBlock() {
|
||||||
super(FabricBlockSettings.copyOf(Blocks.NETHER_PORTAL).resistance(Blocks.BEDROCK.getBlastResistance()).luminance(state -> {
|
super(FabricBlockSettings.copyOf(Blocks.NETHER_PORTAL).resistance(Blocks.BEDROCK.getBlastResistance()).luminance(state -> 12));
|
||||||
return 12;
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -67,8 +66,7 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable
|
||||||
@Override
|
@Override
|
||||||
public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
|
public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
|
||||||
if (world instanceof ServerWorld && !entity.hasVehicle() && !entity.hasPassengers() && entity.canUsePortals()) {
|
if (world instanceof ServerWorld && !entity.hasVehicle() && !entity.hasPassengers() && entity.canUsePortals()) {
|
||||||
TeleportingEntity teleEntity = TeleportingEntity.class.cast(entity);
|
if (entity.hasNetherPortalCooldown()) return;
|
||||||
if (teleEntity.hasCooldown()) return;
|
|
||||||
boolean isOverworld = world.getRegistryKey().equals(World.OVERWORLD);
|
boolean isOverworld = world.getRegistryKey().equals(World.OVERWORLD);
|
||||||
ServerWorld destination = ((ServerWorld) world).getServer().getWorld(isOverworld ? World.END : World.OVERWORLD);
|
ServerWorld destination = ((ServerWorld) world).getServer().getWorld(isOverworld ? World.END : World.OVERWORLD);
|
||||||
BlockPos exitPos = this.findExitPos(destination, pos, entity);
|
BlockPos exitPos = this.findExitPos(destination, pos, entity);
|
||||||
|
@ -76,11 +74,14 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable
|
||||||
if (entity instanceof ServerPlayerEntity) {
|
if (entity instanceof ServerPlayerEntity) {
|
||||||
ServerPlayerEntity player = (ServerPlayerEntity) entity;
|
ServerPlayerEntity player = (ServerPlayerEntity) entity;
|
||||||
player.teleport(destination, exitPos.getX() + 0.5D, exitPos.getY(), exitPos.getZ() + 0.5D, entity.yaw, entity.pitch);
|
player.teleport(destination, exitPos.getX() + 0.5D, exitPos.getY(), exitPos.getZ() + 0.5D, entity.yaw, entity.pitch);
|
||||||
teleEntity.beSetCooldown(player.isCreative() ? 50 : 300);
|
player.resetNetherPortalCooldown();
|
||||||
} else {
|
} else {
|
||||||
|
TeleportingEntity teleEntity = (TeleportingEntity) entity;
|
||||||
teleEntity.beSetExitPos(exitPos);
|
teleEntity.beSetExitPos(exitPos);
|
||||||
entity.moveToWorld(destination);
|
Entity teleported = entity.moveToWorld(destination);
|
||||||
teleEntity.beSetCooldown(300);
|
if (teleported != null) {
|
||||||
|
teleported.resetNetherPortalCooldown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,8 +92,10 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable
|
||||||
}
|
}
|
||||||
|
|
||||||
private BlockPos findExitPos(ServerWorld world, BlockPos pos, Entity entity) {
|
private BlockPos findExitPos(ServerWorld world, BlockPos pos, Entity entity) {
|
||||||
|
if (world == null) return null;
|
||||||
|
|
||||||
Registry<DimensionType> registry = world.getRegistryManager().getDimensionTypes();
|
Registry<DimensionType> registry = world.getRegistryManager().getDimensionTypes();
|
||||||
double mult = registry.get(DimensionType.THE_END_ID).getCoordinateScale();
|
double mult = Objects.requireNonNull(registry.get(DimensionType.THE_END_ID)).getCoordinateScale();
|
||||||
BlockPos.Mutable basePos;
|
BlockPos.Mutable basePos;
|
||||||
if (world.getRegistryKey().equals(World.OVERWORLD)) {
|
if (world.getRegistryKey().equals(World.OVERWORLD)) {
|
||||||
basePos = pos.mutableCopy().set(pos.getX() / mult, pos.getY(), pos.getZ() / mult);
|
basePos = pos.mutableCopy().set(pos.getX() / mult, pos.getY(), pos.getZ() / mult);
|
||||||
|
@ -120,14 +123,11 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable
|
||||||
entityDir = frontDir;
|
entityDir = frontDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frontDir == entityDir || frontDir.getOpposite() == entityDir) {
|
if (frontDir != entityDir && frontDir.getOpposite() != entityDir) {
|
||||||
return checkPos.offset(entityDir);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
entity.applyRotation(BlockRotation.CLOCKWISE_90);
|
entity.applyRotation(BlockRotation.CLOCKWISE_90);
|
||||||
entityDir = entityDir.rotateYClockwise();
|
entityDir = entityDir.rotateYClockwise();
|
||||||
return checkPos.offset(entityDir);
|
|
||||||
}
|
}
|
||||||
|
return checkPos.offset(entityDir);
|
||||||
}
|
}
|
||||||
checkPos.move(Direction.DOWN);
|
checkPos.move(Direction.DOWN);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,5 @@ package ru.betterend.interfaces;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
public interface TeleportingEntity {
|
public interface TeleportingEntity {
|
||||||
public abstract long beGetCooldown();
|
void beSetExitPos(BlockPos pos);
|
||||||
public abstract void beSetCooldown(long time);
|
|
||||||
public abstract void beSetExitPos(BlockPos pos);
|
|
||||||
public abstract BlockPos beGetExitPos();
|
|
||||||
|
|
||||||
default boolean hasCooldown() {
|
|
||||||
return this.beGetCooldown() > 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,8 @@ import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
@ -23,7 +20,7 @@ import ru.betterend.interfaces.TeleportingEntity;
|
||||||
|
|
||||||
@Mixin(Entity.class)
|
@Mixin(Entity.class)
|
||||||
public abstract class EntityMixin implements TeleportingEntity {
|
public abstract class EntityMixin implements TeleportingEntity {
|
||||||
private static final Map<Entity, Long> COOLDOWN = Maps.newHashMap();
|
|
||||||
private BlockPos beExitPos;
|
private BlockPos beExitPos;
|
||||||
|
|
||||||
@Shadow
|
@Shadow
|
||||||
|
@ -45,12 +42,6 @@ public abstract class EntityMixin implements TeleportingEntity {
|
||||||
@Shadow
|
@Shadow
|
||||||
public abstract EntityType<?> getType();
|
public abstract EntityType<?> getType();
|
||||||
|
|
||||||
@Shadow
|
|
||||||
public abstract void copyFrom(Entity original);
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
public abstract Entity moveToWorld(ServerWorld destination);
|
|
||||||
|
|
||||||
@Shadow
|
@Shadow
|
||||||
protected abstract TeleportTarget getTeleportTarget(ServerWorld destination);
|
protected abstract TeleportTarget getTeleportTarget(ServerWorld destination);
|
||||||
|
|
||||||
|
@ -84,41 +75,12 @@ public abstract class EntityMixin implements TeleportingEntity {
|
||||||
@Inject(method = "getTeleportTarget", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "getTeleportTarget", at = @At("HEAD"), cancellable = true)
|
||||||
protected void be_getTeleportTarget(ServerWorld destination, CallbackInfoReturnable<TeleportTarget> info) {
|
protected void be_getTeleportTarget(ServerWorld destination, CallbackInfoReturnable<TeleportTarget> info) {
|
||||||
if (beExitPos != null) {
|
if (beExitPos != null) {
|
||||||
COOLDOWN.remove(beGetSelf());
|
|
||||||
info.setReturnValue(new TeleportTarget(new Vec3d(beExitPos.getX() + 0.5D, beExitPos.getY(), beExitPos.getZ() + 0.5D), getVelocity(), yaw, pitch));
|
info.setReturnValue(new TeleportTarget(new Vec3d(beExitPos.getX() + 0.5D, beExitPos.getY(), beExitPos.getZ() + 0.5D), getVelocity(), yaw, pitch));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "baseTick", at = @At("TAIL"))
|
|
||||||
public void be_baseTick(CallbackInfo info) {
|
|
||||||
if (hasCooldown()) {
|
|
||||||
Entity key = beGetSelf();
|
|
||||||
long value = COOLDOWN.getOrDefault(key, 0L) - 1;
|
|
||||||
COOLDOWN.put(key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long beGetCooldown() {
|
|
||||||
return COOLDOWN.getOrDefault(beGetSelf(), 0L);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void beSetCooldown(long time) {
|
|
||||||
COOLDOWN.put(beGetSelf(), time);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beSetExitPos(BlockPos pos) {
|
public void beSetExitPos(BlockPos pos) {
|
||||||
this.beExitPos = pos;
|
this.beExitPos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockPos beGetExitPos() {
|
|
||||||
return this.beExitPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Entity beGetSelf() {
|
|
||||||
return (Entity) (Object) this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
package ru.betterend.mixin.common;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
|
||||||
import net.minecraft.server.world.ServerWorld;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.registry.RegistryKey;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import ru.betterend.interfaces.TeleportingEntity;
|
|
||||||
|
|
||||||
@Mixin(ServerPlayerEntity.class)
|
|
||||||
public abstract class ServerPlayerEntityMixin extends PlayerEntity implements TeleportingEntity {
|
|
||||||
private static final Map<ServerPlayerEntity, Long> COOLDOWN = Maps.newHashMap();
|
|
||||||
|
|
||||||
public ServerPlayerEntityMixin(World world, BlockPos pos, float yaw, GameProfile profile) {
|
|
||||||
super(world, pos, yaw, profile);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
private RegistryKey<World> spawnPointDimension;
|
|
||||||
|
|
||||||
@Inject(method = "tick", at = @At("TAIL"))
|
|
||||||
public void be_baseTick(CallbackInfo info) {
|
|
||||||
if (hasCooldown()) {
|
|
||||||
ServerPlayerEntity key = (ServerPlayerEntity) (Object) this;
|
|
||||||
long value = COOLDOWN.getOrDefault(key, 0L) - 1;
|
|
||||||
COOLDOWN.put(key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
private void moveToSpawn(ServerWorld world) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long beGetCooldown() {
|
|
||||||
ServerPlayerEntity key = (ServerPlayerEntity) (Object) this;
|
|
||||||
return COOLDOWN.getOrDefault(key, 0L);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void beSetCooldown(long time) {
|
|
||||||
ServerPlayerEntity key = (ServerPlayerEntity) (Object) this;
|
|
||||||
COOLDOWN.put(key, time);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void beSetExitPos(BlockPos pos) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockPos beGetExitPos() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,7 +12,6 @@
|
||||||
"NoiseChunkGeneratorMixin",
|
"NoiseChunkGeneratorMixin",
|
||||||
"AnvilScreenHandlerMixin",
|
"AnvilScreenHandlerMixin",
|
||||||
"ChorusPlantFeatureMixin",
|
"ChorusPlantFeatureMixin",
|
||||||
"ServerPlayerEntityMixin",
|
|
||||||
"ComposterBlockAccessor",
|
"ComposterBlockAccessor",
|
||||||
"ChorusFlowerBlockMixin",
|
"ChorusFlowerBlockMixin",
|
||||||
"LandPathNodeMakerMixin",
|
"LandPathNodeMakerMixin",
|
||||||
|
@ -33,7 +32,7 @@
|
||||||
"PlayerEntityMixin",
|
"PlayerEntityMixin",
|
||||||
"SlimeEntityMixin",
|
"SlimeEntityMixin",
|
||||||
"BrewingAccessor",
|
"BrewingAccessor",
|
||||||
"EntityMixin",
|
"EntityMixin"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue