Optimized entity teleportation

This commit is contained in:
Aleksey 2021-01-13 17:02:45 +03:00
parent 7aa441171c
commit b36c4777c5
5 changed files with 17 additions and 127 deletions

View file

@ -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);
} }

View file

@ -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;
}
} }

View file

@ -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;
}
} }

View file

@ -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;
}
}

View file

@ -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