1.16: base entities, bump mappings

This commit is contained in:
IzzelAliz 2020-08-22 23:32:10 +08:00
parent e7bc56bd66
commit f651ff8e7b
10 changed files with 384 additions and 253 deletions

View File

@ -36,7 +36,7 @@ arclight {
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
minecraft {
mappings channel: 'snapshot', version: "20200813-1.16.1"
mappings channel: 'snapshot', version: "20200820-1.16.1"
accessTransformer = project.file('src/main/resources/META-INF/accesstransformer.cfg')
}

View File

@ -3,7 +3,7 @@ package io.izzel.arclight.common.bridge.entity;
import io.izzel.arclight.common.bridge.command.ICommandSourceBridge;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.entity.CraftEntity;
import org.bukkit.projectiles.ProjectileSource;
@ -11,7 +11,7 @@ import java.util.List;
public interface EntityBridge extends ICommandSourceBridge {
Entity bridge$teleportTo(DimensionType type, BlockPos blockPos);
Entity bridge$teleportTo(ServerWorld world, BlockPos blockPos);
void bridge$setOnFire(int tick, boolean callEvent);
@ -52,4 +52,6 @@ public interface EntityBridge extends ICommandSourceBridge {
void bridge$setRideCooldown(int rideCooldown);
int bridge$getRideCooldown();
boolean bridge$canCollideWith(Entity entity);
}

View File

@ -3,11 +3,14 @@ package io.izzel.arclight.common.bridge.entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.ResourceLocation;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.entity.EntityTransformEvent;
public interface MobEntityBridge extends LivingEntityBridge {
void bridge$pushGoalTargetReason(EntityTargetEvent.TargetReason reason, boolean fireEvent);
void bridge$pushTransformReason(EntityTransformEvent.TransformReason transformReason);
boolean bridge$setGoalTarget(LivingEntity livingEntity, EntityTargetEvent.TargetReason reason, boolean fireEvent);
ResourceLocation bridge$getLootTable();

View File

@ -1,12 +1,14 @@
package io.izzel.arclight.common.bridge.world;
import net.minecraft.block.pattern.BlockPattern;
import net.minecraft.entity.Entity;
import net.minecraft.util.TeleportationRepositioner;
import net.minecraft.util.math.BlockPos;
import java.util.Optional;
public interface TeleporterBridge {
boolean bridge$makePortal(Entity entityIn, BlockPos pos, int createRadius);
BlockPattern.PortalInfo bridge$placeInPortal(Entity p_222268_1_, BlockPos pos, float p_222268_2_, int searchRadius, boolean searchOnly);
Optional<TeleportationRepositioner.Result> bridge$findPortal(BlockPos pos, int searchRadius);
}

View File

@ -1,7 +1,9 @@
package io.izzel.arclight.common.bridge.world;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.RegistryKey;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.DimensionType;
import org.bukkit.craftbukkit.v.CraftServer;
import org.bukkit.craftbukkit.v.CraftWorld;
import org.bukkit.generator.ChunkGenerator;
@ -34,4 +36,6 @@ public interface WorldBridge extends IWorldWriterBridge, IWorldBridge {
long bridge$ticksPerWaterSpawns();
long bridge$ticksPerAmbientSpawns();
RegistryKey<DimensionType> bridge$getTypeKey();
}

View File

@ -1,17 +1,21 @@
package io.izzel.arclight.common.mixin.core.entity;
import io.izzel.arclight.common.bridge.block.PortalInfoBridge;
import io.izzel.arclight.common.bridge.command.ICommandSourceBridge;
import io.izzel.arclight.common.bridge.entity.EntityBridge;
import io.izzel.arclight.common.bridge.entity.InternalEntityBridge;
import io.izzel.arclight.common.bridge.entity.LivingEntityBridge;
import io.izzel.arclight.common.bridge.entity.MobEntityBridge;
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
import io.izzel.arclight.common.bridge.world.TeleporterBridge;
import io.izzel.arclight.common.bridge.world.WorldBridge;
import io.izzel.arclight.common.bridge.world.storage.SaveHandlerBridge;
import io.izzel.arclight.common.mod.util.ArclightCaptures;
import net.minecraft.block.pattern.BlockPattern;
import net.minecraft.block.BlockState;
import net.minecraft.block.PortalInfo;
import net.minecraft.block.PortalSize;
import net.minecraft.command.CommandSource;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntitySize;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.MobEntity;
@ -27,21 +31,23 @@ import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.scoreboard.Team;
import net.minecraft.server.MinecraftServer;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.DamageSource;
import net.minecraft.util.Direction;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.TeleportationRepositioner;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.DimensionType;
import net.minecraft.world.World;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.border.WorldBorder;
import net.minecraft.world.gen.Heightmap;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.common.util.ITeleporter;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.block.BlockFace;
import org.bukkit.command.CommandSender;
@ -50,6 +56,7 @@ import org.bukkit.craftbukkit.v.CraftWorld;
import org.bukkit.craftbukkit.v.entity.CraftEntity;
import org.bukkit.craftbukkit.v.entity.CraftPlayer;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.craftbukkit.v.event.CraftPortalEvent;
import org.bukkit.entity.Hanging;
import org.bukkit.entity.Vehicle;
import org.bukkit.event.entity.EntityAirChangeEvent;
@ -81,6 +88,7 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.UUID;
@ -90,11 +98,8 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
// @formatter:off
@Shadow public float rotationYaw;
@Shadow public double posX;
@Shadow public double posY;
@Shadow public World world;
@Shadow protected int rideCooldown;
@Shadow public double posZ;
@Shadow public float rotationPitch;
@Shadow public int fire;
@Shadow public abstract Pose getPose();
@ -104,7 +109,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
@Shadow public abstract boolean attackEntityFrom(DamageSource source, float amount);
@Shadow public abstract void setFire(int p_70015_1_);
@Shadow public boolean collidedHorizontally;
@Shadow protected abstract Vec3d getAllowedMovement(Vec3d p_213306_1_);
@Shadow protected abstract Vector3d getAllowedMovement(Vector3d p_213306_1_);
@Shadow public abstract void remove();
@Shadow public int ticksExisted;
@Shadow public void setWorld(World p_70029_1_) { }
@ -112,14 +117,13 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
@Shadow @Final public List<Entity> passengers;
@Shadow @Nullable public abstract Entity getControllingPassenger();
@Shadow public abstract boolean isSwimming();
@Shadow public DimensionType dimension;
@Shadow public abstract boolean isAlive();
@Shadow public abstract void detach();
@Shadow @Final protected EntityDataManager dataManager;
@Shadow @Final private static DataParameter<Integer> AIR;
@Shadow @Deprecated public boolean removed;
@Shadow @Nullable public abstract MinecraftServer getServer();
@Shadow public abstract Vec3d getMotion();
@Shadow public abstract Vector3d getMotion();
@Shadow public abstract EntityType<?> getType();
@Shadow(remap = false) public abstract void remove(boolean keepData);
@Shadow @Final protected Random rand;
@ -137,7 +141,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
@Shadow(remap = false) public abstract Collection<ItemEntity> captureDrops();
@Shadow(remap = false) public abstract Collection<ItemEntity> captureDrops(Collection<ItemEntity> value);
@Shadow public abstract BlockPos getPosition();
@Shadow public boolean onGround;
@Shadow protected boolean onGround;
@Shadow public abstract boolean isInWater();
@Shadow public abstract boolean isPassenger();
@Shadow public float fallDistance;
@ -145,7 +149,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
@Shadow public float distanceWalkedModified;
@Shadow public float prevDistanceWalkedModified;
@Shadow public abstract boolean isOnSameTeam(Entity entityIn);
@Shadow public abstract void setMotion(Vec3d motionIn);
@Shadow public abstract void setMotion(Vector3d motionIn);
@Shadow public abstract double getDistanceSq(Entity entityIn);
@Shadow protected UUID entityUniqueID;
@Shadow protected abstract void markVelocityChanged();
@ -160,11 +164,10 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
@Shadow public abstract boolean hasNoGravity();
@Shadow protected abstract void doBlockCollisions();
@Shadow public float prevRotationYaw;
@Shadow public abstract boolean handleWaterMovement();
@Shadow public abstract boolean isBeingRidden();
@Shadow public abstract boolean isPassenger(Entity entityIn);
@Shadow public abstract void setMotion(double x, double y, double z);
@Shadow public abstract void move(MoverType typeIn, Vec3d pos);
@Shadow public abstract void move(MoverType typeIn, Vector3d pos);
@Shadow @Nullable public abstract Entity getRidingEntity();
@Shadow @Nullable public abstract Team getTeam();
@Shadow public abstract void extinguish();
@ -172,18 +175,22 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
@Shadow public abstract void setLocationAndAngles(double x, double y, double z, float yaw, float pitch);
@Shadow public abstract int getEntityId();
@Shadow @Nullable public abstract ITextComponent getCustomName();
@Shadow protected abstract void applyEnchantments(LivingEntity entityLivingBaseIn, Entity entityIn);
@Shadow @Nullable public abstract Entity changeDimension(DimensionType destination);
@Shadow public abstract void applyEnchantments(LivingEntity entityLivingBaseIn, Entity entityIn);
@Shadow @Nullable public abstract Entity changeDimension(ServerWorld world);
@Shadow public abstract boolean isRidingSameEntity(Entity entityIn);
@Shadow public abstract boolean isInvulnerable();
@Shadow public abstract double getPosX();
@Shadow public abstract double getPosZ();
@Shadow public abstract Vec3d getLastPortalVec();
@Shadow public abstract double getPosY();
@Shadow public abstract Direction getTeleportDirection();
@Shadow public abstract double getPosYEye();
@Shadow public abstract Vec3d getPositionVec();
@Shadow public abstract Vector3d getPositionVec();
@Shadow(remap = false) public abstract void revive();
@Shadow public abstract boolean canBePushed();
@Shadow protected abstract void setDead();
@Shadow protected abstract Optional<TeleportationRepositioner.Result> func_241830_a(ServerWorld p_241830_1_, BlockPos p_241830_2_, boolean p_241830_3_);
@Shadow protected BlockPos field_242271_ac;
@Shadow protected abstract Vector3d func_241839_a(Direction.Axis p_241839_1_, TeleportationRepositioner.Result p_241839_2_);
@Shadow public abstract EntitySize getSize(Pose poseIn);
// @formatter:on
private static final int CURRENT_LEVEL = 2;
@ -236,7 +243,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
}
public boolean isChunkLoaded() {
return world.chunkExists((int) Math.floor(posX) >> 4, (int) Math.floor(posY) >> 4);
return world.chunkExists((int) Math.floor(getPosX()) >> 4, (int) Math.floor(getPosZ()) >> 4);
}
@Override
@ -265,7 +272,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
if (yaw == Float.POSITIVE_INFINITY || yaw == Float.NEGATIVE_INFINITY) {
if (((Object) this) instanceof PlayerEntity) {
Bukkit.getLogger().warning(this.getScoreboardName() + " was caught trying to crash the server with an invalid yaw");
((CraftPlayer) this.getBukkitEntity()).kickPlayer("Infinite yaw (Are you hacking?)"); // 专业防抄袭
((CraftPlayer) this.getBukkitEntity()).kickPlayer("Infinite yaw (Are you hacking?)");
}
this.rotationYaw = 0;
callbackInfo.cancel();
@ -280,7 +287,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
if (pitch == Float.POSITIVE_INFINITY || pitch == Float.NEGATIVE_INFINITY) {
if (((Object) this) instanceof PlayerEntity) {
Bukkit.getLogger().warning(this.getScoreboardName() + " was caught trying to crash the server with an invalid pitch");
((CraftPlayer) this.getBukkitEntity()).kickPlayer("Infinite pitch (Are you hacking?)"); // 专业防抄袭
((CraftPlayer) this.getBukkitEntity()).kickPlayer("Infinite pitch (Are you hacking?)");
}
this.rotationPitch = 0;
callbackInfo.cancel();
@ -395,17 +402,30 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
}
@Inject(method = "move", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/block/Block;onEntityWalk(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/Entity;)V"))
private void arclight$resetBlockWalk(MoverType typeIn, Vec3d pos, CallbackInfo ci) {
private void arclight$resetBlockWalk(MoverType typeIn, Vector3d pos, CallbackInfo ci) {
ArclightCaptures.captureDamageEventBlock(null);
}
@Redirect(method = "move", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;setFire(I)V"))
public void arclight$move$EntityCombustEvent(Entity entity, int seconds) {
EntityCombustEvent event = new EntityCombustByBlockEvent(null, getBukkitEntity(), 8);
Bukkit.getPluginManager().callEvent(event);
@Inject(method = "move", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;canTriggerWalking()Z"))
private void arclight$move$blockCollide(MoverType typeIn, Vector3d pos, CallbackInfo ci) {
if (collidedHorizontally && this.bridge$getBukkitEntity() instanceof Vehicle) {
Vehicle vehicle = (Vehicle) this.bridge$getBukkitEntity();
org.bukkit.block.Block block = ((WorldBridge) this.world).bridge$getWorld().getBlockAt(MathHelper.floor(this.getPosX()), MathHelper.floor(this.getPosY()), MathHelper.floor(this.getPosZ()));
Vector3d vec3d = this.getAllowedMovement(pos);
if (pos.x > vec3d.x) {
block = block.getRelative(BlockFace.EAST);
} else if (vec3d.x < vec3d.x) {
block = block.getRelative(BlockFace.WEST);
} else if (pos.z > vec3d.z) {
block = block.getRelative(BlockFace.SOUTH);
} else if (pos.z < vec3d.z) {
block = block.getRelative(BlockFace.NORTH);
}
if (!event.isCancelled()) {
this.setFire(event.getDuration());
if (block.getType() != org.bukkit.Material.AIR) {
VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, block);
Bukkit.getPluginManager().callEvent(event);
}
}
}
@ -436,7 +456,16 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
@Inject(method = "setPositionAndRotation", at = @At("RETURN"))
private void arclight$loadChunk(double x, double y, double z, float yaw, float pitch, CallbackInfo ci) {
this.world.getChunk((int)Math.floor(this.posX) >> 4, (int)Math.floor(this.posZ) >> 4);
this.world.getChunk((int) Math.floor(this.getPosX()) >> 4, (int) Math.floor(this.getPosZ()) >> 4);
}
public boolean canCollideWith(Entity entity) {
return this.canBePushed();
}
@Override
public boolean bridge$canCollideWith(Entity entity) {
return canCollideWith(entity);
}
@Inject(method = "writeUnlessRemoved", cancellable = true, at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/entity/Entity;getEntityString()Ljava/lang/String;"))
@ -459,8 +488,8 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
@Inject(method = "writeWithoutTypeId", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 0, target = "Lnet/minecraft/nbt/CompoundNBT;putUniqueId(Ljava/lang/String;Ljava/util/UUID;)V"))
public void arclight$writeWithoutTypeId$CraftBukkitNBT(CompoundNBT compound, CallbackInfoReturnable<CompoundNBT> cir) {
compound.putLong("WorldUUIDLeast", ((SaveHandlerBridge) (((ServerWorld) this.world).getSaveHandler())).bridge$getUUID(((ServerWorld) this.world)).getLeastSignificantBits());
compound.putLong("WorldUUIDMost", ((SaveHandlerBridge) (((ServerWorld) this.world).getSaveHandler())).bridge$getUUID(((ServerWorld) this.world)).getMostSignificantBits());
compound.putLong("WorldUUIDLeast", ((WorldBridge) this.world).bridge$getWorld().getUID().getLeastSignificantBits());
compound.putLong("WorldUUIDMost", ((WorldBridge) this.world).bridge$getWorld().getUID().getMostSignificantBits());
compound.putInt("Bukkit.updateLevel", CURRENT_LEVEL);
compound.putInt("Spigot.ticksLived", this.ticksExisted);
}
@ -507,7 +536,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
}
if (bworld == null) {
bworld = ((WorldBridge) ((CraftServer) server).getServer().getWorld(DimensionType.OVERWORLD)).bridge$getWorld();
bworld = ((WorldBridge) ((CraftServer) server).getServer().getWorld(World.OVERWORLD)).bridge$getWorld();
}
setWorld(bworld == null ? null : ((CraftWorld) bworld).getHandle());
@ -544,7 +573,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
cir.setReturnValue(true);
}
@Redirect(method = "stopRiding()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;removePassenger(Lnet/minecraft/entity/Entity;)V"))
@Redirect(method = "dismount", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;removePassenger(Lnet/minecraft/entity/Entity;)V"))
public void arclight$stopRiding$CraftBukkitPatch(Entity entity, Entity passenger) {
if (!((EntityBridge) entity).bridge$removePassenger(passenger)) {
this.ridingEntity = entity;
@ -644,7 +673,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
return true; // CraftBukkit
}
@Inject(method = "updatePortal", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;changeDimension(Lnet/minecraft/world/dimension/DimensionType;)Lnet/minecraft/entity/Entity;"))
@Inject(method = "updatePortal", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;changeDimension(Lnet/minecraft/world/server/ServerWorld;)Lnet/minecraft/entity/Entity;"))
public void arclight$changeDimension(CallbackInfo ci) {
if (this instanceof ServerPlayerEntityBridge) {
((ServerPlayerEntityBridge) this).bridge$pushChangeDimensionCause(PlayerTeleportEvent.TeleportCause.NETHER_PORTAL);
@ -677,7 +706,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
// CraftBukkit end
}
@Redirect(method = "onStruckByLightning", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;setFire(I)V"))
@Redirect(method = "func_241841_a", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;setFire(I)V"))
public void arclight$onStruckByLightning$EntityCombustByEntityEvent0(Entity entity, int seconds) {
final org.bukkit.entity.Entity thisBukkitEntity = this.getBukkitEntity();
final org.bukkit.entity.Entity stormBukkitEntity = ((EntityBridge) entity).bridge$getBukkitEntity();
@ -691,7 +720,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
// CraftBukkit end
}
@Redirect(method = "onStruckByLightning", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;attackEntityFrom(Lnet/minecraft/util/DamageSource;F)Z"))
@Redirect(method = "func_241841_a", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;attackEntityFrom(Lnet/minecraft/util/DamageSource;F)Z"))
public boolean arclight$onStruckByLightning$EntityCombustByEntityEvent1(Entity entity, DamageSource source, float amount) {
final org.bukkit.entity.Entity thisBukkitEntity = this.getBukkitEntity();
final org.bukkit.entity.Entity stormBukkitEntity = ((EntityBridge) entity).bridge$getBukkitEntity();
@ -737,37 +766,14 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
}
}
public Entity teleportTo(DimensionType type, BlockPos blockPos) {
public Entity teleportTo(ServerWorld world, BlockPos blockPos) {
arclight$tpPos = blockPos;
return changeDimension(type);
return changeDimension(world);
}
@Override
public Entity bridge$teleportTo(DimensionType type, BlockPos blockPos) {
return teleportTo(type, blockPos);
}
@Inject(method = "move", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;canTriggerWalking()Z"))
private void arclight$move$blockCollide(MoverType typeIn, Vec3d pos, CallbackInfo ci) {
if (collidedHorizontally && this.bridge$getBukkitEntity() instanceof Vehicle) {
Vehicle vehicle = (Vehicle) this.bridge$getBukkitEntity();
org.bukkit.block.Block block = ((WorldBridge) this.world).bridge$getWorld().getBlockAt(MathHelper.floor(this.getPosX()), MathHelper.floor(this.getPosY()), MathHelper.floor(this.getPosZ()));
Vec3d vec3d = this.getAllowedMovement(pos);
if (pos.x > vec3d.x) {
block = block.getRelative(BlockFace.EAST);
} else if (vec3d.x < vec3d.x) {
block = block.getRelative(BlockFace.WEST);
} else if (pos.z > vec3d.z) {
block = block.getRelative(BlockFace.SOUTH);
} else if (pos.z < vec3d.z) {
block = block.getRelative(BlockFace.NORTH);
}
if (block.getType() != org.bukkit.Material.AIR) {
VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, block);
Bukkit.getPluginManager().callEvent(event);
}
}
public Entity bridge$teleportTo(ServerWorld world, BlockPos blockPos) {
return teleportTo(world, blockPos);
}
/**
@ -776,107 +782,135 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
*/
@Overwrite(remap = false)
@Nullable
public Entity changeDimension(DimensionType destination, ITeleporter teleporter) {
BlockPos location = ((InternalEntityBridge) this).internal$capturedPos();
if (!ForgeHooks.onTravelToDimension((Entity) (Object) this, destination)) return null;
if (!this.world.isRemote && !this.removed) {
public Entity changeDimension(ServerWorld server, net.minecraftforge.common.util.ITeleporter teleporter) {
if (this.world instanceof ServerWorld && !this.removed) {
this.world.getProfiler().startSection("changeDimension");
MinecraftServer minecraftserver = this.getServer();
DimensionType dimensiontype = this.dimension;
ServerWorld serverworld = minecraftserver.getWorld(dimensiontype);
ServerWorld[] serverworld1 = new ServerWorld[]{minecraftserver.getWorld(destination)};
if (serverworld1 == null) {
if (server == null) {
return null;
}
//this.dimension = destination;
//this.detach();
this.world.getProfiler().startSection("reposition");
Entity transportedEntity = teleporter.placeEntity((Entity) (Object) this, serverworld, serverworld1[0], this.rotationYaw, spawnPortal -> { //Forge: Start vanilla logic
Vec3d vec3d = this.getMotion();
float f = 0.0F;
BlockPos blockpos = location;
if (blockpos == null) {
if (dimensiontype == DimensionType.THE_END && destination == DimensionType.OVERWORLD) {
EntityPortalEvent event = CraftEventFactory.callEntityPortalEvent((Entity) (Object) this, serverworld1[0], serverworld1[0].getHeight(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, serverworld1[0].getSpawnPoint()), 0);
if (event == null) {
return null;
}
serverworld1[0] = ((CraftWorld) event.getTo().getWorld()).getHandle();
blockpos = new BlockPos(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ());
//blockpos = serverworld1[0].getHeight(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, serverworld1[0].getSpawnPoint());
} else if (destination == DimensionType.THE_END) {
EntityPortalEvent event = CraftEventFactory.callEntityPortalEvent((Entity) (Object) this, serverworld1[0], (serverworld1[0].getSpawnCoordinate() != null) ? serverworld1[0].getSpawnCoordinate() : serverworld1[0].getSpawnPoint(), 0);
if (event == null) {
return null;
}
serverworld1[0] = ((CraftWorld) event.getTo().getWorld()).getHandle();
blockpos = new BlockPos(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ());
//blockpos = serverworld1[0].getSpawnCoordinate();
} else {
double movementFactor = serverworld.getDimension().getMovementFactor() / serverworld1[0].getDimension().getMovementFactor();
double d0 = this.getPosX() * movementFactor;
double d1 = this.getPosZ() * movementFactor;
double d3 = Math.min(-2.9999872E7D, serverworld1[0].getWorldBorder().minX() + 16.0D);
double d4 = Math.min(-2.9999872E7D, serverworld1[0].getWorldBorder().minZ() + 16.0D);
double d5 = Math.min(2.9999872E7D, serverworld1[0].getWorldBorder().maxX() - 16.0D);
double d6 = Math.min(2.9999872E7D, serverworld1[0].getWorldBorder().maxZ() - 16.0D);
d0 = MathHelper.clamp(d0, d3, d5);
d1 = MathHelper.clamp(d1, d4, d6);
Vec3d vec3d1 = this.getLastPortalVec();
blockpos = new BlockPos(d0, this.getPosY(), d1);
EntityPortalEvent event2 = CraftEventFactory.callEntityPortalEvent((Entity) (Object) this, serverworld1[0], blockpos, 128);
if (event2 == null) {
return null;
}
serverworld1[0] = ((CraftWorld) event2.getTo().getWorld()).getHandle();
blockpos = new BlockPos(event2.getTo().getX(), event2.getTo().getY(), event2.getTo().getZ());
int searchRadius = event2.getSearchRadius();
// todo 实现 radius
if (spawnPortal) {
BlockPattern.PortalInfo blockpattern$portalinfo = serverworld1[0].getDefaultTeleporter().placeInExistingPortal(blockpos, vec3d, this.getTeleportDirection(), vec3d1.x, vec3d1.y, (Object) this instanceof PlayerEntity);
if (blockpattern$portalinfo == null) {
return null;
}
blockpos = new BlockPos(blockpattern$portalinfo.pos);
vec3d = blockpattern$portalinfo.motion;
f = (float) blockpattern$portalinfo.rotation;
}
}
}
this.dimension = destination;
PortalInfo portalinfo = this.func_241829_a(server);
if (portalinfo == null) {
return null;
} else {
server = ((PortalInfoBridge) portalinfo).bridge$getWorld();
this.detach();
Entity transportedEntity = teleporter.placeEntity((Entity) (Object) this, (ServerWorld) this.world, server, this.rotationYaw, spawnPortal -> { //Forge: Start vanilla logic
this.world.getProfiler().endStartSection("reloading");
ServerWorld world = ((PortalInfoBridge) portalinfo).bridge$getWorld();
Entity entity = this.getType().create(world);
if (entity != null) {
entity.copyDataFromOld((Entity) (Object) this);
entity.setLocationAndAngles(portalinfo.pos.x, portalinfo.pos.y, portalinfo.pos.z, portalinfo.field_242960_c, entity.rotationPitch);
entity.setMotion(portalinfo.motion);
world.addFromAnotherDimension(entity);
if (((WorldBridge) world).bridge$getTypeKey() == DimensionType.THE_END) {
ArclightCaptures.captureEndPortalEntity((Entity) (Object) this, spawnPortal);
ServerWorld.func_241121_a_(world);
}
this.world.getProfiler().endStartSection("reloading");
Entity entity = this.getType().create(serverworld1[0]);
if (entity != null) {
entity.copyDataFromOld((Entity) (Object) this);
entity.moveToBlockPosAndAngles(blockpos, entity.rotationYaw + f, entity.rotationPitch);
entity.setMotion(vec3d);
serverworld1[0].addFromAnotherDimension(entity);
((InternalEntityBridge) this).internal$getBukkitEntity().setHandle(entity);
((EntityBridge) entity).bridge$setBukkitEntity(((InternalEntityBridge) this).internal$getBukkitEntity());
if ((Object) this instanceof MobEntity) {
((MobEntity) (Object) this).clearLeashed(true, false);
this.getBukkitEntity().setHandle(entity);
((EntityBridge) entity).bridge$setBukkitEntity(this.bridge$getBukkitEntity());
if ((Object) this instanceof MobEntity) {
((MobEntity) (Object) this).clearLeashed(true, false);
}
}
}
return entity;
});//Forge: End vanilla logic
return entity;
}); //Forge: End vanilla logic
this.remove(false);
this.world.getProfiler().endSection();
serverworld.resetUpdateEntityTick();
serverworld1[0].resetUpdateEntityTick();
this.world.getProfiler().endSection();
return transportedEntity;
this.setDead();
this.world.getProfiler().endSection();
((ServerWorld) this.world).resetUpdateEntityTick();
server.resetUpdateEntityTick();
this.world.getProfiler().endSection();
return transportedEntity;
}
} else {
return null;
}
}
/**
* @author IzzelAliz
* @reason
*/
@Nullable
@Overwrite
protected PortalInfo func_241829_a(ServerWorld world) {
if (world == null) {
return null;
}
boolean flag = ((WorldBridge) this.world).bridge$getTypeKey() == DimensionType.THE_END && ((WorldBridge) world).bridge$getTypeKey() == DimensionType.OVERWORLD;
boolean flag1 = ((WorldBridge) world).bridge$getTypeKey() == DimensionType.THE_END;
if (!flag && !flag1) {
boolean flag2 = ((WorldBridge) world).bridge$getTypeKey() == DimensionType.THE_NETHER;
if (this.world.getDimensionKey() != World.THE_NETHER && !flag2) {
return null;
} else {
WorldBorder worldborder = world.getWorldBorder();
double d0 = Math.max(-2.9999872E7D, worldborder.minX() + 16.0D);
double d1 = Math.max(-2.9999872E7D, worldborder.minZ() + 16.0D);
double d2 = Math.min(2.9999872E7D, worldborder.maxX() - 16.0D);
double d3 = Math.min(2.9999872E7D, worldborder.maxZ() - 16.0D);
double d4 = DimensionType.func_242715_a(this.world.func_230315_m_(), world.func_230315_m_());
BlockPos blockpos1 = new BlockPos(MathHelper.clamp(this.getPosX() * d4, d0, d2), this.getPosY(), MathHelper.clamp(this.getPosZ() * d4, d1, d3));
CraftPortalEvent event = this.callPortalEvent((Entity) (Object) this, world, blockpos1, PlayerTeleportEvent.TeleportCause.NETHER_PORTAL, flag2 ? 16 : 128, 16);
if (event == null) {
return null;
}
ServerWorld worldFinal = world = ((CraftWorld) event.getTo().getWorld()).getHandle();
blockpos1 = new BlockPos(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ());
return this.a(world, blockpos1, flag2, event.getSearchRadius(), event.getCanCreatePortal(), event.getCreationRadius()).map((p_242275_2_) -> {
BlockState blockstate = this.world.getBlockState(this.field_242271_ac);
Direction.Axis direction$axis;
Vector3d vector3d;
if (blockstate.hasProperty(BlockStateProperties.HORIZONTAL_AXIS)) {
direction$axis = blockstate.get(BlockStateProperties.HORIZONTAL_AXIS);
TeleportationRepositioner.Result teleportationrepositioner$result = TeleportationRepositioner.func_243676_a(this.field_242271_ac, direction$axis, 21, Direction.Axis.Y, 21, (p_242276_2_) -> {
return this.world.getBlockState(p_242276_2_) == blockstate;
});
vector3d = this.func_241839_a(direction$axis, teleportationrepositioner$result);
} else {
direction$axis = Direction.Axis.X;
vector3d = new Vector3d(0.5D, 0.0D, 0.0D);
}
return PortalSize.func_242963_a(worldFinal, p_242275_2_, direction$axis, vector3d, this.getSize(this.getPose()), this.getMotion(), this.rotationYaw, this.rotationPitch);
}).orElse(null);
}
} else {
BlockPos blockpos;
if (flag1) {
blockpos = ServerWorld.field_241108_a_;
} else {
blockpos = world.getHeight(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, world.getSpawnPoint());
}
CraftPortalEvent event = this.callPortalEvent((Entity) (Object) this, world, blockpos, PlayerTeleportEvent.TeleportCause.END_PORTAL, 0, 0);
if (event == null) {
return null;
}
blockpos = new BlockPos(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ());
return new PortalInfo(new Vector3d((double) blockpos.getX() + 0.5D, blockpos.getY(), (double) blockpos.getZ() + 0.5D), this.getMotion(), this.rotationYaw, this.rotationPitch);
}
}
protected CraftPortalEvent callPortalEvent(Entity entity, ServerWorld exitWorldServer, BlockPos exitPosition, PlayerTeleportEvent.TeleportCause cause, int searchRadius, int creationRadius) {
CraftEntity bukkitEntity = ((EntityBridge) entity).bridge$getBukkitEntity();
Location enter = bukkitEntity.getLocation();
Location exit = new Location(((WorldBridge) exitWorldServer).bridge$getWorld(), exitPosition.getX(), exitPosition.getY(), exitPosition.getZ());
EntityPortalEvent event = new EntityPortalEvent(bukkitEntity, enter, exit, searchRadius);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled() || event.getTo() == null || event.getTo().getWorld() == null || !entity.isAlive()) {
return null;
}
return new CraftPortalEvent(event);
}
protected Optional<TeleportationRepositioner.Result> a(ServerWorld serverWorld, BlockPos pos, boolean flag, int searchRadius, boolean canCreatePortal, int createRadius) {
return ((TeleporterBridge) serverWorld.getDefaultTeleporter()).bridge$findPortal(pos, searchRadius);
}
}

View File

@ -7,14 +7,15 @@ import com.mojang.datafixers.util.Either;
import io.izzel.arclight.common.bridge.entity.LivingEntityBridge;
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
import io.izzel.arclight.common.bridge.world.WorldBridge;
import io.izzel.arclight.mixin.Eject;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.attributes.AbstractAttributeMap;
import net.minecraft.entity.ai.attributes.IAttribute;
import net.minecraft.entity.ai.attributes.IAttributeInstance;
import net.minecraft.entity.ai.attributes.Attribute;
import net.minecraft.entity.ai.attributes.AttributeModifierManager;
import net.minecraft.entity.ai.attributes.Attributes;
import net.minecraft.entity.ai.attributes.ModifiableAttributeInstance;
import net.minecraft.entity.item.ExperienceOrbEntity;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.passive.AnimalEntity;
@ -75,11 +76,14 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
@SuppressWarnings({"ConstantConditions", "Guava"})
@Mixin(LivingEntity.class)
@ -99,7 +103,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
@Shadow public int deathTime;
@Shadow protected boolean dead;
@Shadow(remap = false) public void remove(boolean keepData) { }
@Shadow public abstract IAttributeInstance getAttribute(IAttribute attribute);
@Shadow public abstract ModifiableAttributeInstance getAttribute(Attribute attribute);
@Shadow public boolean potionsNeedUpdate;
@Shadow public abstract boolean removePotionEffect(Effect effectIn);
@Shadow public abstract boolean clearActivePotions();
@ -119,7 +123,6 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
@Shadow public float attackedAtYaw;
@Shadow public abstract void setRevengeTarget(@Nullable LivingEntity livingBase);
@Shadow protected abstract void markVelocityChanged();
@Shadow public abstract void knockBack(Entity entityIn, float strength, double xRatio, double zRatio);
@Shadow @Nullable protected abstract SoundEvent getDeathSound();
@Shadow protected abstract float getSoundVolume();
@Shadow protected abstract float getSoundPitch();
@ -132,10 +135,9 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
@Shadow @Nullable public abstract EffectInstance getActivePotionEffect(Effect potionIn);
@Shadow protected abstract float applyPotionDamageCalculations(DamageSource source, float damage);
@Shadow public abstract float getAbsorptionAmount();
@Shadow protected abstract void damageArmor(float damage);
@Shadow public abstract void setAbsorptionAmount(float amount);
@Shadow public abstract CombatTracker getCombatTracker();
@Shadow private AbstractAttributeMap attributes;
@Shadow @Final private AttributeModifierManager attributes;
@Shadow public abstract boolean isOnLadder();
@Shadow protected ItemStack activeItemStack;
@Shadow public abstract void onItemPickup(Entity entityIn, int quantity);
@ -164,6 +166,10 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
@Shadow protected abstract void onNewPotionEffect(EffectInstance id);
@Shadow @Nullable public abstract EffectInstance removeActivePotionEffect(@Nullable Effect potioneffectin);
@Shadow protected abstract void createWitherRose(@Nullable LivingEntity p_226298_1_);
@Shadow public abstract double getAttributeValue(Attribute attribute);
@Shadow public abstract void applyKnockback(float strength, double ratioX, double ratioZ);
@Shadow protected abstract void damageArmor(DamageSource damageSource, float damage);
@Shadow protected abstract void playEquipSound(ItemStack stack);
// @formatter:on
public int expToDrop;
@ -172,11 +178,19 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
public CraftAttributeMap craftAttributes;
public boolean collides;
public boolean canPickUpLoot;
public Set<UUID> collidableExemptions = new HashSet<>();
@Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;setHealth(F)V"))
private void arclight$muteHealth(LivingEntity entity, float health) {
// do nothing
}
@Inject(method = "<init>", at = @At("RETURN"))
private void arclight$init(EntityType<? extends LivingEntity> type, World worldIn, CallbackInfo ci) {
this.maxAirTicks = 300;
this.collides = true;
this.craftAttributes = new CraftAttributeMap(this.attributes);
this.dataManager.set(HEALTH, (float) this.getAttributeValue(Attributes.MAX_HEALTH));
}
/**
@ -375,19 +389,11 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
}
}
private transient boolean arclight$fallSuccess;
@Inject(method = "onLivingFall", cancellable = true, at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/entity/LivingEntity;attackEntityFrom(Lnet/minecraft/util/DamageSource;F)Z"))
public void arclight$fall(float distance, float damageMultiplier, CallbackInfoReturnable<Boolean> cir) {
if (!arclight$fallSuccess) {
cir.setReturnValue(true);
}
}
@Redirect(method = "onLivingFall", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;attackEntityFrom(Lnet/minecraft/util/DamageSource;F)Z"))
public boolean arclight$fall(LivingEntity livingEntity, DamageSource source, float amount) {
return arclight$fallSuccess = livingEntity.attackEntityFrom(source, amount);
@Eject(method = "onLivingFall", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;attackEntityFrom(Lnet/minecraft/util/DamageSource;F)Z"))
private boolean arclight$fall(LivingEntity livingEntity, DamageSource source, float amount, CallbackInfoReturnable<Boolean> cir) {
boolean ret = livingEntity.attackEntityFrom(source, amount);
cir.setReturnValue(ret);
return ret;
}
@Override
@ -395,16 +401,6 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
return canPickUpLoot;
}
@Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;getMaxHealth()F"))
public float arclight$muteHealth(LivingEntity livingEntity) {
return 0;
}
@Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;setHealth(F)V"))
public void arclight$muteHealth2(LivingEntity livingEntity, float health) {
this.dataManager.set(HEALTH, (float) this.getAttribute(SharedMonsterAttributes.MAX_HEALTH).getValue());
}
@Override
public float getBukkitYaw() {
return getRotationYawHead();
@ -444,9 +440,9 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
if (compound.contains("Bukkit.MaxHealth")) {
INBT nbtbase = compound.get("Bukkit.MaxHealth");
if (nbtbase.getId() == 5) {
this.getAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(((FloatNBT) nbtbase).getDouble());
this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(((FloatNBT) nbtbase).getDouble());
} else if (nbtbase.getId() == 3) {
this.getAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(((IntNBT) nbtbase).getDouble());
this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(((IntNBT) nbtbase).getDouble());
}
}
}
@ -567,7 +563,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
if ((Object) this instanceof AnimalEntity) {
((AnimalEntity) (Object) this).resetInLove();
if ((Object) this instanceof TameableEntity) {
((TameableEntity) (Object) this).getAISit().setSitting(false);
((TameableEntity) (Object) this).func_233687_w_(false);
}
}
@ -620,15 +616,15 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
}
if (entity1 != null) {
double d1 = entity1.posX - this.posX;
double d1 = entity1.getPosX() - this.getPosX();
double d0;
for (d0 = entity1.posZ - this.posZ; d1 * d1 + d0 * d0 < 1.0E-4D; d0 = (Math.random() - Math.random()) * 0.01D) {
for (d0 = entity1.getPosZ() - this.getPosZ(); d1 * d1 + d0 * d0 < 1.0E-4D; d0 = (Math.random() - Math.random()) * 0.01D) {
d1 = (Math.random() - Math.random()) * 0.01D;
}
this.attackedAtYaw = (float) (MathHelper.atan2(d0, d1) * (double) (180F / (float) Math.PI) - (double) this.rotationYaw);
this.knockBack(entity1, 0.4F, d1, d0);
this.applyKnockback(0.4F, d1, d0);
} else {
this.attackedAtYaw = (float) ((int) (Math.random() * 2.0D) * 180);
}
@ -751,7 +747,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
// Apply damage to armor
if (!damagesource.isUnblockable()) {
float armorDamage = (float) (event.getDamage() + event.getDamage(EntityDamageEvent.DamageModifier.BLOCKING) + event.getDamage(EntityDamageEvent.DamageModifier.HARD_HAT));
this.damageArmor(armorDamage);
this.damageArmor(damagesource, armorDamage);
}
// Apply blocking code // PAIL: steal from above
@ -927,14 +923,16 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
this.addPotionEffect(new EffectInstance(Effects.REGENERATION, 900, 1));
bridge$pushEffectCause(EntityPotionEffectEvent.Cause.TOTEM);
this.addPotionEffect(new EffectInstance(Effects.ABSORPTION, 100, 1));
bridge$pushEffectCause(EntityPotionEffectEvent.Cause.TOTEM);
this.addPotionEffect(new EffectInstance(Effects.FIRE_RESISTANCE, 800, 1));
this.world.setEntityState((Entity) (Object) this, (byte) 35);
}
return !event.isCancelled();
}
}
@Redirect(method = "applyArmorCalculations", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;damageArmor(F)V"))
public void arclight$muteDamageArmor(LivingEntity livingEntity, float damage) {
@Redirect(method = "applyArmorCalculations", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;damageArmor(Lnet/minecraft/util/DamageSource;F)V"))
public void arclight$muteDamageArmor(LivingEntity entity, DamageSource damageSource, float damage) {
}
@Redirect(method = "applyPotionDamageCalculations", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;isPotionActive(Lnet/minecraft/potion/Effect;)Z"))
@ -942,13 +940,6 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
return false;
}
@Inject(method = "getAttributes", at = @At("RETURN"))
public void arclight$initializeCraftAttr(CallbackInfoReturnable<AbstractAttributeMap> cir) {
if (this.craftAttributes == null) {
this.craftAttributes = new CraftAttributeMap(this.attributes);
}
}
@Redirect(method = "travel", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;setFlag(IZ)V"))
public void arclight$stopGlide(LivingEntity livingEntity, int flag, boolean set) {
if (set != livingEntity.getFlag(flag) && !CraftEventFactory.callToggleGlideEvent(livingEntity, set).isCancelled()) {
@ -981,6 +972,11 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
return this.isAlive() && !this.isOnLadder() && this.collides;
}
@Override
public boolean canCollideWith(Entity entity) {
return this.canBePushed() && this.collides != this.collidableExemptions.contains(entity.getUniqueID());
}
private transient ItemStack arclight$consumePost;
@Inject(method = "onItemUseFinish", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD,
@ -1001,25 +997,33 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
}
}
@Redirect(method = "onItemUseFinish", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;onItemUseFinish(Lnet/minecraft/world/World;Lnet/minecraft/entity/LivingEntity;)Lnet/minecraft/item/ItemStack;"))
public ItemStack arclight$useEventItem(ItemStack itemStack, World worldIn, LivingEntity entityLiving) {
if (arclight$consumePost != null) itemStack = arclight$consumePost;
arclight$consumePost = null;
@Eject(method = "onItemUseFinish", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;onItemUseFinish(Lnet/minecraft/world/World;Lnet/minecraft/entity/LivingEntity;)Lnet/minecraft/item/ItemStack;"))
private ItemStack arclight$itemConsume(ItemStack itemStack, World worldIn, LivingEntity entityLiving, CallbackInfo ci) {
if (this instanceof ServerPlayerEntityBridge) {
final org.bukkit.inventory.ItemStack craftItem = CraftItemStack.asBukkitCopy(itemStack);
final PlayerItemConsumeEvent event = new PlayerItemConsumeEvent((Player) this.getBukkitEntity(), craftItem);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
((ServerPlayerEntityBridge) this).bridge$getBukkitEntity().updateInventory();
((ServerPlayerEntityBridge) this).bridge$getBukkitEntity().updateScaledHealth();
ci.cancel();
return null;
} else if (!craftItem.equals(event.getItem())) {
return CraftItemStack.asNMSCopy(event.getItem()).onItemUseFinish(worldIn, entityLiving);
}
}
return itemStack.onItemUseFinish(worldIn, entityLiving);
}
@Inject(method = "attemptTeleport", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD,
at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/entity/LivingEntity;setPositionAndUpdate(DDD)V"))
public void arclight$entityTeleport(double d0, double d1, double d2, boolean flag, CallbackInfoReturnable<Boolean> cir, double d3, double d4, double d5) {
EntityTeleportEvent event = new EntityTeleportEvent(getBukkitEntity(), new Location(((WorldBridge) this.world).bridge$getWorld(), d3, d4, d5),
new Location(((WorldBridge) this.world).bridge$getWorld(), this.posX, this.posY, this.posZ));
@Eject(method = "attemptTeleport", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/entity/LivingEntity;setPositionAndUpdate(DDD)V"))
private void arclight$entityTeleport(LivingEntity entity, double x, double y, double z, CallbackInfoReturnable<Boolean> cir) {
EntityTeleportEvent event = new EntityTeleportEvent(getBukkitEntity(), new Location(((WorldBridge) this.world).bridge$getWorld(), this.getPosX(), this.getPosY(), this.getPosZ()),
new Location(((WorldBridge) this.world).bridge$getWorld(), x, y, z));
Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) {
this.posX = event.getTo().getX();
this.posY = event.getTo().getY();
this.posZ = event.getTo().getZ();
this.setPositionAndUpdate(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ());
} else {
this.setPositionAndUpdate(d3, d4, d5);
this.setPositionAndUpdate(this.getPosX(), this.getPosY(), this.getPosZ());
cir.setReturnValue(false);
}
}
@ -1031,6 +1035,13 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
return drops == null ? livingEntity.captureDrops(value) : drops;
}
@Inject(method = "canEntityBeSeen", cancellable = true, at = @At("HEAD"))
private void arclight$seeNoEvil(Entity entityIn, CallbackInfoReturnable<Boolean> cir) {
if (this.world != entityIn.world) {
cir.setReturnValue(false);
}
}
@Inject(method = "applyFoodEffects", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;addPotionEffect(Lnet/minecraft/potion/EffectInstance;)Z"))
public void arclight$foodEffectCause(ItemStack p_213349_1_, World p_213349_2_, LivingEntity livingEntity, CallbackInfo ci) {
((LivingEntityBridge) livingEntity).bridge$pushEffectCause(EntityPotionEffectEvent.Cause.FOOD);

View File

@ -3,7 +3,9 @@ package io.izzel.arclight.common.mixin.core.entity;
import io.izzel.arclight.common.bridge.entity.EntityBridge;
import io.izzel.arclight.common.bridge.entity.LivingEntityBridge;
import io.izzel.arclight.common.bridge.entity.MobEntityBridge;
import io.izzel.arclight.common.bridge.world.WorldBridge;
import io.izzel.arclight.common.mod.ArclightMod;
import io.izzel.arclight.mixin.Eject;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
@ -15,6 +17,7 @@ import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.play.server.SMountEntityPacket;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
@ -23,9 +26,11 @@ import org.apache.logging.log4j.Level;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.EntityCombustByEntityEvent;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
import org.bukkit.event.entity.EntityTransformEvent;
import org.bukkit.event.entity.EntityUnleashEvent;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Implements;
@ -54,8 +59,7 @@ public abstract class MobEntityMixin extends LivingEntityMixin implements MobEnt
@Shadow protected abstract ResourceLocation shadow$getLootTable();
@Shadow public static EquipmentSlotType getSlotForItemStack(ItemStack stack) { return null; }
@Shadow public abstract ItemStack getItemStackFromSlot(EquipmentSlotType slotIn);
@Shadow protected abstract boolean shouldExchangeEquipment(ItemStack candidate, ItemStack existing, EquipmentSlotType p_208003_3_);
@Shadow protected abstract boolean canEquipItem(ItemStack stack);
@Shadow public abstract boolean canEquipItem(ItemStack stack);
@Shadow protected abstract float getDropChance(EquipmentSlotType slotIn);
@Shadow public abstract void setItemStackToSlot(EquipmentSlotType slotIn, ItemStack stack);
@Shadow @Final public float[] inventoryHandsDropChances;
@ -64,6 +68,9 @@ public abstract class MobEntityMixin extends LivingEntityMixin implements MobEnt
@Shadow public abstract boolean isNoDespawnRequired();
@Shadow protected void updateAITasks() { }
@Shadow public abstract boolean isAIDisabled();
@Shadow protected abstract boolean shouldExchangeEquipment(ItemStack candidate, ItemStack existing);
@Shadow protected abstract void func_233657_b_(EquipmentSlotType p_233657_1_, ItemStack p_233657_2_);
@Shadow @Nullable public abstract <T extends MobEntity> T func_233656_b_(EntityType<T> p_233656_1_, boolean p_233656_2_);
// @formatter:on
public boolean aware;
@ -193,38 +200,41 @@ public abstract class MobEntityMixin extends LivingEntityMixin implements MobEnt
}
}
@Inject(method = "updateEquipmentIfNeeded", at = @At("HEAD"))
private void arclight$captureItemEntity(ItemEntity itemEntity, CallbackInfo ci) {
arclight$item = itemEntity;
}
private transient ItemEntity arclight$item;
/**
* @author IzzelAliz
* @reason
*/
@Overwrite
protected void updateEquipmentIfNeeded(ItemEntity itemEntity) {
ItemStack itemstack = itemEntity.getItem();
EquipmentSlotType equipmentslottype = getSlotForItemStack(itemstack);
ItemStack itemstack1 = this.getItemStackFromSlot(equipmentslottype);
boolean flag = this.shouldExchangeEquipment(itemstack, itemstack1, equipmentslottype);
boolean canPickup = flag && this.canEquipItem(itemstack);
canPickup = !CraftEventFactory.callEntityPickupItemEvent((Entity) (Object) this, itemEntity, 0, !canPickup).isCancelled();
public boolean func_233665_g_(ItemStack p_233665_1_) {
ItemEntity itemEntity = arclight$item;
arclight$item = null;
EquipmentSlotType equipmentslottype = getSlotForItemStack(p_233665_1_);
ItemStack itemstack = this.getItemStackFromSlot(equipmentslottype);
boolean flag = this.shouldExchangeEquipment(p_233665_1_, itemstack);
boolean canPickup = flag && this.canEquipItem(p_233665_1_);
if (itemEntity != null) {
canPickup = !CraftEventFactory.callEntityPickupItemEvent((MobEntity) (Object) this, itemEntity, 0, !canPickup).isCancelled();
}
if (canPickup) {
double d0 = this.getDropChance(equipmentslottype);
if (!itemstack1.isEmpty() && (double) (this.rand.nextFloat() - 0.1F) < d0) {
if (!itemstack.isEmpty() && (double) Math.max(this.rand.nextFloat() - 0.1F, 0.0F) < d0) {
forceDrops = true;
this.entityDropItem(itemstack1);
this.entityDropItem(itemstack);
forceDrops = false;
}
this.setItemStackToSlot(equipmentslottype, itemstack);
switch (equipmentslottype.getSlotType()) {
case HAND:
this.inventoryHandsDropChances[equipmentslottype.getIndex()] = 2.0F;
break;
case ARMOR:
this.inventoryArmorDropChances[equipmentslottype.getIndex()] = 2.0F;
}
this.persistenceRequired = true;
this.onItemPickup(itemEntity, itemstack.getCount());
itemEntity.remove();
this.func_233657_b_(equipmentslottype, p_233665_1_);
this.playEquipSound(p_233665_1_);
return true;
} else {
return false;
}
}
@ -234,18 +244,18 @@ public abstract class MobEntityMixin extends LivingEntityMixin implements MobEnt
}
@Inject(method = "processInitialInteract", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/MobEntity;clearLeashed(ZZ)V"))
private void arclight$unleash(PlayerEntity player, Hand hand, CallbackInfoReturnable<Boolean> cir) {
private void arclight$unleash(PlayerEntity player, Hand hand, CallbackInfoReturnable<ActionResultType> cir) {
if (CraftEventFactory.callPlayerUnleashEntityEvent((MobEntity) (Object) this, player).isCancelled()) {
((ServerPlayerEntity) player).connection.sendPacket(new SMountEntityPacket((MobEntity) (Object) this, this.getLeashHolder()));
cir.setReturnValue(false);
cir.setReturnValue(ActionResultType.PASS);
}
}
@Inject(method = "processInitialInteract", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/MobEntity;setLeashHolder(Lnet/minecraft/entity/Entity;Z)V"))
private void arclight$leash(PlayerEntity player, Hand hand, CallbackInfoReturnable<Boolean> cir) {
@Inject(method = "func_233661_c_", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/MobEntity;setLeashHolder(Lnet/minecraft/entity/Entity;Z)V"))
private void arclight$leash(PlayerEntity player, Hand hand, CallbackInfoReturnable<ActionResultType> cir) {
if (CraftEventFactory.callPlayerLeashEntityEvent((MobEntity) (Object) this, player, player).isCancelled()) {
((ServerPlayerEntity) player).connection.sendPacket(new SMountEntityPacket((MobEntity) (Object) this, this.getLeashHolder()));
cir.setReturnValue(false);
cir.setReturnValue(ActionResultType.PASS);
}
}
@ -265,11 +275,41 @@ public abstract class MobEntityMixin extends LivingEntityMixin implements MobEnt
this.forceDrops = true;
}
@Inject(method = "recreateLeash", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/MobEntity;clearLeashed(ZZ)V"))
public void arclight$createLeash(CallbackInfo ci) {
@Inject(method = "startRiding", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/MobEntity;clearLeashed(ZZ)V"))
private void arclight$unleashRide(Entity entityIn, boolean force, CallbackInfoReturnable<Boolean> cir) {
Bukkit.getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.UNKNOWN));
}
@Inject(method = "setDead", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/MobEntity;clearLeashed(ZZ)V"))
private void arclight$unleashDead(CallbackInfo ci) {
Bukkit.getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.UNKNOWN));
}
@Eject(method = "func_233656_b_", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;addEntity(Lnet/minecraft/entity/Entity;)Z"))
private boolean arclight$copySpawn(World world, Entity entityIn, CallbackInfoReturnable<MobEntity> cir) {
EntityTransformEvent.TransformReason transformReason = arclight$transform == null ? EntityTransformEvent.TransformReason.UNKNOWN : arclight$transform;
arclight$transform = null;
if (CraftEventFactory.callEntityTransformEvent((MobEntity) (Object) this, (LivingEntity) entityIn, transformReason).isCancelled()) {
cir.setReturnValue(null);
return false;
} else {
return world.addEntity(entityIn);
}
}
public <T extends MobEntity> T a(EntityType<T> entityType, boolean flag, EntityTransformEvent.TransformReason transformReason, CreatureSpawnEvent.SpawnReason spawnReason) {
((WorldBridge) this.world).bridge$pushAddEntityReason(spawnReason);
bridge$pushTransformReason(transformReason);
return this.func_233656_b_(entityType, flag);
}
private transient EntityTransformEvent.TransformReason arclight$transform;
@Override
public void bridge$pushTransformReason(EntityTransformEvent.TransformReason transformReason) {
this.arclight$transform = transformReason;
}
@Redirect(method = "attackEntityAsMob", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;setFire(I)V"))
public void arclight$attackCombust(Entity entity, int seconds) {
EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), ((EntityBridge) entity).bridge$getBukkitEntity(), seconds);

View File

@ -11,7 +11,9 @@ import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.profiler.IProfiler;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.RegistryKey;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.DimensionType;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import net.minecraft.world.border.WorldBorder;
@ -59,9 +61,10 @@ public abstract class WorldMixin implements WorldBridge {
@Shadow public abstract WorldBorder getWorldBorder();
@Shadow@Final private WorldBorder worldBorder;
@Shadow public abstract long getDayTime();
@Accessor("mainThread") public abstract Thread arclight$getMainThread();
@Shadow@Final private DimensionType dimensionType;@Accessor("mainThread") public abstract Thread arclight$getMainThread();
// @formatter:on
private RegistryKey<DimensionType> typeKey;
protected CraftWorld world;
public boolean pvpMode;
public boolean keepSpawnInMemory = true;
@ -90,6 +93,8 @@ public abstract class WorldMixin implements WorldBridge {
this.ticksPerWaterSpawns = 1;
this.ticksPerAmbientSpawns = 1;
}
this.typeKey = this.getServer().getHandle().getServer().func_244267_aX().func_230520_a_().func_230519_c_(dimensionType)
.orElseThrow(() -> new IllegalStateException("Unregistered dimension type: " + dimType));
}
@Override
@ -123,6 +128,15 @@ public abstract class WorldMixin implements WorldBridge {
bridge$getWorld();
}
public RegistryKey<DimensionType> getTypeKey() {
return this.typeKey;
}
@Override
public RegistryKey<DimensionType> bridge$getTypeKey() {
return getTypeKey();
}
@Override
public SpigotWorldConfig bridge$spigotConfig() {
return this.spigotConfig;

View File

@ -198,6 +198,27 @@ public class ArclightCaptures {
}
}
private static transient Entity endPortalEntity;
private static transient boolean spawnPortal;
public static void captureEndPortalEntity(Entity entity, boolean portal) {
endPortalEntity = entity;
spawnPortal = portal;
}
public static boolean getEndPortalSpawn() {
return spawnPortal;
}
public static Entity getEndPortalEntity() {
try {
return endPortalEntity;
} finally {
endPortalEntity = null;
spawnPortal = false;
}
}
private static void recapture(String type) {
throw new IllegalStateException("Recapturing " + type);
}