Entities
This commit is contained in:
parent
792df330b4
commit
4f0e52fb69
@ -52,4 +52,6 @@ public interface EntityBridge extends ICommandSourceBridge {
|
||||
void bridge$setRideCooldown(int rideCooldown);
|
||||
|
||||
int bridge$getRideCooldown();
|
||||
|
||||
double bridge$getEyeHeight();
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package io.izzel.arclight.common.bridge.entity;
|
||||
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.potion.Effect;
|
||||
import net.minecraft.potion.EffectInstance;
|
||||
import org.bukkit.craftbukkit.v.entity.CraftLivingEntity;
|
||||
@ -18,6 +19,12 @@ public interface LivingEntityBridge extends EntityBridge {
|
||||
|
||||
void bridge$setExpToDrop(int amount);
|
||||
|
||||
int bridge$getExpToDrop();
|
||||
|
||||
void bridge$dropExperience();
|
||||
|
||||
void bridge$createWitherRose(LivingEntity entity);
|
||||
|
||||
void bridge$pushHealReason(EntityRegainHealthEvent.RegainReason regainReason);
|
||||
|
||||
void bridge$heal(float healAmount, EntityRegainHealthEvent.RegainReason regainReason);
|
||||
|
||||
@ -16,6 +16,8 @@ public interface MobEntityBridge extends LivingEntityBridge {
|
||||
|
||||
void bridge$setPersistenceRequired(boolean value);
|
||||
|
||||
void bridge$setAware(boolean aware);
|
||||
|
||||
interface Hack {
|
||||
|
||||
ResourceLocation getLootTable();
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
package io.izzel.arclight.common.bridge.entity.player;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import io.izzel.arclight.common.bridge.entity.LivingEntityBridge;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
||||
import io.izzel.arclight.common.bridge.entity.LivingEntityBridge;
|
||||
|
||||
public interface PlayerEntityBridge extends LivingEntityBridge {
|
||||
|
||||
@ -13,6 +13,8 @@ public interface PlayerEntityBridge extends LivingEntityBridge {
|
||||
|
||||
String bridge$getSpawnWorld();
|
||||
|
||||
void bridge$setSpawnWorld(String world);
|
||||
|
||||
@Override
|
||||
CraftHumanEntity bridge$getBukkitEntity();
|
||||
|
||||
|
||||
@ -9,6 +9,8 @@ import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v.entity.CraftPlayer;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface ServerPlayerEntityBridge extends PlayerEntityBridge {
|
||||
|
||||
@Override
|
||||
@ -16,6 +18,8 @@ public interface ServerPlayerEntityBridge extends PlayerEntityBridge {
|
||||
|
||||
void bridge$pushChangeDimensionCause(PlayerTeleportEvent.TeleportCause cause);
|
||||
|
||||
Optional<PlayerTeleportEvent.TeleportCause> bridge$getTeleportCause();
|
||||
|
||||
BlockPos bridge$getSpawnPoint(ServerWorld world);
|
||||
|
||||
boolean bridge$isMovementBlocked();
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
package io.izzel.arclight.common.bridge.entity.projectile;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
|
||||
public interface ProjectileItemEntityBridge {
|
||||
|
||||
interface Hack {
|
||||
|
||||
Item getDefaultItem();
|
||||
}
|
||||
}
|
||||
@ -14,4 +14,6 @@ public interface ExplosionBridge {
|
||||
Explosion.Mode bridge$getMode();
|
||||
|
||||
boolean bridge$wasCancelled();
|
||||
|
||||
float bridge$callBlockExplodeEvent();
|
||||
}
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
package io.izzel.arclight.common.bridge.world;
|
||||
|
||||
import net.minecraft.block.pattern.BlockPattern;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
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);
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
package io.izzel.arclight.common.bridge.world.dimension;
|
||||
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
|
||||
public interface DimensionTypeBridge {
|
||||
|
||||
DimensionType bridge$getType();
|
||||
}
|
||||
@ -169,6 +169,13 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
|
||||
@Shadow public abstract float getEyeHeight();
|
||||
@Shadow @Nullable public abstract Entity changeDimension(DimensionType destination);
|
||||
@Shadow public abstract boolean isRidingSameEntity(Entity entityIn);
|
||||
@Shadow public boolean noClip;
|
||||
@Shadow public abstract double getPosX();
|
||||
@Shadow public abstract double getPosY();
|
||||
@Shadow public abstract double getPosZ();
|
||||
@Shadow(remap = false) public abstract void revive();
|
||||
@Shadow public abstract Vec3d getPositionVec();
|
||||
@Shadow public abstract boolean isInvulnerable();
|
||||
// @formatter:on
|
||||
|
||||
private static final int CURRENT_LEVEL = 2;
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
package io.izzel.arclight.common.mixin.core.entity;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
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;
|
||||
@ -15,7 +12,6 @@ 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.item.ExperienceOrbEntity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.passive.AnimalEntity;
|
||||
import net.minecraft.entity.passive.TameableEntity;
|
||||
@ -29,7 +25,6 @@ import net.minecraft.nbt.FloatNBT;
|
||||
import net.minecraft.nbt.INBT;
|
||||
import net.minecraft.nbt.IntNBT;
|
||||
import net.minecraft.network.datasync.DataParameter;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.potion.Effect;
|
||||
import net.minecraft.potion.EffectInstance;
|
||||
import net.minecraft.potion.Effects;
|
||||
@ -39,13 +34,12 @@ import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.EntityDamageSource;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.GameRules;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.ForgeEventFactory;
|
||||
import net.minecraftforge.event.entity.living.PotionEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v.attribute.CraftAttributeMap;
|
||||
@ -73,10 +67,6 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
|
||||
@ -99,18 +89,9 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
|
||||
@Shadow protected boolean dead;
|
||||
@Shadow public void remove(boolean keepData) { }
|
||||
@Shadow public abstract IAttributeInstance getAttribute(IAttribute attribute);
|
||||
@Shadow @Final public Map<Effect, EffectInstance> activePotionsMap;
|
||||
@Shadow protected abstract void onFinishedPotionEffect(EffectInstance effect);
|
||||
@Shadow protected abstract void onChangedPotionEffect(EffectInstance id, boolean reapply);
|
||||
@Shadow public boolean potionsNeedUpdate;
|
||||
@Shadow protected abstract void updatePotionMetadata();
|
||||
@Shadow @Final private static DataParameter<Integer> POTION_EFFECTS;
|
||||
@Shadow @Final private static DataParameter<Boolean> HIDE_PARTICLES;
|
||||
@Shadow public abstract boolean removePotionEffect(Effect effectIn);
|
||||
@Shadow public abstract boolean isPotionApplicable(EffectInstance potioneffectIn);
|
||||
@Shadow protected abstract void onNewPotionEffect(EffectInstance id);
|
||||
@Shadow public abstract boolean clearActivePotions();
|
||||
@Shadow @Nullable public abstract EffectInstance removeActivePotionEffect(@Nullable Effect potioneffectin);
|
||||
@Shadow @Final public static DataParameter<Float> HEALTH;
|
||||
@Shadow public abstract boolean isPotionActive(Effect potionIn);
|
||||
@Shadow public abstract boolean isSleeping();
|
||||
@ -162,6 +143,8 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
|
||||
@Shadow public CombatTracker combatTracker;
|
||||
@Shadow public abstract ItemStack getHeldItemOffhand();
|
||||
@Shadow public abstract Random getRNG();
|
||||
@Shadow public abstract Optional<BlockPos> getBedPosition();
|
||||
@Shadow public abstract boolean addPotionEffect(EffectInstance effectInstanceIn);
|
||||
// @formatter:on
|
||||
|
||||
public int expToDrop;
|
||||
@ -198,8 +181,8 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
|
||||
}
|
||||
|
||||
public int getExpReward() {
|
||||
int exp = this.getExperiencePoints(this.attackingPlayer);
|
||||
if (!this.world.isRemote && (this.recentlyHit > 0 || this.isPlayer()) && this.canDropLoot() && this.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) {
|
||||
int exp = this.getExperiencePoints(this.attackingPlayer);
|
||||
return ForgeEventFactory.getExperienceDrop((LivingEntity) (Object) this, this.attackingPlayer, exp);
|
||||
} else {
|
||||
return 0;
|
||||
@ -216,40 +199,16 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
|
||||
this.expToDrop = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bridge$getExpToDrop() {
|
||||
return this.expToDrop;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bridge$isForceDrops() {
|
||||
return forceDrops;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
*/
|
||||
@Overwrite
|
||||
protected void onDeathUpdate() {
|
||||
++this.deathTime;
|
||||
if (this.deathTime >= 20 && !this.removed) {
|
||||
if (!this.world.isRemote && (this.isPlayer() || this.recentlyHit > 0 && this.canDropLoot() && this.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT))) {
|
||||
int i = this.expToDrop;
|
||||
while (i > 0) {
|
||||
int j = ExperienceOrbEntity.getXPSplit(i);
|
||||
i -= j;
|
||||
this.world.addEntity(new ExperienceOrbEntity(this.world, this.posX, this.posY, this.posZ, j));
|
||||
}
|
||||
this.expToDrop = 0;
|
||||
}
|
||||
|
||||
this.remove((Object) this instanceof ServerPlayerEntity); //Forge keep data until we revive player
|
||||
|
||||
for (int k = 0; k < 20; ++k) {
|
||||
double d2 = this.rand.nextGaussian() * 0.02D;
|
||||
double d0 = this.rand.nextGaussian() * 0.02D;
|
||||
double d1 = this.rand.nextGaussian() * 0.02D;
|
||||
this.world.addParticle(ParticleTypes.POOF, this.posX + (double) (this.rand.nextFloat() * this.getWidth() * 2.0F) - (double) this.getWidth(), this.posY + (double) (this.rand.nextFloat() * this.getHeight()), this.posZ + (double) (this.rand.nextFloat() * this.getWidth() * 2.0F) - (double) this.getWidth(), d2, d0, d1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "readAdditional", at = @At("HEAD"))
|
||||
public void arclight$readMaxHealth(CompoundNBT compound, CallbackInfo ci) {
|
||||
if (compound.contains("Bukkit.MaxHealth")) {
|
||||
@ -262,160 +221,11 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isTickingEffects = false;
|
||||
private List<Map.Entry<Either<EffectInstance, Effect>, EntityPotionEffectEvent.Cause>> effectsToProcess = Lists.newArrayList();
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
*/
|
||||
@Overwrite
|
||||
protected void updatePotionEffects() {
|
||||
this.isTickingEffects = true;
|
||||
Iterator<Effect> iterator = this.activePotionsMap.keySet().iterator();
|
||||
|
||||
try {
|
||||
while (iterator.hasNext()) {
|
||||
Effect effect = iterator.next();
|
||||
EffectInstance effectinstance = this.activePotionsMap.get(effect);
|
||||
if (!effectinstance.tick((LivingEntity) (Object) this)) {
|
||||
if (!this.world.isRemote && !MinecraftForge.EVENT_BUS.post(new PotionEvent.PotionExpiryEvent((LivingEntity) (Object) this, effectinstance))) {
|
||||
|
||||
EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent((LivingEntity) (Object) this, effectinstance, null, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.EXPIRATION);
|
||||
if (event.isCancelled()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
iterator.remove();
|
||||
this.onFinishedPotionEffect(effectinstance);
|
||||
}
|
||||
} else if (effectinstance.getDuration() % 600 == 0) {
|
||||
this.onChangedPotionEffect(effectinstance, false);
|
||||
}
|
||||
}
|
||||
} catch (ConcurrentModificationException ignored) {
|
||||
}
|
||||
|
||||
isTickingEffects = false;
|
||||
for (Map.Entry<Either<EffectInstance, Effect>, EntityPotionEffectEvent.Cause> e : effectsToProcess) {
|
||||
Either<EffectInstance, Effect> either = e.getKey();
|
||||
EntityPotionEffectEvent.Cause cause = e.getValue();
|
||||
bridge$pushEffectCause(cause);
|
||||
if (either.left().isPresent()) {
|
||||
addPotionEffect(either.left().get());
|
||||
} else {
|
||||
removePotionEffect(either.right().get());
|
||||
}
|
||||
}
|
||||
effectsToProcess.clear();
|
||||
|
||||
if (this.potionsNeedUpdate) {
|
||||
if (!this.world.isRemote) {
|
||||
this.updatePotionMetadata();
|
||||
}
|
||||
|
||||
this.potionsNeedUpdate = false;
|
||||
}
|
||||
|
||||
int i = this.dataManager.get(POTION_EFFECTS);
|
||||
boolean flag1 = this.dataManager.get(HIDE_PARTICLES);
|
||||
if (i > 0) {
|
||||
boolean flag;
|
||||
if (this.isInvisible()) {
|
||||
flag = this.rand.nextInt(15) == 0;
|
||||
} else {
|
||||
flag = this.rand.nextBoolean();
|
||||
}
|
||||
|
||||
if (flag1) {
|
||||
flag &= this.rand.nextInt(5) == 0;
|
||||
}
|
||||
|
||||
if (flag && i > 0) {
|
||||
double d0 = (double) (i >> 16 & 255) / 255.0D;
|
||||
double d1 = (double) (i >> 8 & 255) / 255.0D;
|
||||
double d2 = (double) (i >> 0 & 255) / 255.0D;
|
||||
this.world.addParticle(flag1 ? ParticleTypes.AMBIENT_ENTITY_EFFECT : ParticleTypes.ENTITY_EFFECT, this.posX + (this.rand.nextDouble() - 0.5D) * (double) this.getWidth(), this.posY + this.rand.nextDouble() * (double) this.getHeight(), this.posZ + (this.rand.nextDouble() - 0.5D) * (double) this.getWidth(), d0, d1, d2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "clearActivePotions", at = @At(value = "INVOKE", remap = false, target = "Lnet/minecraftforge/eventbus/api/IEventBus;post(Lnet/minecraftforge/eventbus/api/Event;)Z"))
|
||||
public void arclight$clearReason(CallbackInfoReturnable<Boolean> cir) {
|
||||
arclight$action = EntityPotionEffectEvent.Action.CLEARED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
*/
|
||||
@Overwrite
|
||||
public boolean addPotionEffect(EffectInstance effectInstanceIn) {
|
||||
EntityPotionEffectEvent.Cause cause = arclight$cause == null ? EntityPotionEffectEvent.Cause.UNKNOWN : arclight$cause;
|
||||
arclight$cause = null;
|
||||
if (isTickingEffects) {
|
||||
effectsToProcess.add(Maps.immutableEntry(Either.left(effectInstanceIn), cause));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!this.isPotionApplicable(effectInstanceIn)) {
|
||||
return false;
|
||||
} else {
|
||||
EffectInstance effectinstance = this.activePotionsMap.get(effectInstanceIn.getPotion());
|
||||
|
||||
boolean override = false;
|
||||
if (effectinstance != null) {
|
||||
override = new EffectInstance(effectinstance).combine(effectInstanceIn);
|
||||
}
|
||||
|
||||
EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent((LivingEntity) (Object) this, effectinstance, effectInstanceIn, cause, override);
|
||||
if (event.isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MinecraftForge.EVENT_BUS.post(new PotionEvent.PotionAddedEvent((LivingEntity) (Object) this, effectinstance, effectInstanceIn));
|
||||
if (effectinstance == null) {
|
||||
this.activePotionsMap.put(effectInstanceIn.getPotion(), effectInstanceIn);
|
||||
this.onNewPotionEffect(effectInstanceIn);
|
||||
return true;
|
||||
} else if (event.isOverride()) {
|
||||
effectinstance.combine(effectInstanceIn);
|
||||
this.onChangedPotionEffect(effectinstance, true);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused") // mock
|
||||
public EffectInstance c(@Nullable Effect potioneffectin, EntityPotionEffectEvent.Cause cause) {
|
||||
bridge$pushEffectCause(cause);
|
||||
return removeActivePotionEffect(potioneffectin);
|
||||
}
|
||||
|
||||
@Inject(method = "removeActivePotionEffect", at = @At("HEAD"))
|
||||
public void arclight$clearActive(Effect effect, CallbackInfoReturnable<EffectInstance> cir) {
|
||||
EntityPotionEffectEvent.Cause cause = arclight$cause == null ? EntityPotionEffectEvent.Cause.UNKNOWN : arclight$cause;
|
||||
arclight$cause = null;
|
||||
if (isTickingEffects) {
|
||||
effectsToProcess.add(Maps.immutableEntry(Either.right(effect), cause));
|
||||
cir.setReturnValue(null);
|
||||
return;
|
||||
}
|
||||
|
||||
EffectInstance effectInstance = this.activePotionsMap.get(effect);
|
||||
if (effectInstance == null) {
|
||||
cir.setReturnValue(null);
|
||||
return;
|
||||
}
|
||||
|
||||
EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent((LivingEntity) (Object) this, effectInstance, null, cause);
|
||||
if (event.isCancelled()) {
|
||||
cir.setReturnValue(null);
|
||||
}
|
||||
}
|
||||
|
||||
private transient EntityPotionEffectEvent.Action arclight$action;
|
||||
|
||||
@Override
|
||||
@ -669,6 +479,11 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
|
||||
float absorptionModifier = absorption.apply((double) f).floatValue();
|
||||
|
||||
EntityDamageEvent event = CraftEventFactory.handleLivingEntityDamageEvent((LivingEntity) (Object) this, damagesource, originalDamage, hardHatModifier, blockingModifier, armorModifier, resistanceModifier, magicModifier, absorptionModifier, hardHat, blocking, armor, resistance, magic, absorption);
|
||||
|
||||
if (damagesource.getTrueSource() instanceof PlayerEntity) {
|
||||
((PlayerEntity) damagesource.getTrueSource()).resetCooldown();
|
||||
}
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
@ -877,20 +692,6 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
|
||||
}
|
||||
}
|
||||
|
||||
private transient boolean arclight$fallSuccess;
|
||||
|
||||
@Inject(method = "fall", 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, CallbackInfo ci) {
|
||||
if (!arclight$fallSuccess) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(method = "fall", 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);
|
||||
}
|
||||
|
||||
@Redirect(method = "applyArmorCalculations", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;damageArmor(F)V"))
|
||||
public void arclight$muteDamageArmor(LivingEntity livingEntity, float damage) {
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ 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.mod.ArclightMod;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
@ -37,7 +38,6 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import io.izzel.arclight.common.mod.ArclightMod;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@ -66,6 +66,13 @@ public abstract class MobEntityMixin extends LivingEntityMixin implements MobEnt
|
||||
@Shadow public abstract boolean isAIDisabled();
|
||||
// @formatter:on
|
||||
|
||||
public boolean aware;
|
||||
|
||||
@Override
|
||||
public void bridge$setAware(boolean aware) {
|
||||
this.aware = aware;
|
||||
}
|
||||
|
||||
@Inject(method = "setCanPickUpLoot", at = @At("HEAD"))
|
||||
public void arclight$setPickupLoot(boolean canPickup, CallbackInfo ci) {
|
||||
super.canPickUpLoot = canPickup;
|
||||
@ -83,6 +90,7 @@ public abstract class MobEntityMixin extends LivingEntityMixin implements MobEnt
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
private void arclight$init(EntityType<? extends MobEntity> type, World worldIn, CallbackInfo ci) {
|
||||
this.persistenceRequired = !this.canDespawn(0.0);
|
||||
this.aware = true;
|
||||
}
|
||||
|
||||
private transient AtomicBoolean arclight$targetSuccess;
|
||||
@ -155,6 +163,18 @@ public abstract class MobEntityMixin extends LivingEntityMixin implements MobEnt
|
||||
arclight$fireEvent = fireEvent;
|
||||
}
|
||||
|
||||
@Inject(method = "writeAdditional", at = @At("HEAD"))
|
||||
private void arclight$setAware(CompoundNBT compound, CallbackInfo ci) {
|
||||
compound.putBoolean("Bukkit.Aware", this.aware);
|
||||
}
|
||||
|
||||
@Inject(method = "readAdditional", at = @At("HEAD"))
|
||||
private void arclight$readAware(CompoundNBT compound, CallbackInfo ci) {
|
||||
if (compound.contains("Bukkit.Aware")) {
|
||||
this.aware = compound.getBoolean("Bukkit.Aware");
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(method = "readAdditional", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/MobEntity;setCanPickUpLoot(Z)V"))
|
||||
public void arclight$setIfTrue(MobEntity mobEntity, boolean canPickup) {
|
||||
if (canPickup) mobEntity.setCanPickUpLoot(true);
|
||||
@ -165,6 +185,14 @@ public abstract class MobEntityMixin extends LivingEntityMixin implements MobEnt
|
||||
return nbt.getBoolean(key) || this.persistenceRequired;
|
||||
}
|
||||
|
||||
@Inject(method = "updateEntityActionState", cancellable = true, at = @At("HEAD"))
|
||||
private void arclight$unaware(CallbackInfo ci) {
|
||||
if (!this.aware) {
|
||||
++this.idleTime;
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
|
||||
@ -3,6 +3,7 @@ package io.izzel.arclight.common.mixin.core.entity.item;
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.izzel.arclight.common.bridge.entity.LivingEntityBridge;
|
||||
import io.izzel.arclight.common.bridge.entity.player.PlayerEntityBridge;
|
||||
import io.izzel.arclight.common.bridge.entity.player.PlayerInventoryBridge;
|
||||
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
||||
import io.izzel.arclight.common.bridge.network.datasync.EntityDataManagerBridge;
|
||||
import io.izzel.arclight.common.mixin.core.entity.EntityMixin;
|
||||
@ -23,10 +24,8 @@ import org.spongepowered.asm.mixin.Overwrite;
|
||||
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.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import io.izzel.arclight.common.bridge.entity.player.PlayerInventoryBridge;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@ -38,7 +37,6 @@ public abstract class ItemEntityMixin extends EntityMixin {
|
||||
@Shadow public int pickupDelay;
|
||||
@Shadow public abstract ItemStack getItem();
|
||||
@Shadow private UUID owner;
|
||||
@Shadow public int age;
|
||||
// @formatter:on
|
||||
|
||||
@Inject(method = "func_213858_a", cancellable = true, at = @At("HEAD"))
|
||||
@ -48,13 +46,6 @@ public abstract class ItemEntityMixin extends EntityMixin {
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(method = "func_213858_a", at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/entity/item/ItemEntity;setItem(Lnet/minecraft/item/ItemStack;)V"))
|
||||
private static void arclight$setNonEmpty(ItemEntity itemEntity, ItemStack stack) {
|
||||
if (!stack.isEmpty()) {
|
||||
itemEntity.setItem(stack);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "attackEntityFrom", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/item/ItemEntity;markVelocityChanged()V"))
|
||||
private void arclight$damageNonLiving(DamageSource source, float amount, CallbackInfoReturnable<Boolean> cir) {
|
||||
if (CraftEventFactory.handleNonLivingEntityDamageEvent((ItemEntity) (Object) this, source, amount)) {
|
||||
@ -109,7 +100,7 @@ public abstract class ItemEntityMixin extends EntityMixin {
|
||||
} else if (this.pickupDelay == 0) {
|
||||
this.pickupDelay = -1;
|
||||
}
|
||||
if (this.pickupDelay == 0 && (this.owner == null || 6000 - this.age <= 200 || this.owner.equals(entity.getUniqueID())) && entity.inventory.addItemStackToInventory(itemstack)) {
|
||||
if (this.pickupDelay == 0 && (this.owner == null /*|| 6000 - this.age <= 200*/ || this.owner.equals(entity.getUniqueID())) && entity.inventory.addItemStackToInventory(itemstack)) {
|
||||
entity.onItemPickup((ItemEntity) (Object) this, i);
|
||||
if (itemstack.isEmpty()) {
|
||||
this.remove();
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package io.izzel.arclight.common.mixin.core.entity.item;
|
||||
|
||||
import io.izzel.arclight.api.ArclightVersion;
|
||||
import io.izzel.arclight.common.mixin.core.entity.EntityMixin;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
@ -44,9 +45,11 @@ public abstract class TNTEntityMixin extends EntityMixin {
|
||||
*/
|
||||
@Overwrite
|
||||
public void tick() {
|
||||
if (ArclightVersion.lesserThan(ArclightVersion.v1_15)) {
|
||||
this.prevPosX = this.posX;
|
||||
this.prevPosY = this.posY;
|
||||
this.prevPosZ = this.posZ;
|
||||
}
|
||||
if (!this.hasNoGravity()) {
|
||||
this.setMotion(this.getMotion().add(0.0D, -0.04D, 0.0D));
|
||||
}
|
||||
@ -65,9 +68,11 @@ public abstract class TNTEntityMixin extends EntityMixin {
|
||||
this.remove();
|
||||
} else {
|
||||
this.handleWaterMovement();
|
||||
if (this.world.isRemote) {
|
||||
this.world.addParticle(ParticleTypes.SMOKE, this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
|
||||
@ -160,9 +160,11 @@ public abstract class AbstractMinecartEntityMixin extends EntityMixin {
|
||||
this.setRotation(this.rotationYaw, this.rotationPitch);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
this.prevPosX = this.posX;
|
||||
this.prevPosY = this.posY;
|
||||
this.prevPosZ = this.posZ;
|
||||
*/
|
||||
if (!this.hasNoGravity()) {
|
||||
this.setMotion(this.getMotion().add(0.0, -0.04, 0.0));
|
||||
}
|
||||
@ -217,12 +219,15 @@ public abstract class AbstractMinecartEntityMixin extends EntityMixin {
|
||||
entity.startRiding((AbstractMinecartEntity) (Object) this);
|
||||
}
|
||||
} else {
|
||||
if (!isRidingSameEntity(entity)) {
|
||||
VehicleEntityCollisionEvent collisionEvent = new VehicleEntityCollisionEvent(vehicle, ((EntityBridge) entity).bridge$getBukkitEntity());
|
||||
Bukkit.getPluginManager().callEvent(collisionEvent);
|
||||
if (!collisionEvent.isCancelled()) {
|
||||
entity.applyEntityCollision((AbstractMinecartEntity) (Object) this);
|
||||
if (collisionEvent.isCancelled()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
entity.applyEntityCollision((AbstractMinecartEntity) (Object) this);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -273,14 +278,16 @@ public abstract class AbstractMinecartEntityMixin extends EntityMixin {
|
||||
return this.isBeingRidden() || !this.slowWhenEmpty;
|
||||
}
|
||||
|
||||
@Inject(method = "applyEntityCollision", at = @At(value = "FIELD", ordinal = 0, target = "Lnet/minecraft/entity/Entity;posX:D"))
|
||||
@Inject(method = "applyEntityCollision", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/item/minecart/AbstractMinecartEntity;isPassenger(Lnet/minecraft/entity/Entity;)Z"))
|
||||
private void arclight$vehicleCollide(Entity entityIn, CallbackInfo ci) {
|
||||
if (!this.isPassenger(entityIn)) {
|
||||
VehicleEntityCollisionEvent collisionEvent = new VehicleEntityCollisionEvent((Vehicle) this.getBukkitEntity(), ((EntityBridge) entityIn).bridge$getBukkitEntity());
|
||||
Bukkit.getPluginManager().callEvent(collisionEvent);
|
||||
if (collisionEvent.isCancelled()) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector getFlyingVelocityMod() {
|
||||
return new Vector(flyingX, flyingY, flyingZ);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package io.izzel.arclight.common.mixin.core.entity.monster;
|
||||
|
||||
import io.izzel.arclight.api.ArclightVersion;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
@ -46,7 +47,11 @@ public abstract class SilverfishEntity_SummonSilverfishGoalMixin extends Goal {
|
||||
continue;
|
||||
}
|
||||
if (ForgeEventFactory.getMobGriefingEvent(world, this.silverfish)) {
|
||||
if (ArclightVersion.atLeast(ArclightVersion.v1_15)) {
|
||||
world.destroyBlock(blockpos1, true, this.silverfish);
|
||||
} else {
|
||||
world.destroyBlock(blockpos1, true);
|
||||
}
|
||||
} else {
|
||||
world.setBlockState(blockpos1, ((SilverfishBlock) block).getMimickedBlock().getDefaultState(), 3);
|
||||
}
|
||||
|
||||
@ -55,6 +55,7 @@ public abstract class SlimeEntityMixin extends MobEntityMixin {
|
||||
if (this.isNoDespawnRequired()) {
|
||||
entityslime.enablePersistence();
|
||||
}
|
||||
entityslime.setInvulnerable(this.isInvulnerable());
|
||||
entityslime.setSlimeSize(i / 2, true);
|
||||
entityslime.setLocationAndAngles(this.posX + f, this.posY + 0.5, this.posZ + f2, this.rand.nextFloat() * 360.0f, 0.0f);
|
||||
slimes.add(entityslime);
|
||||
|
||||
@ -33,11 +33,11 @@ public abstract class ZombieVillagerEntityMixin extends ZombieEntityMixin {
|
||||
bridge$pushEffectCause(EntityPotionEffectEvent.Cause.CONVERSION);
|
||||
}
|
||||
|
||||
@Redirect(method = "func_213791_a", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/monster/ZombieVillagerEntity;remove()V"))
|
||||
@Redirect(method = "cureZombie", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/monster/ZombieVillagerEntity;remove()V"))
|
||||
private void arclight$transformPre(ZombieVillagerEntity zombieVillagerEntity) {
|
||||
}
|
||||
|
||||
@Inject(method = "func_213791_a", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;addEntity(Lnet/minecraft/entity/Entity;)Z"))
|
||||
@Inject(method = "cureZombie", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;addEntity(Lnet/minecraft/entity/Entity;)Z"))
|
||||
private void arclight$transform(ServerWorld world, CallbackInfo ci, VillagerEntity villagerEntity) {
|
||||
if (CraftEventFactory.callEntityTransformEvent((ZombieVillagerEntity)(Object)this, villagerEntity, EntityTransformEvent.TransformReason.CURED).isCancelled()) {
|
||||
((ZombieVillager) getBukkitEntity()).setConversionTime(-1);
|
||||
|
||||
@ -1,14 +1,9 @@
|
||||
package io.izzel.arclight.common.mixin.core.entity.passive;
|
||||
|
||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||
import net.minecraft.entity.passive.OcelotEntity;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
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;
|
||||
|
||||
@Mixin(OcelotEntity.class)
|
||||
public abstract class OcelotEntityMixin extends AnimalEntityMixin {
|
||||
@ -27,9 +22,4 @@ public abstract class OcelotEntityMixin extends AnimalEntityMixin {
|
||||
public boolean canDespawn(double distanceToClosestPlayer) {
|
||||
return !this.isTrusting() /*&& this.ticksExisted > 2400*/;
|
||||
}
|
||||
|
||||
@Inject(method = "func_213525_dW", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;addEntity(Lnet/minecraft/entity/Entity;)Z"))
|
||||
private void arclight$spawnBaby(CallbackInfo ci) {
|
||||
((WorldBridge) this.world).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.OCELOT_BABY);
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ import java.util.function.Predicate;
|
||||
@Mixin(PandaEntity.class)
|
||||
public abstract class PandaEntityMixin extends AnimalEntityMixin {
|
||||
|
||||
@Shadow @Final private static Predicate<ItemEntity> field_213607_bQ;
|
||||
@Shadow @Final private static Predicate<ItemEntity> PANDA_ITEMS;
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
@ -23,7 +23,7 @@ public abstract class PandaEntityMixin extends AnimalEntityMixin {
|
||||
*/
|
||||
@Overwrite
|
||||
protected void updateEquipmentIfNeeded(ItemEntity itemEntity) {
|
||||
boolean cancel = this.getItemStackFromSlot(EquipmentSlotType.MAINHAND).isEmpty() && field_213607_bQ.test(itemEntity);
|
||||
boolean cancel = this.getItemStackFromSlot(EquipmentSlotType.MAINHAND).isEmpty() && PANDA_ITEMS.test(itemEntity);
|
||||
if (CraftEventFactory.callEntityPickupItemEvent((PandaEntity) (Object) this, itemEntity, 0, cancel).isCancelled()) {
|
||||
ItemStack itemstack = itemEntity.getItem();
|
||||
this.setItemStackToSlot(EquipmentSlotType.MAINHAND, itemstack);
|
||||
|
||||
@ -37,7 +37,7 @@ public abstract class SheepEntityMixin extends AnimalEntityMixin {
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "func_213611_a", locals = LocalCapture.CAPTURE_FAILHARD, at = @At("RETURN"))
|
||||
@Inject(method = "createDyeColorCraftingInventory", locals = LocalCapture.CAPTURE_FAILHARD, at = @At("RETURN"))
|
||||
private static void arclight$resultInv(DyeColor p_213611_0_, DyeColor p_213611_1_, CallbackInfoReturnable<CraftingInventory> cir, CraftingInventory craftingInventory) {
|
||||
((CraftingInventoryBridge) craftingInventory).bridge$setResultInventory(new CraftResultInventory());
|
||||
}
|
||||
|
||||
@ -19,11 +19,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
@Mixin(WolfEntity.class)
|
||||
public abstract class WolfEntityMixin extends TameableEntityMixin {
|
||||
|
||||
@Shadow
|
||||
public abstract void setAngry(boolean angry);
|
||||
|
||||
@Shadow
|
||||
public abstract boolean isAngry();
|
||||
// @formatter:off
|
||||
@Shadow public abstract void setAngry(boolean angry);
|
||||
@Shadow public abstract boolean isAngry();
|
||||
// @formatter:on
|
||||
|
||||
@Override
|
||||
public boolean setGoalTarget(LivingEntity entityliving, EntityTargetEvent.TargetReason reason, boolean fire) {
|
||||
@ -54,6 +53,11 @@ public abstract class WolfEntityMixin extends TameableEntityMixin {
|
||||
private void arclight$handledBy(SitGoal sitGoal, boolean sitting) {
|
||||
}
|
||||
|
||||
@Redirect(method = "setTamed", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/passive/WolfEntity;setHealth(F)V"))
|
||||
private void arclight$healToMax(WolfEntity wolfEntity, float health) {
|
||||
wolfEntity.setHealth(wolfEntity.getMaxHealth());
|
||||
}
|
||||
|
||||
@Inject(method = "processInteract", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/passive/WolfEntity;heal(F)V"))
|
||||
private void arclight$healReason(PlayerEntity player, Hand hand, CallbackInfoReturnable<Boolean> cir) {
|
||||
bridge$pushHealReason(EntityRegainHealthEvent.RegainReason.EATING);
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
package io.izzel.arclight.common.mixin.core.entity.player;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
||||
import io.izzel.arclight.common.bridge.entity.InternalEntityBridge;
|
||||
import io.izzel.arclight.common.bridge.entity.player.PlayerEntityBridge;
|
||||
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
||||
import io.izzel.arclight.common.bridge.inventory.IInventoryBridge;
|
||||
import io.izzel.arclight.common.bridge.util.DamageSourceBridge;
|
||||
import io.izzel.arclight.common.bridge.util.FoodStatsBridge;
|
||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||
import io.izzel.arclight.common.bridge.world.server.ServerWorldBridge;
|
||||
import io.izzel.arclight.common.mixin.core.entity.LivingEntityMixin;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.CreatureAttribute;
|
||||
import net.minecraft.entity.Entity;
|
||||
@ -23,6 +24,7 @@ import net.minecraft.entity.player.PlayerAbilities;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.inventory.EnderChestInventory;
|
||||
import net.minecraft.inventory.container.Container;
|
||||
import net.minecraft.inventory.container.PlayerContainer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@ -35,14 +37,12 @@ import net.minecraft.scoreboard.Scoreboard;
|
||||
import net.minecraft.stats.Stat;
|
||||
import net.minecraft.stats.Stats;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.FoodStats;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.HandSide;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
@ -53,18 +53,16 @@ import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v.block.CraftBlock;
|
||||
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||
import org.bukkit.craftbukkit.v.util.CraftVector;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.event.entity.EntityCombustByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityPotionEffectEvent;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||
import org.bukkit.event.player.PlayerBedLeaveEvent;
|
||||
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||
import org.bukkit.event.player.PlayerVelocityEvent;
|
||||
import org.bukkit.scoreboard.Team;
|
||||
@ -75,25 +73,18 @@ import org.spongepowered.asm.mixin.Overwrite;
|
||||
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.ModifyVariable;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
import io.izzel.arclight.common.bridge.util.DamageSourceBridge;
|
||||
import io.izzel.arclight.common.mixin.core.entity.LivingEntityMixin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Mixin(PlayerEntity.class)
|
||||
public abstract class PlayerEntityMixin extends LivingEntityMixin implements PlayerEntityBridge {
|
||||
|
||||
// @formatter:off
|
||||
@Shadow public int sleepTimer;
|
||||
@Shadow public abstract String getScoreboardName();
|
||||
@Shadow public abstract Either<PlayerEntity.SleepResult, Unit> trySleep(BlockPos at);
|
||||
@Shadow public abstract void startSleeping(BlockPos p_213342_1_);
|
||||
@Shadow @Final public PlayerAbilities abilities;
|
||||
@Shadow public abstract float getCooledAttackStrength(float adjustTicks);
|
||||
@Shadow public abstract void resetCooldown();
|
||||
@ -104,7 +95,7 @@ public abstract class PlayerEntityMixin extends LivingEntityMixin implements Pla
|
||||
@Shadow public abstract void onEnchantmentCritical(Entity entityHit);
|
||||
@Shadow public abstract void addStat(ResourceLocation p_195067_1_, int p_195067_2_);
|
||||
@Shadow public abstract void addExhaustion(float exhaustion);
|
||||
@Shadow private long field_223730_e;
|
||||
@Shadow private long timeEntitySatOnShoulder;
|
||||
@Shadow public abstract void setRightShoulderEntity(CompoundNBT tag);
|
||||
@Shadow public abstract void setLeftShoulderEntity(CompoundNBT tag);
|
||||
@Shadow public abstract CompoundNBT getRightShoulderEntity();
|
||||
@ -123,6 +114,7 @@ public abstract class PlayerEntityMixin extends LivingEntityMixin implements Pla
|
||||
@Shadow protected FoodStats foodStats;
|
||||
@Shadow protected boolean isMovementBlocked() { return false; }
|
||||
@Shadow public abstract Scoreboard getWorldScoreboard();
|
||||
@Shadow protected EnderChestInventory enterChestInventory;
|
||||
// @formatter:on
|
||||
|
||||
public boolean fauxSleeping;
|
||||
@ -133,6 +125,7 @@ public abstract class PlayerEntityMixin extends LivingEntityMixin implements Pla
|
||||
private void arclight$init(World worldIn, GameProfile gameProfileIn, CallbackInfo ci) {
|
||||
oldLevel = -1;
|
||||
((FoodStatsBridge) this.foodStats).bridge$setEntityHuman((PlayerEntity) (Object) this);
|
||||
((IInventoryBridge) this.enterChestInventory).setOwner(((HumanEntity) this.getBukkitEntity()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -422,92 +415,9 @@ public abstract class PlayerEntityMixin extends LivingEntityMixin implements Pla
|
||||
}
|
||||
}
|
||||
|
||||
private boolean arclight$forceSleep = false;
|
||||
private Object arclight$processSleep = null;
|
||||
|
||||
public CraftHumanEntity getBukkitEntity() {
|
||||
return (CraftHumanEntity) ((InternalEntityBridge) this).internal$getBukkitEntity();
|
||||
}
|
||||
|
||||
private Either<PlayerEntity.SleepResult, Unit> getBedResult(BlockPos at, Direction direction) {
|
||||
arclight$processSleep = true;
|
||||
Either<PlayerEntity.SleepResult, Unit> either = this.trySleep(at);
|
||||
arclight$processSleep = null;
|
||||
return either;
|
||||
}
|
||||
|
||||
public Either<PlayerEntity.SleepResult, Unit> sleep(BlockPos at, boolean force) {
|
||||
arclight$forceSleep = force;
|
||||
try {
|
||||
return this.trySleep(at);
|
||||
} finally {
|
||||
arclight$forceSleep = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "trySleep", cancellable = true, at = @At(value = "HEAD"))
|
||||
public void arclight$onSleep(BlockPos at, CallbackInfoReturnable<Either<PlayerEntity.SleepResult, Unit>> cir) {
|
||||
if (arclight$processSleep == null) {
|
||||
Either<PlayerEntity.SleepResult, Unit> result = getBedResult(at, null);
|
||||
|
||||
if (result.left().orElse(null) == PlayerEntity.SleepResult.OTHER_PROBLEM) {
|
||||
cir.setReturnValue(result);
|
||||
return;
|
||||
}
|
||||
if (arclight$forceSleep) {
|
||||
result = Either.right(Unit.INSTANCE);
|
||||
}
|
||||
if (this.bridge$getBukkitEntity() instanceof Player) {
|
||||
result = CraftEventFactory.callPlayerBedEnterEvent((PlayerEntity) (Object) this, at, result);
|
||||
if (result.left().isPresent()) {
|
||||
cir.setReturnValue(result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.startSleeping(at);
|
||||
this.sleepTimer = 0;
|
||||
if (this.world instanceof ServerWorld) {
|
||||
((ServerWorld) this.world).updateAllPlayersSleepingFlag();
|
||||
}
|
||||
cir.setReturnValue(Either.right(Unit.INSTANCE));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "trySleep", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;startSleeping(Lnet/minecraft/util/math/BlockPos;)V"))
|
||||
public void arclight$preSleep(BlockPos at, CallbackInfoReturnable<Either<PlayerEntity.SleepResult, Unit>> cir) {
|
||||
if (arclight$processSleep != null) {
|
||||
cir.setReturnValue(Either.right(Unit.INSTANCE));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "wakeUpPlayer", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "FIELD", target = "Lnet/minecraft/entity/player/PlayerEntity;sleepTimer:I"))
|
||||
private void arclight$wakeup(boolean immediately, boolean updateWorldFlag, boolean setSpawn, CallbackInfo ci, Optional<BlockPos> optional) {
|
||||
if (this.getBukkitEntity() instanceof Player) {
|
||||
final Player player = (Player) this.getBukkitEntity();
|
||||
final BlockPos blockposition2 = optional.orElse(null);
|
||||
Block bed;
|
||||
if (blockposition2 != null) {
|
||||
bed = CraftBlock.at(this.world, blockposition2);
|
||||
} else {
|
||||
bed = ((WorldBridge) this.world).bridge$getWorld().getBlockAt(player.getLocation());
|
||||
}
|
||||
final PlayerBedLeaveEvent event = new PlayerBedLeaveEvent(player, bed, setSpawn);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
arclight$setSpawn = event.shouldSetSpawnLocation();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean arclight$setSpawn;
|
||||
|
||||
@ModifyVariable(method = "wakeUpPlayer", index = 3, name = "setSpawn", at = @At(value = "FIELD", shift = At.Shift.AFTER, target = "Lnet/minecraft/entity/player/PlayerEntity;sleepTimer:I"))
|
||||
private boolean arclight$modifySpawn(boolean setSpawn) {
|
||||
return arclight$setSpawn;
|
||||
}
|
||||
|
||||
@Inject(method = "setSpawnPoint(Lnet/minecraft/util/math/BlockPos;Z)V", at = @At("RETURN"))
|
||||
private void arclight$updateSpawnpoint(BlockPos pos, boolean forced, CallbackInfo ci) {
|
||||
this.spawnWorld = pos == null ? "" : this.world.worldInfo.getWorldName();
|
||||
@Override
|
||||
public void bridge$setSpawnWorld(String world) {
|
||||
this.spawnWorld = world;
|
||||
}
|
||||
|
||||
@Redirect(method = "travel", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;setFlag(IZ)V"))
|
||||
@ -523,7 +433,7 @@ public abstract class PlayerEntityMixin extends LivingEntityMixin implements Pla
|
||||
*/
|
||||
@Overwrite
|
||||
protected void spawnShoulderEntities() {
|
||||
if (this.field_223730_e + 20L < this.world.getGameTime()) {
|
||||
if (this.timeEntitySatOnShoulder + 20L < this.world.getGameTime()) {
|
||||
if (this.spawnEntityFromShoulder(this.getLeftShoulderEntity())) {
|
||||
this.setLeftShoulderEntity(new CompoundNBT());
|
||||
}
|
||||
@ -548,11 +458,6 @@ public abstract class PlayerEntityMixin extends LivingEntityMixin implements Pla
|
||||
return (CraftHumanEntity) ((InternalEntityBridge) this).internal$getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Either<PlayerEntity.SleepResult, Unit> bridge$trySleep(BlockPos at, boolean force) {
|
||||
return sleep(at, force);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String bridge$getSpawnWorld() {
|
||||
return spawnWorld;
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package io.izzel.arclight.common.mixin.core.entity.player;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
||||
import io.izzel.arclight.common.bridge.entity.InternalEntityBridge;
|
||||
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
||||
@ -9,12 +8,8 @@ import io.izzel.arclight.common.bridge.inventory.container.ContainerBridge;
|
||||
import io.izzel.arclight.common.bridge.util.FoodStatsBridge;
|
||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||
import io.izzel.arclight.common.mod.util.ChestBlockDoubleInventoryHacks;
|
||||
import net.minecraft.advancements.CriteriaTriggers;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.boss.WitherEntity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.passive.horse.AbstractHorseEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
@ -24,7 +19,6 @@ import net.minecraft.inventory.container.Container;
|
||||
import net.minecraft.inventory.container.HorseInventoryContainer;
|
||||
import net.minecraft.inventory.container.INamedContainerProvider;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.item.crafting.RecipeBook;
|
||||
import net.minecraft.item.crafting.ServerRecipeBook;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
@ -33,21 +27,14 @@ import net.minecraft.network.play.client.CClientSettingsPacket;
|
||||
import net.minecraft.network.play.server.SChangeGameStatePacket;
|
||||
import net.minecraft.network.play.server.SCombatPacket;
|
||||
import net.minecraft.network.play.server.SOpenHorseWindowPacket;
|
||||
import net.minecraft.network.play.server.SPlayEntityEffectPacket;
|
||||
import net.minecraft.network.play.server.SPlaySoundEventPacket;
|
||||
import net.minecraft.network.play.server.SPlayerAbilitiesPacket;
|
||||
import net.minecraft.network.play.server.SRespawnPacket;
|
||||
import net.minecraft.network.play.server.SServerDifficultyPacket;
|
||||
import net.minecraft.network.play.server.SSetSlotPacket;
|
||||
import net.minecraft.network.play.server.SUpdateHealthPacket;
|
||||
import net.minecraft.potion.EffectInstance;
|
||||
import net.minecraft.scoreboard.Score;
|
||||
import net.minecraft.scoreboard.ScoreCriteria;
|
||||
import net.minecraft.scoreboard.Scoreboard;
|
||||
import net.minecraft.scoreboard.Team;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.management.PlayerInteractionManager;
|
||||
import net.minecraft.server.management.PlayerList;
|
||||
import net.minecraft.stats.Stat;
|
||||
import net.minecraft.stats.Stats;
|
||||
import net.minecraft.util.CombatTracker;
|
||||
@ -55,7 +42,6 @@ import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.FoodStats;
|
||||
import net.minecraft.util.HandSide;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
@ -67,9 +53,7 @@ import net.minecraft.util.text.event.HoverEvent;
|
||||
import net.minecraft.world.GameRules;
|
||||
import net.minecraft.world.GameType;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraft.world.storage.WorldInfo;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
@ -80,18 +64,14 @@ import org.bukkit.craftbukkit.v.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||
import org.bukkit.craftbukkit.v.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.v.scoreboard.CraftScoreboardManager;
|
||||
import org.bukkit.craftbukkit.v.util.BlockStateListPopulator;
|
||||
import org.bukkit.craftbukkit.v.util.CraftChatMessage;
|
||||
import org.bukkit.event.entity.EntityPotionEffectEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.event.player.PlayerChangedMainHandEvent;
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
import org.bukkit.event.player.PlayerGameModeChangeEvent;
|
||||
import org.bukkit.event.player.PlayerLocaleChangeEvent;
|
||||
import org.bukkit.event.player.PlayerPortalEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.event.world.PortalCreateEvent;
|
||||
import org.bukkit.inventory.MainHand;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@ -108,6 +88,7 @@ import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.Random;
|
||||
import java.util.function.Consumer;
|
||||
@ -125,11 +106,11 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntityMixin implemen
|
||||
@Shadow public abstract void closeScreen();
|
||||
@Shadow public abstract void setSpectatingEntity(Entity entityToSpectate);
|
||||
@Shadow public boolean invulnerableDimensionChange;
|
||||
@Shadow public abstract ServerWorld func_71121_q();
|
||||
@Shadow public abstract ServerWorld getServerWorld();
|
||||
@Shadow public boolean queuedEndExit;
|
||||
@Shadow private boolean seenCredits;
|
||||
@Shadow @Nullable private Vec3d enteredNetherPosition;
|
||||
@Shadow protected abstract void func_213846_b(ServerWorld p_213846_1_);
|
||||
@Shadow public abstract void func_213846_b(ServerWorld p_213846_1_);
|
||||
@Shadow public int lastExperience;
|
||||
@Shadow private float lastHealth;
|
||||
@Shadow private int lastFoodLevel;
|
||||
@ -137,7 +118,7 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntityMixin implemen
|
||||
@Shadow public abstract void getNextWindowId();
|
||||
@Shadow public abstract void sendMessage(ITextComponent component);
|
||||
@Shadow public String language;
|
||||
@Shadow public abstract void func_200619_a(ServerWorld p_200619_1_, double x, double y, double z, float yaw, float pitch);
|
||||
@Shadow public abstract void teleport(ServerWorld p_200619_1_, double x, double y, double z, float yaw, float pitch);
|
||||
@Shadow public abstract void giveExperiencePoints(int p_195068_1_);
|
||||
// @formatter:on
|
||||
|
||||
@ -168,7 +149,7 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntityMixin implemen
|
||||
public BlockPos getSpawnPoint(ServerWorld worldserver) {
|
||||
BlockPos blockposition = worldserver.getSpawnPoint();
|
||||
if (worldserver.dimension.hasSkyLight() && worldserver.getWorldInfo().getGameType() != GameType.ADVENTURE) {
|
||||
int i = Math.max(0, this.server.func_184108_a(worldserver));
|
||||
int i = Math.max(0, this.server.getSpawnRadius(worldserver));
|
||||
int j = MathHelper.floor(worldserver.getWorldBorder().getClosestDistance(blockposition.getX(), blockposition.getZ()));
|
||||
if (j < i) {
|
||||
i = j;
|
||||
@ -233,7 +214,7 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntityMixin implemen
|
||||
CraftWorld cworld = (CraftWorld) Bukkit.getServer().getWorld(this.spawnWorld);
|
||||
if (cworld != null && this.getBedLocation() != null) {
|
||||
world = cworld.getHandle();
|
||||
position = PlayerEntity.func_213822_a(cworld.getHandle(), this.getBedLocation(), false).orElse(null);
|
||||
position = PlayerEntity.checkBedValidRespawnPosition(cworld.getHandle(), this.getBedLocation(), false).orElse(null);
|
||||
}
|
||||
}
|
||||
if (world == null || position == null) {
|
||||
@ -244,7 +225,7 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntityMixin implemen
|
||||
this.setPosition(position.getX(), position.getY(), position.getZ());
|
||||
}
|
||||
this.dimension = this.world.getDimension().getType();
|
||||
this.interactionManager.func_73080_a((ServerWorld) world);
|
||||
this.interactionManager.setWorld((ServerWorld) world);
|
||||
}
|
||||
|
||||
@Inject(method = "tick", at = @At("HEAD"))
|
||||
@ -330,31 +311,23 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntityMixin implemen
|
||||
this.connection.sendPacket(new SCombatPacket(this.getCombatTracker(), SCombatPacket.Event.ENTITY_DIED));
|
||||
}
|
||||
this.spawnShoulderEntities();
|
||||
|
||||
this.bridge$dropExperience();
|
||||
|
||||
if (!event.getKeepInventory()) {
|
||||
this.inventory.clear();
|
||||
}
|
||||
this.setSpectatingEntity((ServerPlayerEntity) (Object) this);
|
||||
((CraftScoreboardManager) Bukkit.getScoreboardManager()).getScoreboardScores(ScoreCriteria.DEATH_COUNT, this.getScoreboardName(), Score::incrementScore);
|
||||
|
||||
LivingEntity entityliving = this.getAttackingEntity();
|
||||
if (entityliving != null) {
|
||||
this.addStat(Stats.ENTITY_KILLED_BY.get(entityliving.getType()));
|
||||
entityliving.awardKillScore((ServerPlayerEntity) (Object) this, this.scoreValue, damagesource);
|
||||
if (!this.world.isRemote && entityliving instanceof WitherEntity) {
|
||||
boolean flag3 = false;
|
||||
if (net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, (ServerPlayerEntity) (Object) this)) {
|
||||
BlockPos blockposition = new BlockPos(this.posX, this.posY, this.posZ);
|
||||
BlockState iblockdata = Blocks.WITHER_ROSE.getDefaultState();
|
||||
if (this.world.getBlockState(blockposition).isAir() && iblockdata.isValidPosition(this.world, blockposition)) {
|
||||
this.world.setBlockState(blockposition, iblockdata, 3);
|
||||
flag3 = true;
|
||||
}
|
||||
}
|
||||
if (!flag3) {
|
||||
ItemEntity entityitem = new ItemEntity(this.world, this.posX, this.posY, this.posZ, new ItemStack(Items.WITHER_ROSE));
|
||||
this.world.addEntity(entityitem);
|
||||
}
|
||||
}
|
||||
this.bridge$createWitherRose(entityliving);
|
||||
}
|
||||
|
||||
this.world.setEntityState((ServerPlayerEntity) (Object) this, (byte) 3);
|
||||
this.addStat(Stats.DEATHS);
|
||||
this.takeStat(Stats.CUSTOM.get(Stats.TIME_SINCE_DEATH));
|
||||
this.takeStat(Stats.CUSTOM.get(Stats.TIME_SINCE_REST));
|
||||
@ -378,177 +351,6 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntityMixin implemen
|
||||
cir.setReturnValue(((WorldBridge) this.world).bridge$isPvpMode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
*/
|
||||
@Nullable
|
||||
@Overwrite
|
||||
// todo DimensionType getType
|
||||
public Entity changeDimension(DimensionType dimensionmanager) {
|
||||
PlayerTeleportEvent.TeleportCause cause = arclight$cause == null ? PlayerTeleportEvent.TeleportCause.UNKNOWN : arclight$cause;
|
||||
arclight$cause = null;
|
||||
if (!net.minecraftforge.common.ForgeHooks.onTravelToDimension((ServerPlayerEntity) (Object) this, dimensionmanager))
|
||||
return null;
|
||||
if (this.isSleeping()) {
|
||||
return (ServerPlayerEntity) (Object) this;
|
||||
}
|
||||
DimensionType dimensionmanager2 = this.dimension;
|
||||
if (dimensionmanager2 == DimensionType.THE_END && dimensionmanager == DimensionType.OVERWORLD) {
|
||||
this.invulnerableDimensionChange = true;
|
||||
this.detach();
|
||||
this.func_71121_q().removePlayer((ServerPlayerEntity) (Object) this, true);
|
||||
if (!this.queuedEndExit) {
|
||||
this.queuedEndExit = true;
|
||||
this.connection.sendPacket(new SChangeGameStatePacket(4, this.seenCredits ? 0.0f : 1.0f));
|
||||
this.seenCredits = true;
|
||||
}
|
||||
return (ServerPlayerEntity) (Object) this;
|
||||
}
|
||||
ServerWorld worldserver = this.server.func_71218_a(dimensionmanager2);
|
||||
ServerWorld worldserver2 = this.server.func_71218_a(dimensionmanager);
|
||||
WorldInfo worlddata = this.world.getWorldInfo();
|
||||
double d0 = this.posX;
|
||||
double d2 = this.posY;
|
||||
double d3 = this.posZ;
|
||||
float f = this.rotationPitch;
|
||||
float f2 = this.rotationYaw;
|
||||
double d4 = 8.0;
|
||||
float f3 = f2;
|
||||
worldserver.getProfiler().startSection("moving");
|
||||
if (worldserver2 != null) {
|
||||
if (dimensionmanager2 == DimensionType.OVERWORLD && dimensionmanager == DimensionType.THE_NETHER) {
|
||||
this.enteredNetherPosition = new Vec3d(this.posX, this.posY, this.posZ);
|
||||
d0 /= 8.0;
|
||||
d3 /= 8.0;
|
||||
} else if (dimensionmanager2 == DimensionType.THE_NETHER && dimensionmanager == DimensionType.OVERWORLD) {
|
||||
d0 *= 8.0;
|
||||
d3 *= 8.0;
|
||||
} else if (dimensionmanager2 == DimensionType.OVERWORLD && dimensionmanager == DimensionType.THE_END) {
|
||||
BlockPos blockposition = worldserver2.getSpawnCoordinate();
|
||||
d0 = blockposition.getX();
|
||||
d2 = blockposition.getY();
|
||||
d3 = blockposition.getZ();
|
||||
f2 = 90.0f;
|
||||
f = 0.0f;
|
||||
}
|
||||
}
|
||||
Location enter = this.getBukkitEntity().getLocation();
|
||||
Location exit = (worldserver2 == null) ? null : new Location(((WorldBridge) worldserver2).bridge$getWorld(), d0, d2, d3, f2, f);
|
||||
PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled() || event.getTo() == null) {
|
||||
return null;
|
||||
}
|
||||
exit = event.getTo();
|
||||
if (exit == null) {
|
||||
return null;
|
||||
}
|
||||
PlayerTeleportEvent tpEvent = new PlayerTeleportEvent(this.getBukkitEntity(), enter, exit, cause);
|
||||
Bukkit.getServer().getPluginManager().callEvent(tpEvent);
|
||||
if (tpEvent.isCancelled() || tpEvent.getTo() == null) {
|
||||
return null;
|
||||
}
|
||||
exit = tpEvent.getTo();
|
||||
if (exit == null) {
|
||||
return null;
|
||||
}
|
||||
worldserver2 = ((CraftWorld) exit.getWorld()).getHandle();
|
||||
d0 = exit.getX();
|
||||
d2 = exit.getY();
|
||||
d3 = exit.getZ();
|
||||
f2 = exit.getYaw();
|
||||
f = exit.getPitch();
|
||||
this.invulnerableDimensionChange = true;
|
||||
dimensionmanager = worldserver2.getDimension().getType();
|
||||
this.dimension = dimensionmanager;
|
||||
net.minecraftforge.fml.network.NetworkHooks.sendDimensionDataPacket(this.connection.netManager, (ServerPlayerEntity) (Object) this);
|
||||
this.connection.sendPacket(new SRespawnPacket(worldserver2.dimension.getType(), this.world.getWorldInfo().getGenerator(), this.interactionManager.getGameType()));
|
||||
this.connection.sendPacket(new SServerDifficultyPacket(this.world.getDifficulty(), this.world.getWorldInfo().isDifficultyLocked()));
|
||||
PlayerList playerlist = this.server.getPlayerList();
|
||||
playerlist.updatePermissionLevel((ServerPlayerEntity) (Object) this);
|
||||
worldserver.removePlayer((ServerPlayerEntity) (Object) this, true);
|
||||
this.removed = false;
|
||||
this.setLocationAndAngles(d0, d2, d3, f2, f);
|
||||
worldserver.getProfiler().endSection();
|
||||
worldserver.getProfiler().startSection("placing");
|
||||
double d5 = Math.min(-2.9999872E7, worldserver2.getWorldBorder().minX() + 16.0);
|
||||
double d6 = Math.min(-2.9999872E7, worldserver2.getWorldBorder().minZ() + 16.0);
|
||||
double d7 = Math.min(2.9999872E7, worldserver2.getWorldBorder().maxX() - 16.0);
|
||||
double d8 = Math.min(2.9999872E7, worldserver2.getWorldBorder().maxZ() - 16.0);
|
||||
d0 = MathHelper.clamp(d0, d5, d7);
|
||||
d3 = MathHelper.clamp(d3, d6, d8);
|
||||
this.setLocationAndAngles(d0, d2, d3, f2, f);
|
||||
if (dimensionmanager == DimensionType.THE_END) {
|
||||
int i = MathHelper.floor(this.posX);
|
||||
int j = MathHelper.floor(this.posY) - 1;
|
||||
int k = MathHelper.floor(this.posZ);
|
||||
boolean flag = true;
|
||||
boolean flag2 = false;
|
||||
BlockStateListPopulator blockList = new BlockStateListPopulator(worldserver2);
|
||||
for (int l = -2; l <= 2; ++l) {
|
||||
for (int i2 = -2; i2 <= 2; ++i2) {
|
||||
for (int j2 = -1; j2 < 3; ++j2) {
|
||||
int k2 = i + i2 * 1 + l * 0;
|
||||
int l2 = j + j2;
|
||||
int i3 = k + i2 * 0 - l * 1;
|
||||
boolean flag3 = j2 < 0;
|
||||
blockList.setBlockState(new BlockPos(k2, l2, i3), flag3 ? Blocks.OBSIDIAN.getDefaultState() : Blocks.AIR.getDefaultState(), 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
org.bukkit.World bworld = ((WorldBridge) worldserver2).bridge$getWorld();
|
||||
PortalCreateEvent portalEvent = new PortalCreateEvent((List) blockList.getList(), bworld, this.getBukkitEntity(), PortalCreateEvent.CreateReason.END_PLATFORM);
|
||||
Bukkit.getPluginManager().callEvent(portalEvent);
|
||||
if (!portalEvent.isCancelled()) {
|
||||
blockList.updateList();
|
||||
}
|
||||
this.setLocationAndAngles(i, j, k, f2, 0.0f);
|
||||
this.setMotion(Vec3d.ZERO);
|
||||
} else if (!worldserver2.getDefaultTeleporter().placeInPortal((ServerPlayerEntity) (Object) this, f3)) {
|
||||
worldserver2.getDefaultTeleporter().makePortal((ServerPlayerEntity) (Object) this);
|
||||
worldserver2.getDefaultTeleporter().placeInPortal((ServerPlayerEntity) (Object) this, f3);
|
||||
}
|
||||
worldserver.getProfiler().endSection();
|
||||
this.setWorld(worldserver2);
|
||||
worldserver2.func_217447_b((ServerPlayerEntity) (Object) this);
|
||||
this.func_213846_b(worldserver);
|
||||
this.connection.setPlayerLocation(this.posX, this.posY, this.posZ, f2, f);
|
||||
this.interactionManager.func_73080_a(worldserver2);
|
||||
this.connection.sendPacket(new SPlayerAbilitiesPacket(this.abilities));
|
||||
playerlist.func_72354_b((ServerPlayerEntity) (Object) this, worldserver2);
|
||||
playerlist.sendInventory((ServerPlayerEntity) (Object) this);
|
||||
for (EffectInstance mobeffect : this.getActivePotionEffects()) {
|
||||
this.connection.sendPacket(new SPlayEntityEffectPacket(this.getEntityId(), mobeffect));
|
||||
}
|
||||
this.connection.sendPacket(new SPlaySoundEventPacket(1032, BlockPos.ZERO, 0, false));
|
||||
this.lastExperience = -1;
|
||||
this.lastHealth = -1.0f;
|
||||
this.lastFoodLevel = -1;
|
||||
PlayerChangedWorldEvent changeEvent = new PlayerChangedWorldEvent(this.getBukkitEntity(), ((WorldBridge) worldserver).bridge$getWorld());
|
||||
Bukkit.getPluginManager().callEvent(changeEvent);
|
||||
net.minecraftforge.fml.hooks.BasicEventHooks.firePlayerChangedDimensionEvent((ServerPlayerEntity) (Object) this, dimensionmanager2, dimensionmanager);
|
||||
return (ServerPlayerEntity) (Object) this;
|
||||
}
|
||||
|
||||
public Entity a(DimensionType dimensionmanager, final PlayerTeleportEvent.TeleportCause cause) {
|
||||
bridge$pushChangeDimensionCause(cause);
|
||||
return this.changeDimension(dimensionmanager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Either<PlayerEntity.SleepResult, Unit> sleep(BlockPos at, boolean force) {
|
||||
return super.sleep(at, force).ifRight((p_213849_1_) -> {
|
||||
this.addStat(Stats.SLEEP_IN_BED);
|
||||
CriteriaTriggers.SLEPT_IN_BED.trigger((ServerPlayerEntity) (Object) this);
|
||||
});
|
||||
}
|
||||
|
||||
@Inject(method = "wakeUpPlayer", cancellable = true, at = @At("HEAD"))
|
||||
private void arclight$notWake(boolean immediately, boolean updateWorldFlag, boolean setSpawn, CallbackInfo ci) {
|
||||
if (!isSleeping()) ci.cancel();
|
||||
}
|
||||
|
||||
public int nextContainerCounter() {
|
||||
this.getNextWindowId();
|
||||
return this.currentWindowId;
|
||||
@ -677,21 +479,7 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntityMixin implemen
|
||||
return listName;
|
||||
}
|
||||
|
||||
@Inject(method = "setElytraFlying", cancellable = true, at = @At("HEAD"))
|
||||
private void arclight$beginGlide(CallbackInfo ci) {
|
||||
if (CraftEventFactory.callToggleGlideEvent((ServerPlayerEntity) (Object) this, true).isCancelled()) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "clearElytraFlying", cancellable = true, at = @At("HEAD"))
|
||||
private void arclight$endGlide(CallbackInfo ci) {
|
||||
if (CraftEventFactory.callToggleGlideEvent((ServerPlayerEntity) (Object) this, false).isCancelled()) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "func_200619_a", cancellable = true, at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/entity/player/ServerPlayerEntity;stopRiding()V"))
|
||||
@Inject(method = "teleport", cancellable = true, at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/entity/player/ServerPlayerEntity;stopRiding()V"))
|
||||
private void arclight$handleBy(ServerWorld world, double x, double y, double z, float yaw, float pitch, CallbackInfo ci) {
|
||||
PlayerTeleportEvent.TeleportCause cause = arclight$cause == null ? PlayerTeleportEvent.TeleportCause.UNKNOWN : arclight$cause;
|
||||
arclight$cause = null;
|
||||
@ -701,7 +489,7 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntityMixin implemen
|
||||
|
||||
public void a(ServerWorld worldserver, double d0, double d1, double d2, float f, float f1, PlayerTeleportEvent.TeleportCause cause) {
|
||||
bridge$pushChangeDimensionCause(cause);
|
||||
func_200619_a(worldserver, d0, d1, d2, f, f1);
|
||||
teleport(worldserver, d0, d1, d2, f, f1);
|
||||
}
|
||||
|
||||
public CraftPlayer getBukkitEntity() {
|
||||
@ -721,8 +509,12 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntityMixin implemen
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity bridge$changeDimension(DimensionType dimensionType, PlayerTeleportEvent.TeleportCause cause) {
|
||||
return a(dimensionType, cause);
|
||||
public Optional<PlayerTeleportEvent.TeleportCause> bridge$getTeleportCause() {
|
||||
try {
|
||||
return Optional.ofNullable(arclight$cause);
|
||||
} finally {
|
||||
arclight$cause = null;
|
||||
}
|
||||
}
|
||||
|
||||
public long getPlayerTime() {
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package io.izzel.arclight.common.mixin.core.entity.projectile;
|
||||
|
||||
import io.izzel.arclight.common.bridge.entity.projectile.DamagingProjectileEntityBridge;
|
||||
import io.izzel.arclight.common.mixin.core.entity.EntityMixin;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
@ -16,7 +17,6 @@ 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.LocalCapture;
|
||||
import io.izzel.arclight.common.bridge.entity.projectile.DamagingProjectileEntityBridge;
|
||||
|
||||
@Mixin(DamagingProjectileEntity.class)
|
||||
public abstract class DamagingProjectileEntityMixin extends EntityMixin implements DamagingProjectileEntityBridge {
|
||||
@ -26,6 +26,7 @@ public abstract class DamagingProjectileEntityMixin extends EntityMixin implemen
|
||||
@Shadow public double accelerationY;
|
||||
@Shadow public double accelerationZ;
|
||||
@Shadow public LivingEntity shootingEntity;
|
||||
@Shadow protected void onImpact(RayTraceResult result) {}
|
||||
// @formatter:on
|
||||
|
||||
public float bukkitYield;
|
||||
|
||||
@ -2,6 +2,9 @@ package io.izzel.arclight.common.mixin.core.entity.projectile;
|
||||
|
||||
import io.izzel.arclight.common.bridge.entity.LivingEntityBridge;
|
||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.CampfireBlock;
|
||||
import net.minecraft.entity.AreaEffectCloudEntity;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
@ -11,7 +14,9 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.potion.Effect;
|
||||
import net.minecraft.potion.EffectInstance;
|
||||
import net.minecraft.potion.Potion;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import org.bukkit.craftbukkit.v.entity.CraftLivingEntity;
|
||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||
import org.bukkit.event.entity.EntityPotionEffectEvent;
|
||||
@ -104,4 +109,18 @@ public abstract class PotionEntityMixin extends ThrowableEntityMixin {
|
||||
entity.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "extinguishFires", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;extinguishFire(Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;)Z"))
|
||||
private void arclight$entityChangeBlock(BlockPos pos, Direction direction, CallbackInfo ci) {
|
||||
if (CraftEventFactory.callEntityChangeBlockEvent((PotionEntity) (Object) this, pos.offset(direction), Blocks.AIR.getDefaultState()).isCancelled()) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "extinguishFires", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;playEvent(Lnet/minecraft/entity/player/PlayerEntity;ILnet/minecraft/util/math/BlockPos;I)V"))
|
||||
private void arclight$entityChangeBlock2(BlockPos pos, Direction p_184542_2_, CallbackInfo ci, BlockState state) {
|
||||
if (CraftEventFactory.callEntityChangeBlockEvent((PotionEntity) (Object) this, pos, state.with(CampfireBlock.LIT, false)).isCancelled()) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,44 @@
|
||||
package io.izzel.arclight.common.mixin.core.entity.projectile;
|
||||
|
||||
import io.izzel.arclight.common.bridge.entity.projectile.ProjectileItemEntityBridge;
|
||||
import net.minecraft.entity.projectile.ProjectileItemEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.datasync.DataParameter;
|
||||
import net.minecraft.util.Util;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Implements;
|
||||
import org.spongepowered.asm.mixin.Interface;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(ProjectileItemEntity.class)
|
||||
@Implements(@Interface(iface = ProjectileItemEntityBridge.Hack.class, prefix = "hack$"))
|
||||
public abstract class ProjectileItemEntityMixin extends ThrowableEntityMixin {
|
||||
|
||||
// @formatter:off
|
||||
@Shadow protected abstract Item shadow$getDefaultItem();
|
||||
@Shadow @Final private static DataParameter<ItemStack> ITEMSTACK_DATA;
|
||||
// @formatter:on
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
*/
|
||||
@Overwrite
|
||||
public void setItem(ItemStack stack) {
|
||||
if (stack.getItem() != this.shadow$getDefaultItem() || stack.hasTag()) {
|
||||
this.getDataManager().set(ITEMSTACK_DATA, Util.make(stack.copy(), (itemStack) -> {
|
||||
if (!itemStack.isEmpty()) {
|
||||
itemStack.setCount(1);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Item hack$getDefaultItem() {
|
||||
return this.shadow$getDefaultItem();
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package io.izzel.arclight.common.mixin.core.entity.projectile;
|
||||
|
||||
import io.izzel.arclight.api.ArclightVersion;
|
||||
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.Entity;
|
||||
@ -39,6 +40,9 @@ public abstract class SmallFireballEntityMixin extends DamagingProjectileEntityM
|
||||
*/
|
||||
@Overwrite
|
||||
protected void onImpact(RayTraceResult result) {
|
||||
if (ArclightVersion.atLeast(ArclightVersion.v1_15)) {
|
||||
super.onImpact(result);
|
||||
}
|
||||
if (!this.world.isRemote) {
|
||||
if (result.getType() == RayTraceResult.Type.ENTITY) {
|
||||
Entity entity = ((EntityRayTraceResult) result).getEntity();
|
||||
|
||||
@ -22,7 +22,7 @@ public abstract class WitherSkullEntityMixin extends DamagingProjectileEntityMix
|
||||
|
||||
@Inject(method = "onImpact", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;heal(F)V"))
|
||||
private void arclight$heal(RayTraceResult result, CallbackInfo ci) {
|
||||
((LivingEntityBridge) this.shootingEntity).bridge$pushHealReason(EntityRegainHealthEvent.RegainReason.REGEN);
|
||||
((LivingEntityBridge) this.shootingEntity).bridge$pushHealReason(EntityRegainHealthEvent.RegainReason.WITHER);
|
||||
}
|
||||
|
||||
@Inject(method = "onImpact", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;addPotionEffect(Lnet/minecraft/potion/EffectInstance;)Z"))
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package io.izzel.arclight.common.mixin.core.fluid;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.fluid.FlowingFluid;
|
||||
import net.minecraft.fluid.Fluid;
|
||||
import net.minecraft.fluid.IFluidState;
|
||||
@ -9,7 +8,6 @@ import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.Block;
|
||||
@ -20,7 +18,6 @@ import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||
import org.bukkit.event.block.BlockFromToEvent;
|
||||
import org.bukkit.event.block.FluidLevelChangeEvent;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
@ -32,9 +29,6 @@ public abstract class FlowingFluidMixin {
|
||||
|
||||
// @formatter:off
|
||||
@Shadow protected abstract boolean canFlow(IBlockReader worldIn, BlockPos fromPos, BlockState fromBlockState, Direction direction, BlockPos toPos, BlockState toBlockState, IFluidState toFluidState, Fluid fluidIn);
|
||||
@Shadow protected abstract IFluidState calculateCorrectFlowingState(IWorldReader worldIn, BlockPos pos, BlockState blockStateIn);
|
||||
@Shadow protected abstract int func_215667_a(World p_215667_1_, BlockPos p_215667_2_, IFluidState p_215667_3_, IFluidState p_215667_4_);
|
||||
@Shadow protected abstract void flowAround(IWorld worldIn, BlockPos pos, IFluidState stateIn);
|
||||
// @formatter:on
|
||||
|
||||
@Inject(method = "flowAround", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/fluid/FlowingFluid;flowInto(Lnet/minecraft/world/IWorld;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/Direction;Lnet/minecraft/fluid/IFluidState;)V"))
|
||||
@ -59,35 +53,13 @@ public abstract class FlowingFluidMixin {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
*/
|
||||
@Overwrite
|
||||
public void tick(World worldIn, BlockPos pos, IFluidState state) {
|
||||
if (!state.isSource()) {
|
||||
IFluidState ifluidstate = this.calculateCorrectFlowingState(worldIn, pos, worldIn.getBlockState(pos));
|
||||
int i = this.func_215667_a(worldIn, pos, state, ifluidstate);
|
||||
if (ifluidstate.isEmpty()) {
|
||||
state = ifluidstate;
|
||||
FluidLevelChangeEvent event = CraftEventFactory.callFluidLevelChangeEvent(worldIn, pos, Blocks.AIR.getDefaultState());
|
||||
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
|
||||
private boolean arclight$fluidLevelChange(World world, BlockPos pos, BlockState newState, int flags) {
|
||||
FluidLevelChangeEvent event = CraftEventFactory.callFluidLevelChangeEvent(world, pos, newState);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
worldIn.setBlockState(pos, ((CraftBlockData) event.getNewData()).getState(), 3);
|
||||
} else if (!ifluidstate.equals(state)) {
|
||||
state = ifluidstate;
|
||||
BlockState blockstate = ifluidstate.getBlockState();
|
||||
FluidLevelChangeEvent event = CraftEventFactory.callFluidLevelChangeEvent(worldIn, pos, blockstate);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
worldIn.setBlockState(pos, ((CraftBlockData) event.getNewData()).getState(), 2);
|
||||
worldIn.getPendingFluidTicks().scheduleTick(pos, ifluidstate.getFluid(), i);
|
||||
worldIn.notifyNeighborsOfStateChange(pos, blockstate.getBlock());
|
||||
return false;
|
||||
} else {
|
||||
return world.setBlockState(pos, ((CraftBlockData) event.getNewData()).getState(), flags);
|
||||
}
|
||||
}
|
||||
|
||||
this.flowAround(worldIn, pos, state);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,8 +4,10 @@ import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.fluid.IFluidState;
|
||||
import net.minecraft.fluid.LavaFluid;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.GameRules;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.event.ForgeEventFactory;
|
||||
@ -13,6 +15,10 @@ import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
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.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@ -77,4 +83,16 @@ public abstract class LavaFluidMixin {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "flowInto", cancellable = true, at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/IWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
|
||||
private void arclight$returnIfFail(IWorld worldIn, BlockPos pos, BlockState blockStateIn, Direction direction, IFluidState fluidStateIn, CallbackInfo ci) {
|
||||
if (!arclight$success) ci.cancel();
|
||||
}
|
||||
|
||||
private transient boolean arclight$success;
|
||||
|
||||
@Redirect(method = "flowInto", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/IWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
|
||||
private boolean arclight$blockFromTo(IWorld iWorld, BlockPos pos, BlockState newState, int flags) {
|
||||
return arclight$success = CraftEventFactory.handleBlockFormEvent(iWorld.getWorld(), pos, newState, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,8 @@ import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.tileentity.EnderChestTileEntity;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v.block.CraftBlock;
|
||||
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@ -39,6 +41,13 @@ public abstract class EnderChestInventoryMixin extends InventoryMixin implements
|
||||
return ((PlayerEntityBridge) owner).bridge$getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOwner(InventoryHolder owner) {
|
||||
if (owner instanceof HumanEntity) {
|
||||
this.owner = ((CraftHumanEntity) owner).getHandle();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
return CraftBlock.at(this.associatedChest.getWorld(), this.associatedChest.getPos()).getLocation();
|
||||
|
||||
@ -5,9 +5,7 @@ import com.google.common.collect.Sets;
|
||||
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
||||
import io.izzel.arclight.common.bridge.world.ExplosionBridge;
|
||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.enchantment.ProtectionEnchantment;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
@ -16,27 +14,17 @@ import net.minecraft.entity.item.TNTEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.projectile.DamagingProjectileEntity;
|
||||
import net.minecraft.fluid.IFluidState;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
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.world.Explosion;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraft.world.storage.loot.LootContext;
|
||||
import net.minecraft.world.storage.loot.LootParameters;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||
import org.bukkit.event.block.BlockExplodeEvent;
|
||||
import org.bukkit.event.block.BlockIgniteEvent;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@ -51,7 +39,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
@Mixin(Explosion.class)
|
||||
@ -65,8 +52,6 @@ public abstract class ExplosionMixin implements ExplosionBridge {
|
||||
@Shadow @Final private double x;
|
||||
@Shadow @Final private double y;
|
||||
@Shadow @Final private double z;
|
||||
@Shadow @Final private boolean causesFire;
|
||||
@Shadow @Final private Random random;
|
||||
@Shadow @Final public Entity exploder;
|
||||
@Shadow public abstract DamageSource getDamageSource();
|
||||
@Shadow @Final private Map<PlayerEntity, Vec3d> playerKnockbackMap;
|
||||
@ -76,8 +61,6 @@ public abstract class ExplosionMixin implements ExplosionBridge {
|
||||
@Accessor("mode") public abstract Explosion.Mode bridge$getMode();
|
||||
// @formatter:on
|
||||
|
||||
public boolean wasCanceled = false;
|
||||
|
||||
@Inject(method = "<init>(Lnet/minecraft/world/World;Lnet/minecraft/entity/Entity;DDDFZLnet/minecraft/world/Explosion$Mode;)V",
|
||||
at = @At("RETURN"))
|
||||
public void arclight$adjustSize(World worldIn, Entity exploderIn, double xIn, double yIn, double zIn, float sizeIn, boolean causesFireIn, Explosion.Mode modeIn, CallbackInfo ci) {
|
||||
@ -147,13 +130,12 @@ public abstract class ExplosionMixin implements ExplosionBridge {
|
||||
net.minecraftforge.event.ForgeEventFactory.onExplosionDetonate(this.world, (Explosion) (Object) this, list, f3);
|
||||
Vec3d vec3d = new Vec3d(this.x, this.y, this.z);
|
||||
|
||||
for (int k2 = 0; k2 < list.size(); ++k2) {
|
||||
Entity entity = list.get(k2);
|
||||
for (Entity entity : list) {
|
||||
if (!entity.isImmuneToExplosions()) {
|
||||
double d12 = MathHelper.sqrt(entity.getDistanceSq(new Vec3d(this.x, this.y, this.z))) / f3;
|
||||
double d12 = MathHelper.sqrt(entity.getDistanceSq(vec3d)) / f3;
|
||||
if (d12 <= 1.0D) {
|
||||
double d5 = entity.posX - this.x;
|
||||
double d7 = entity.posY + (double) entity.getEyeHeight() - this.y;
|
||||
double d7 = ((EntityBridge) entity).bridge$getEyeHeight() - this.y;
|
||||
double d9 = entity.posZ - this.z;
|
||||
double d13 = MathHelper.sqrt(d5 * d5 + d7 * d7 + d9 * d9);
|
||||
if (d13 != 0.0D) {
|
||||
@ -190,81 +172,8 @@ public abstract class ExplosionMixin implements ExplosionBridge {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
*/
|
||||
@Overwrite
|
||||
public void doExplosionB(boolean spawnParticles) {
|
||||
this.world.playSound(null, this.x, this.y, this.z, SoundEvents.ENTITY_GENERIC_EXPLODE, SoundCategory.BLOCKS, 4.0F, (1.0F + (this.world.rand.nextFloat() - this.world.rand.nextFloat()) * 0.2F) * 0.7F);
|
||||
boolean flag = this.mode != Explosion.Mode.NONE;
|
||||
if (!(this.size < 2.0F) && flag) {
|
||||
this.world.addParticle(ParticleTypes.EXPLOSION_EMITTER, this.x, this.y, this.z, 1.0D, 0.0D, 0.0D);
|
||||
} else {
|
||||
this.world.addParticle(ParticleTypes.EXPLOSION, this.x, this.y, this.z, 1.0D, 0.0D, 0.0D);
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
|
||||
float yield = arclight$callBlockExplodeEvent();
|
||||
|
||||
if (Float.isNaN(yield)) {
|
||||
this.wasCanceled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
for (BlockPos blockpos : this.affectedBlockPositions) {
|
||||
BlockState blockstate = this.world.getBlockState(blockpos);
|
||||
Block block = blockstate.getBlock();
|
||||
if (spawnParticles) {
|
||||
double d0 = ((float) blockpos.getX() + this.world.rand.nextFloat());
|
||||
double d1 = ((float) blockpos.getY() + this.world.rand.nextFloat());
|
||||
double d2 = ((float) blockpos.getZ() + this.world.rand.nextFloat());
|
||||
double d3 = d0 - this.x;
|
||||
double d4 = d1 - this.y;
|
||||
double d5 = d2 - this.z;
|
||||
double d6 = MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5);
|
||||
d3 = d3 / d6;
|
||||
d4 = d4 / d6;
|
||||
d5 = d5 / d6;
|
||||
double d7 = 0.5D / (d6 / (double) this.size + 0.1D);
|
||||
d7 = d7 * (double) (this.world.rand.nextFloat() * this.world.rand.nextFloat() + 0.3F);
|
||||
d3 = d3 * d7;
|
||||
d4 = d4 * d7;
|
||||
d5 = d5 * d7;
|
||||
this.world.addParticle(ParticleTypes.POOF, (d0 + this.x) / 2.0D, (d1 + this.y) / 2.0D, (d2 + this.z) / 2.0D, d3, d4, d5);
|
||||
this.world.addParticle(ParticleTypes.SMOKE, d0, d1, d2, d3, d4, d5);
|
||||
}
|
||||
|
||||
if (!blockstate.isAir(this.world, blockpos)) {
|
||||
if (this.world instanceof ServerWorld && blockstate.canDropFromExplosion(this.world, blockpos, (Explosion) (Object) this)) {
|
||||
TileEntity tileentity = blockstate.hasTileEntity() ? this.world.getTileEntity(blockpos) : null;
|
||||
LootContext.Builder lootcontext$builder = (new LootContext.Builder((ServerWorld) this.world)).withRandom(this.world.rand).withParameter(LootParameters.POSITION, blockpos).withParameter(LootParameters.TOOL, ItemStack.EMPTY).withNullableParameter(LootParameters.BLOCK_ENTITY, tileentity);
|
||||
if (this.mode == Explosion.Mode.DESTROY || yield < 1.0F) {
|
||||
lootcontext$builder.withParameter(LootParameters.EXPLOSION_RADIUS, 1.0F / yield);
|
||||
}
|
||||
|
||||
Block.spawnDrops(blockstate, lootcontext$builder);
|
||||
}
|
||||
|
||||
blockstate.onBlockExploded(this.world, blockpos, (Explosion) (Object) this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.causesFire) {
|
||||
for (BlockPos blockPos : this.affectedBlockPositions) {
|
||||
if (this.world.getBlockState(blockPos).isAir(world, blockPos) && this.world.getBlockState(blockPos.down()).isOpaqueCube(this.world, blockPos.down()) && this.random.nextInt(3) == 0) {
|
||||
BlockIgniteEvent event = CraftEventFactory.callBlockIgniteEvent(this.world, blockPos.getX(), blockPos.getY(), blockPos.getZ(), (Explosion) (Object) this);
|
||||
if (!event.isCancelled()) {
|
||||
this.world.setBlockState(blockPos, Blocks.FIRE.getDefaultState());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float arclight$callBlockExplodeEvent() {
|
||||
@Override
|
||||
public float bridge$callBlockExplodeEvent() {
|
||||
org.bukkit.World world = ((WorldBridge) this.world).bridge$getWorld();
|
||||
org.bukkit.entity.Entity exploder = this.exploder == null ? null : ((EntityBridge) this.exploder).bridge$getBukkitEntity();
|
||||
Location location = new Location(world, this.x, this.y, this.z);
|
||||
@ -272,7 +181,7 @@ public abstract class ExplosionMixin implements ExplosionBridge {
|
||||
for (int i = this.affectedBlockPositions.size() - 1; i >= 0; i--) {
|
||||
BlockPos blockPos = this.affectedBlockPositions.get(i);
|
||||
org.bukkit.block.Block block = world.getBlockAt(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
||||
if (block.getType() != Material.AIR && block.getType() != Material.CAVE_AIR && block.getType() != Material.VOID_AIR) {
|
||||
if (!block.getType().isAir()) {
|
||||
blockList.add(block);
|
||||
}
|
||||
}
|
||||
@ -323,9 +232,4 @@ public abstract class ExplosionMixin implements ExplosionBridge {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bridge$wasCancelled() {
|
||||
return wasCanceled;
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,14 +26,14 @@ public interface IBlockReaderMixin extends IBlockReaderBridge {
|
||||
default BlockRayTraceResult rayTraceBlock(RayTraceContext context, BlockPos pos) {
|
||||
BlockState blockstate = this.getBlockState(pos);
|
||||
IFluidState ifluidstate = this.getFluidState(pos);
|
||||
Vec3d vec3d = context.func_222253_b();
|
||||
Vec3d vec3d1 = context.func_222250_a();
|
||||
Vec3d vec3d = context.getStartVec();
|
||||
Vec3d vec3d1 = context.getStartVec();
|
||||
VoxelShape voxelshape = context.getBlockShape(blockstate, (IBlockReader) this, pos);
|
||||
BlockRayTraceResult blockraytraceresult = this.rayTraceBlocks(vec3d, vec3d1, pos, voxelshape, blockstate);
|
||||
VoxelShape voxelshape1 = context.getFluidShape(ifluidstate, (IBlockReader) this, pos);
|
||||
BlockRayTraceResult blockraytraceresult1 = voxelshape1.rayTrace(vec3d, vec3d1, pos);
|
||||
double d0 = blockraytraceresult == null ? Double.MAX_VALUE : context.func_222253_b().squareDistanceTo(blockraytraceresult.getHitVec());
|
||||
double d1 = blockraytraceresult1 == null ? Double.MAX_VALUE : context.func_222253_b().squareDistanceTo(blockraytraceresult1.getHitVec());
|
||||
double d0 = blockraytraceresult == null ? Double.MAX_VALUE : context.getStartVec().squareDistanceTo(blockraytraceresult.getHitVec());
|
||||
double d1 = blockraytraceresult1 == null ? Double.MAX_VALUE : context.getStartVec().squareDistanceTo(blockraytraceresult1.getHitVec());
|
||||
return d0 <= d1 ? blockraytraceresult : blockraytraceresult1;
|
||||
}
|
||||
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
package io.izzel.arclight.common.mixin.core.world;
|
||||
|
||||
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
||||
import io.izzel.arclight.common.bridge.world.TeleporterBridge;
|
||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||
import io.izzel.arclight.common.mod.util.ArclightBlockPopulator;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.pattern.BlockPattern;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.Teleporter;
|
||||
@ -21,7 +23,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(Teleporter.class)
|
||||
public class TeleporterMixin {
|
||||
public class TeleporterMixin implements TeleporterBridge {
|
||||
|
||||
// @formatter:off
|
||||
@Shadow @Final protected ServerWorld world;
|
||||
@ -56,4 +58,16 @@ public class TeleporterMixin {
|
||||
}
|
||||
arclight$populator = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bridge$makePortal(Entity entityIn, BlockPos pos, int createRadius) {
|
||||
// todo
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPattern.PortalInfo bridge$placeInPortal(Entity p_222268_1_, BlockPos pos, float p_222268_2_, int searchRadius, boolean searchOnly) {
|
||||
// todo
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package io.izzel.arclight.common.mixin.core.world;
|
||||
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.MobEntity;
|
||||
import net.minecraft.entity.ai.attributes.AttributeMap;
|
||||
import net.minecraft.entity.ai.attributes.IAttributeInstance;
|
||||
import net.minecraft.entity.item.ItemFrameEntity;
|
||||
@ -20,6 +21,7 @@ import net.minecraft.network.play.server.SEntityPacket;
|
||||
import net.minecraft.network.play.server.SEntityPropertiesPacket;
|
||||
import net.minecraft.network.play.server.SEntityTeleportPacket;
|
||||
import net.minecraft.network.play.server.SEntityVelocityPacket;
|
||||
import net.minecraft.network.play.server.SMountEntityPacket;
|
||||
import net.minecraft.network.play.server.SPlayEntityEffectPacket;
|
||||
import net.minecraft.network.play.server.SSetPassengersPacket;
|
||||
import net.minecraft.network.play.server.SSpawnMobPacket;
|
||||
@ -29,7 +31,6 @@ import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.TrackedEntity;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraft.world.storage.MapData;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerVelocityEvent;
|
||||
@ -76,7 +77,6 @@ public abstract class TrackedEntityMixin {
|
||||
@Shadow protected abstract void sendPacket(IPacket<?> p_219451_1_);
|
||||
// @formatter:on
|
||||
|
||||
@Shadow @Final private static Logger LOGGER;
|
||||
private Set<ServerPlayerEntity> trackedPlayers;
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
@ -136,7 +136,7 @@ public abstract class TrackedEntityMixin {
|
||||
++this.ticksSinceAbsoluteTeleport;
|
||||
int i = MathHelper.floor(this.trackedEntity.rotationYaw * 256.0f / 360.0f);
|
||||
int j = MathHelper.floor(this.trackedEntity.rotationPitch * 256.0f / 360.0f);
|
||||
Vec3d vec3d = new Vec3d(this.trackedEntity.posX, this.trackedEntity.posY, this.trackedEntity.posZ).subtract(SEntityPacket.func_218744_a(this.encodedPosX, this.encodedPosY, this.encodedPosZ));
|
||||
Vec3d vec3d = this.trackedEntity.getPositionVec().subtract(SEntityPacket.func_218744_a(this.encodedPosX, this.encodedPosY, this.encodedPosZ));
|
||||
boolean flag2 = vec3d.lengthSquared() >= 7.62939453125E-6;
|
||||
IPacket<?> packet2 = null;
|
||||
boolean flag3 = flag2 || this.updateCounter % 60 == 0;
|
||||
@ -266,6 +266,12 @@ public abstract class TrackedEntityMixin {
|
||||
if (this.trackedEntity.isPassenger()) {
|
||||
consumer.accept(new SSetPassengersPacket(this.trackedEntity.getRidingEntity()));
|
||||
}
|
||||
if (this.trackedEntity instanceof MobEntity) {
|
||||
MobEntity mobentity = (MobEntity) this.trackedEntity;
|
||||
if (mobentity.getLeashed()) {
|
||||
consumer.accept(new SMountEntityPacket(mobentity, mobentity.getLeashHolder()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "sendMetadata", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/world/TrackedEntity;sendPacket(Lnet/minecraft/network/IPacket;)V"))
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
package io.izzel.arclight.common.mixin.core.world.chunk.storage;
|
||||
|
||||
import io.izzel.arclight.common.bridge.world.dimension.DimensionTypeBridge;
|
||||
import net.minecraft.world.chunk.storage.ChunkLoader;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
||||
@Mixin(ChunkLoader.class)
|
||||
public class ChunkLoaderMixin {
|
||||
|
||||
@ModifyArg(method = "updateChunkData", index = 0, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/gen/feature/structure/LegacyStructureDataUtil;func_215130_a(Lnet/minecraft/world/dimension/DimensionType;Lnet/minecraft/world/storage/DimensionSavedDataManager;)Lnet/minecraft/world/gen/feature/structure/LegacyStructureDataUtil;"))
|
||||
private DimensionType arclight$dimType(DimensionType dim) {
|
||||
return ((DimensionTypeBridge) dim).bridge$getType();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package io.izzel.arclight.common.mixin.v1_15.block;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.LilyPadBlock;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(LilyPadBlock.class)
|
||||
public class LilyPadBlockMixin_1_15 {
|
||||
|
||||
@Inject(method = "onEntityCollision", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;destroyBlock(Lnet/minecraft/util/math/BlockPos;ZLnet/minecraft/entity/Entity;)Z"))
|
||||
public void arclight$entityChangeBlock(BlockState state, World worldIn, BlockPos pos, Entity entityIn, CallbackInfo ci) {
|
||||
if (CraftEventFactory.callEntityChangeBlockEvent(entityIn, pos, Blocks.AIR.getDefaultState()).isCancelled()) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,6 +7,7 @@ import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.MobEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.network.datasync.EntityDataManager;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@ -21,14 +22,16 @@ import net.minecraftforge.common.util.ITeleporter;
|
||||
import org.bukkit.craftbukkit.v.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||
import org.bukkit.event.entity.EntityPortalEvent;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Random;
|
||||
|
||||
@Mixin(Entity.class)
|
||||
public abstract class EntityMixin_1_15 {
|
||||
public abstract class EntityMixin_1_15 implements EntityBridge {
|
||||
|
||||
// @formatter:off
|
||||
@Shadow public World world;
|
||||
@ -47,6 +50,12 @@ public abstract class EntityMixin_1_15 {
|
||||
@Shadow public abstract double getPosY();
|
||||
@Shadow public abstract Direction getTeleportDirection();
|
||||
@Shadow public abstract EntityType<?> getType();
|
||||
@Shadow @Final protected EntityDataManager dataManager;
|
||||
@Shadow public abstract boolean isInvisible();
|
||||
@Shadow @Final protected Random rand;
|
||||
@Shadow public abstract float getWidth();
|
||||
@Shadow public abstract float getHeight();
|
||||
@Shadow public abstract double getPosYEye();
|
||||
// @formatter:on
|
||||
|
||||
/**
|
||||
@ -156,4 +165,9 @@ public abstract class EntityMixin_1_15 {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double bridge$getEyeHeight() {
|
||||
return this.getPosYEye();
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,274 @@
|
||||
package io.izzel.arclight.common.mixin.v1_15.entity;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import io.izzel.arclight.common.bridge.entity.LivingEntityBridge;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.item.ExperienceOrbEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.network.datasync.DataParameter;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.potion.Effect;
|
||||
import net.minecraft.potion.EffectInstance;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.living.PotionEvent;
|
||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||
import org.bukkit.event.entity.EntityPotionEffectEvent;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
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.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(LivingEntity.class)
|
||||
public abstract class LivingEntityMixin_1_15 extends EntityMixin_1_15 implements LivingEntityBridge {
|
||||
|
||||
// @formatter:off
|
||||
@Shadow @Final private static DataParameter<Integer> POTION_EFFECTS;
|
||||
@Shadow @Final private static DataParameter<Boolean> HIDE_PARTICLES;
|
||||
@Shadow @Final public Map<Effect, EffectInstance> activePotionsMap;
|
||||
@Shadow public boolean potionsNeedUpdate;
|
||||
@Shadow protected abstract void onFinishedPotionEffect(EffectInstance effect);
|
||||
@Shadow protected abstract void onChangedPotionEffect(EffectInstance id, boolean reapply);
|
||||
@Shadow protected abstract void updatePotionMetadata();
|
||||
@Shadow public abstract boolean removePotionEffect(Effect effectIn);
|
||||
@Shadow public abstract boolean isPotionApplicable(EffectInstance potioneffectIn);
|
||||
@Shadow protected abstract void onNewPotionEffect(EffectInstance id);
|
||||
@Shadow @Nullable public abstract EffectInstance removeActivePotionEffect(@Nullable Effect potioneffectin);
|
||||
@Shadow public int deathTime;
|
||||
@Shadow protected abstract void createWitherRose(@Nullable LivingEntity p_226298_1_);
|
||||
// @formatter:on
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
*/
|
||||
@Overwrite
|
||||
protected void onDeathUpdate() {
|
||||
++this.deathTime;
|
||||
if (this.deathTime >= 20 && !this.removed) {
|
||||
|
||||
this.remove((Object) this instanceof ServerPlayerEntity); //Forge keep data until we revive player
|
||||
|
||||
for (int k = 0; k < 20; ++k) {
|
||||
double d2 = this.rand.nextGaussian() * 0.02D;
|
||||
double d0 = this.rand.nextGaussian() * 0.02D;
|
||||
double d1 = this.rand.nextGaussian() * 0.02D;
|
||||
this.world.addParticle(ParticleTypes.POOF, this.getPosX() + (double) (this.rand.nextFloat() * this.getWidth() * 2.0F) - (double) this.getWidth(), this.getPosY() + (double) (this.rand.nextFloat() * this.getHeight()), this.getPosZ() + (double) (this.rand.nextFloat() * this.getWidth() * 2.0F) - (double) this.getWidth(), d2, d0, d1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(method = "spawnDrops", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;dropExperience()V"))
|
||||
private void arclight$dropLater(LivingEntity livingEntity) {
|
||||
}
|
||||
|
||||
@Inject(method = "spawnDrops", at = @At("RETURN"))
|
||||
private void arclight$dropLast(DamageSource damageSourceIn, CallbackInfo ci) {
|
||||
this.dropExperience();
|
||||
}
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
*/
|
||||
@Overwrite
|
||||
protected void dropExperience() {
|
||||
// if (!this.world.isRemote && (this.isPlayer() || this.recentlyHit > 0 && this.canDropLoot() && this.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT))) {
|
||||
if (true) {
|
||||
int i = bridge$getExpToDrop();
|
||||
while (i > 0) {
|
||||
int j = ExperienceOrbEntity.getXPSplit(i);
|
||||
i -= j;
|
||||
this.world.addEntity(new ExperienceOrbEntity(this.world, this.getPosX(), this.getPosY(), this.getPosZ(), j));
|
||||
}
|
||||
bridge$setExpToDrop(0);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isTickingEffects = false;
|
||||
private List<Map.Entry<Either<EffectInstance, Effect>, EntityPotionEffectEvent.Cause>> effectsToProcess = Lists.newArrayList();
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
*/
|
||||
@Overwrite
|
||||
protected void updatePotionEffects() {
|
||||
this.isTickingEffects = true;
|
||||
Iterator<Effect> iterator = this.activePotionsMap.keySet().iterator();
|
||||
|
||||
try {
|
||||
while (iterator.hasNext()) {
|
||||
Effect effect = iterator.next();
|
||||
EffectInstance effectinstance = this.activePotionsMap.get(effect);
|
||||
if (!effectinstance.tick((LivingEntity) (Object) this, () -> {
|
||||
onChangedPotionEffect(effectinstance, true);
|
||||
})) {
|
||||
if (!this.world.isRemote && !MinecraftForge.EVENT_BUS.post(new PotionEvent.PotionExpiryEvent((LivingEntity) (Object) this, effectinstance))) {
|
||||
|
||||
EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent((LivingEntity) (Object) this, effectinstance, null, EntityPotionEffectEvent.Cause.EXPIRATION);
|
||||
if (event.isCancelled()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
iterator.remove();
|
||||
this.onFinishedPotionEffect(effectinstance);
|
||||
}
|
||||
} else if (effectinstance.getDuration() % 600 == 0) {
|
||||
this.onChangedPotionEffect(effectinstance, false);
|
||||
}
|
||||
}
|
||||
} catch (ConcurrentModificationException ignored) {
|
||||
}
|
||||
|
||||
isTickingEffects = false;
|
||||
for (Map.Entry<Either<EffectInstance, Effect>, EntityPotionEffectEvent.Cause> e : effectsToProcess) {
|
||||
Either<EffectInstance, Effect> either = e.getKey();
|
||||
EntityPotionEffectEvent.Cause cause = e.getValue();
|
||||
bridge$pushEffectCause(cause);
|
||||
if (either.left().isPresent()) {
|
||||
addPotionEffect(either.left().get());
|
||||
} else {
|
||||
removePotionEffect(either.right().get());
|
||||
}
|
||||
}
|
||||
effectsToProcess.clear();
|
||||
|
||||
if (this.potionsNeedUpdate) {
|
||||
if (!this.world.isRemote) {
|
||||
this.updatePotionMetadata();
|
||||
}
|
||||
|
||||
this.potionsNeedUpdate = false;
|
||||
}
|
||||
|
||||
int i = this.dataManager.get(POTION_EFFECTS);
|
||||
boolean flag1 = this.dataManager.get(HIDE_PARTICLES);
|
||||
if (i > 0) {
|
||||
boolean flag;
|
||||
if (this.isInvisible()) {
|
||||
flag = this.rand.nextInt(15) == 0;
|
||||
} else {
|
||||
flag = this.rand.nextBoolean();
|
||||
}
|
||||
|
||||
if (flag1) {
|
||||
flag &= this.rand.nextInt(5) == 0;
|
||||
}
|
||||
|
||||
if (flag && i > 0) {
|
||||
double d0 = (double) (i >> 16 & 255) / 255.0D;
|
||||
double d1 = (double) (i >> 8 & 255) / 255.0D;
|
||||
double d2 = (double) (i >> 0 & 255) / 255.0D;
|
||||
this.world.addParticle(flag1 ? ParticleTypes.AMBIENT_ENTITY_EFFECT : ParticleTypes.ENTITY_EFFECT, this.getPosX() + (this.rand.nextDouble() - 0.5D) * (double) this.getWidth(), this.getPosY() + this.rand.nextDouble() * (double) this.getHeight(), this.getPosZ() + (this.rand.nextDouble() - 0.5D) * (double) this.getWidth(), d0, d1, d2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
*/
|
||||
@Overwrite
|
||||
public boolean addPotionEffect(EffectInstance effectInstanceIn) {
|
||||
EntityPotionEffectEvent.Cause cause = bridge$getEffectCause().orElse(EntityPotionEffectEvent.Cause.UNKNOWN);
|
||||
if (isTickingEffects) {
|
||||
effectsToProcess.add(Maps.immutableEntry(Either.left(effectInstanceIn), cause));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!this.isPotionApplicable(effectInstanceIn)) {
|
||||
return false;
|
||||
} else {
|
||||
EffectInstance effectinstance = this.activePotionsMap.get(effectInstanceIn.getPotion());
|
||||
|
||||
boolean override = false;
|
||||
if (effectinstance != null) {
|
||||
override = new EffectInstance(effectinstance).combine(effectInstanceIn);
|
||||
}
|
||||
|
||||
EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent((LivingEntity) (Object) this, effectinstance, effectInstanceIn, cause, override);
|
||||
if (event.isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MinecraftForge.EVENT_BUS.post(new PotionEvent.PotionAddedEvent((LivingEntity) (Object) this, effectinstance, effectInstanceIn));
|
||||
if (effectinstance == null) {
|
||||
this.activePotionsMap.put(effectInstanceIn.getPotion(), effectInstanceIn);
|
||||
this.onNewPotionEffect(effectInstanceIn);
|
||||
return true;
|
||||
} else if (event.isOverride()) {
|
||||
effectinstance.combine(effectInstanceIn);
|
||||
this.onChangedPotionEffect(effectinstance, true);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused") // mock
|
||||
public EffectInstance c(@Nullable Effect potioneffectin, EntityPotionEffectEvent.Cause cause) {
|
||||
bridge$pushEffectCause(cause);
|
||||
return removeActivePotionEffect(potioneffectin);
|
||||
}
|
||||
|
||||
@Inject(method = "removeActivePotionEffect", at = @At("HEAD"))
|
||||
public void arclight$clearActive(Effect effect, CallbackInfoReturnable<EffectInstance> cir) {
|
||||
EntityPotionEffectEvent.Cause cause = bridge$getEffectCause().orElse(EntityPotionEffectEvent.Cause.UNKNOWN);
|
||||
if (isTickingEffects) {
|
||||
effectsToProcess.add(Maps.immutableEntry(Either.right(effect), cause));
|
||||
cir.setReturnValue(null);
|
||||
return;
|
||||
}
|
||||
|
||||
EffectInstance effectInstance = this.activePotionsMap.get(effect);
|
||||
if (effectInstance == null) {
|
||||
cir.setReturnValue(null);
|
||||
return;
|
||||
}
|
||||
|
||||
EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent((LivingEntity) (Object) this, effectInstance, null, cause);
|
||||
if (event.isCancelled()) {
|
||||
cir.setReturnValue(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bridge$dropExperience() {
|
||||
this.dropExperience();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bridge$createWitherRose(LivingEntity entity) {
|
||||
this.createWitherRose(entity);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,177 @@
|
||||
package io.izzel.arclight.common.mixin.v1_15.entity.boss;
|
||||
|
||||
import io.izzel.arclight.common.mixin.core.entity.CreatureEntityMixin;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityPredicate;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.boss.WitherEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.Difficulty;
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.world.server.ServerBossInfo;
|
||||
import net.minecraftforge.event.ForgeEventFactory;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||
import org.bukkit.event.entity.EntityTargetEvent;
|
||||
import org.bukkit.event.entity.ExplosionPrimeEvent;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(WitherEntity.class)
|
||||
public abstract class WitherEntityMixin_1_15 extends CreatureEntityMixin {
|
||||
|
||||
// @formatter:off
|
||||
@Shadow public abstract int getInvulTime();
|
||||
@Shadow public abstract void setInvulTime(int time);
|
||||
@Shadow @Final private int[] nextHeadUpdate;
|
||||
@Shadow @Final private int[] idleHeadUpdates;
|
||||
@Shadow protected abstract void launchWitherSkullToCoords(int p_82209_1_, double x, double y, double z, boolean invulnerable);
|
||||
@Shadow public abstract int getWatchedTargetId(int head);
|
||||
@Shadow public abstract void updateWatchedTargetId(int targetOffset, int newId);
|
||||
@Shadow protected abstract void launchWitherSkullToEntity(int p_82216_1_, LivingEntity p_82216_2_);
|
||||
@Shadow @Final private static EntityPredicate field_213798_bB;
|
||||
@Shadow private int blockBreakCounter;
|
||||
@Shadow @Final public ServerBossInfo bossInfo;
|
||||
// @formatter:on
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
*/
|
||||
@Overwrite
|
||||
protected void updateAITasks() {
|
||||
if (this.getInvulTime() > 0) {
|
||||
int j1 = this.getInvulTime() - 1;
|
||||
if (j1 <= 0) {
|
||||
Explosion.Mode explosion$mode = ForgeEventFactory.getMobGriefingEvent(this.world, (WitherEntity) (Object) this) ? Explosion.Mode.DESTROY : Explosion.Mode.NONE;
|
||||
ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 7.0F, false);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
this.world.createExplosion((WitherEntity) (Object) this, this.posX, this.bridge$getEyeHeight(), this.posZ, event.getRadius(), event.getFire(), explosion$mode);
|
||||
}
|
||||
this.world.playBroadcastSound(1023, new BlockPos((WitherEntity) (Object) this), 0);
|
||||
}
|
||||
|
||||
this.setInvulTime(j1);
|
||||
if (this.ticksExisted % 10 == 0) {
|
||||
bridge$pushHealReason(EntityRegainHealthEvent.RegainReason.WITHER_SPAWN);
|
||||
this.heal(10.0F);
|
||||
}
|
||||
|
||||
} else {
|
||||
super.updateAITasks();
|
||||
|
||||
for (int i = 1; i < 3; ++i) {
|
||||
if (this.ticksExisted >= this.nextHeadUpdate[i - 1]) {
|
||||
this.nextHeadUpdate[i - 1] = this.ticksExisted + 10 + this.rand.nextInt(10);
|
||||
if (this.world.getDifficulty() == Difficulty.NORMAL || this.world.getDifficulty() == Difficulty.HARD) {
|
||||
int j3 = i - 1;
|
||||
int k3 = this.idleHeadUpdates[i - 1];
|
||||
this.idleHeadUpdates[j3] = this.idleHeadUpdates[i - 1] + 1;
|
||||
if (k3 > 15) {
|
||||
float f = 10.0F;
|
||||
float f1 = 5.0F;
|
||||
double d0 = MathHelper.nextDouble(this.rand, this.posX - 10.0D, this.posX + 10.0D);
|
||||
double d1 = MathHelper.nextDouble(this.rand, this.posY - 5.0D, this.posY + 5.0D);
|
||||
double d2 = MathHelper.nextDouble(this.rand, this.posZ - 10.0D, this.posZ + 10.0D);
|
||||
this.launchWitherSkullToCoords(i + 1, d0, d1, d2, true);
|
||||
this.idleHeadUpdates[i - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int k1 = this.getWatchedTargetId(i);
|
||||
if (k1 > 0) {
|
||||
Entity entity = this.world.getEntityByID(k1);
|
||||
if (entity != null && entity.isAlive() && !(this.getDistanceSq(entity) > 900.0D) && this.canEntityBeSeen(entity)) {
|
||||
if (entity instanceof PlayerEntity && ((PlayerEntity) entity).abilities.disableDamage) {
|
||||
this.updateWatchedTargetId(i, 0);
|
||||
} else {
|
||||
this.launchWitherSkullToEntity(i + 1, (LivingEntity) entity);
|
||||
this.nextHeadUpdate[i - 1] = this.ticksExisted + 40 + this.rand.nextInt(20);
|
||||
this.idleHeadUpdates[i - 1] = 0;
|
||||
}
|
||||
} else {
|
||||
this.updateWatchedTargetId(i, 0);
|
||||
}
|
||||
} else {
|
||||
List<LivingEntity> list = this.world.getTargettableEntitiesWithinAABB(LivingEntity.class, field_213798_bB, (WitherEntity) (Object) this, this.getBoundingBox().grow(20.0D, 8.0D, 20.0D));
|
||||
|
||||
for (int j2 = 0; j2 < 10 && !list.isEmpty(); ++j2) {
|
||||
LivingEntity livingentity = list.get(this.rand.nextInt(list.size()));
|
||||
if (livingentity != (Object) this && livingentity.isAlive() && this.canEntityBeSeen(livingentity)) {
|
||||
if (livingentity instanceof PlayerEntity) {
|
||||
if (!((PlayerEntity) livingentity).abilities.disableDamage) {
|
||||
if (CraftEventFactory.callEntityTargetLivingEvent((WitherEntity) (Object) this, livingentity, EntityTargetEvent.TargetReason.CLOSEST_ENTITY).isCancelled())
|
||||
continue;
|
||||
this.updateWatchedTargetId(i, livingentity.getEntityId());
|
||||
}
|
||||
} else {
|
||||
if (CraftEventFactory.callEntityTargetLivingEvent((WitherEntity) (Object) this, livingentity, EntityTargetEvent.TargetReason.CLOSEST_ENTITY).isCancelled())
|
||||
continue;
|
||||
this.updateWatchedTargetId(i, livingentity.getEntityId());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
list.remove(livingentity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getAttackTarget() != null) {
|
||||
this.updateWatchedTargetId(0, this.getAttackTarget().getEntityId());
|
||||
} else {
|
||||
this.updateWatchedTargetId(0, 0);
|
||||
}
|
||||
|
||||
if (this.blockBreakCounter > 0) {
|
||||
--this.blockBreakCounter;
|
||||
if (this.blockBreakCounter == 0 && ForgeEventFactory.getMobGriefingEvent(this.world, (WitherEntity) (Object) this)) {
|
||||
int i1 = MathHelper.floor(this.posY);
|
||||
int l1 = MathHelper.floor(this.posX);
|
||||
int i2 = MathHelper.floor(this.posZ);
|
||||
boolean flag = false;
|
||||
|
||||
for (int k2 = -1; k2 <= 1; ++k2) {
|
||||
for (int l2 = -1; l2 <= 1; ++l2) {
|
||||
for (int j = 0; j <= 3; ++j) {
|
||||
int i3 = l1 + k2;
|
||||
int k = i1 + j;
|
||||
int l = i2 + l2;
|
||||
BlockPos blockpos = new BlockPos(i3, k, l);
|
||||
BlockState blockstate = this.world.getBlockState(blockpos);
|
||||
if (blockstate.canEntityDestroy(this.world, blockpos, (WitherEntity) (Object) this) && ForgeEventFactory.onEntityDestroyBlock((WitherEntity) (Object) this, blockpos, blockstate)) {
|
||||
if (CraftEventFactory.callEntityChangeBlockEvent((WitherEntity) (Object) this, blockpos, Blocks.AIR.getDefaultState()).isCancelled()) {
|
||||
continue;
|
||||
}
|
||||
flag = this.world.destroyBlock(blockpos, true, (WitherEntity) (Object) this) || flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
this.world.playEvent(null, 1022, new BlockPos((WitherEntity) (Object) this), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.ticksExisted % 20 == 0) {
|
||||
bridge$pushHealReason(EntityRegainHealthEvent.RegainReason.REGEN);
|
||||
this.heal(1.0F);
|
||||
}
|
||||
|
||||
this.bossInfo.setPercent(this.getHealth() / this.getMaxHealth());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package io.izzel.arclight.common.mixin.v1_15.entity.item;
|
||||
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(ItemEntity.class)
|
||||
public class ItemEntityMixin_1_15 {
|
||||
|
||||
@Redirect(method = "func_226531_a_", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/item/ItemEntity;setItem(Lnet/minecraft/item/ItemStack;)V"))
|
||||
private static void arclight$setNonEmpty(ItemEntity itemEntity, ItemStack stack) {
|
||||
if (!stack.isEmpty()) {
|
||||
itemEntity.setItem(stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package io.izzel.arclight.common.mixin.v1_15.entity.monster;
|
||||
|
||||
import io.izzel.arclight.common.bridge.entity.player.PlayerEntityBridge;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.monster.AbstractRaiderEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.world.raid.Raid;
|
||||
import org.bukkit.event.entity.EntityPotionEffectEvent;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
@Mixin(AbstractRaiderEntity.class)
|
||||
public class AbstractRaiderEntityMixin {
|
||||
|
||||
@Inject(method = "onDeath", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;addPotionEffect(Lnet/minecraft/potion/EffectInstance;)Z"))
|
||||
private void arclight$raid(DamageSource cause, CallbackInfo ci, Entity entity, Raid raid, ItemStack itemStack, PlayerEntity playerEntity) {
|
||||
((PlayerEntityBridge) playerEntity).bridge$pushEffectCause(EntityPotionEffectEvent.Cause.PATROL_CAPTAIN);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package io.izzel.arclight.common.mixin.v1_15.entity.monster;
|
||||
|
||||
import io.izzel.arclight.common.mixin.core.entity.CreatureEntityMixin;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.monster.RavagerEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(RavagerEntity.class)
|
||||
public abstract class RavagerEntityMixin_1_15 extends CreatureEntityMixin {
|
||||
|
||||
@Redirect(method = "livingTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;destroyBlock(Lnet/minecraft/util/math/BlockPos;ZLnet/minecraft/entity/Entity;)Z"))
|
||||
private boolean arclight$entityChangeBlock(World world, BlockPos pos, boolean p_225521_2_, Entity entityIn) {
|
||||
return !CraftEventFactory.callEntityChangeBlockEvent((RavagerEntity) (Object) this, pos, Blocks.AIR.getDefaultState()).isCancelled()
|
||||
&& world.destroyBlock(pos, p_225521_2_, entityIn);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package io.izzel.arclight.common.mixin.v1_15.entity.monster;
|
||||
|
||||
import io.izzel.arclight.common.mixin.core.entity.CreatureEntityMixin;
|
||||
import net.minecraft.entity.monster.ShulkerEntity;
|
||||
import net.minecraft.network.datasync.DataParameter;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(ShulkerEntity.class)
|
||||
public abstract class ShulkerEntityMixin_1_15 extends CreatureEntityMixin {
|
||||
|
||||
@Inject(method = "notifyDataManagerChange", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/entity/monster/ShulkerEntity;forceSetPosition(DDD)V"))
|
||||
private void arclight$chunkCheck(DataParameter<?> key, CallbackInfo ci) {
|
||||
if (valid) ((ServerWorld) this.world).chunkCheck((ShulkerEntity) (Object) this);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
package io.izzel.arclight.common.mixin.v1_15.entity.monster;
|
||||
|
||||
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
||||
import io.izzel.arclight.common.mixin.core.entity.monster.ZombieEntityMixin;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.monster.ZombiePigmanEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.PigZombie;
|
||||
import org.bukkit.event.entity.PigZombieAngerEvent;
|
||||
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.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(ZombiePigmanEntity.class)
|
||||
public abstract class ZombiePigmanEntityMixin_1_15 extends ZombieEntityMixin {
|
||||
|
||||
// @formatter:off
|
||||
@Shadow protected abstract boolean func_226547_i_(LivingEntity p_70835_1_);
|
||||
@Shadow protected abstract int func_223336_ef();
|
||||
// @formatter:on
|
||||
|
||||
public boolean attackEntityFrom(DamageSource damagesource, float f) {
|
||||
if (this.isInvulnerableTo(damagesource)) {
|
||||
return false;
|
||||
}
|
||||
Entity entity = damagesource.getTrueSource();
|
||||
boolean result = super.attackEntityFrom(damagesource, f);
|
||||
if (result && entity instanceof PlayerEntity && !((PlayerEntity) entity).isCreative() && this.canEntityBeSeen(entity)) {
|
||||
this.func_226547_i_((LivingEntity) entity);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Inject(method = "func_226547_i_", cancellable = true, at = @At("HEAD"))
|
||||
private void arclight$anger(LivingEntity entity, CallbackInfoReturnable<Boolean> cir) {
|
||||
PigZombieAngerEvent event = new PigZombieAngerEvent((PigZombie) this.getBukkitEntity(), (entity == null) ? null : ((EntityBridge) entity).bridge$getBukkitEntity(), this.func_223336_ef());
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
cir.setReturnValue(false);
|
||||
} else {
|
||||
arclight$capture = event.getNewAnger();
|
||||
}
|
||||
}
|
||||
|
||||
private transient int arclight$capture;
|
||||
|
||||
@Redirect(method = "func_226547_i_", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/monster/ZombiePigmanEntity;func_223336_ef()I"))
|
||||
private int arclight$useAnger(ZombiePigmanEntity pigmanEntity) {
|
||||
return arclight$capture;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,145 @@
|
||||
package io.izzel.arclight.common.mixin.v1_15.entity.player;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import io.izzel.arclight.common.bridge.entity.InternalEntityBridge;
|
||||
import io.izzel.arclight.common.bridge.entity.player.PlayerEntityBridge;
|
||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||
import io.izzel.arclight.common.mixin.core.entity.LivingEntityMixin;
|
||||
import net.minecraft.entity.player.PlayerAbilities;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v.block.CraftBlock;
|
||||
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerBedLeaveEvent;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(PlayerEntity.class)
|
||||
public abstract class PlayerEntityMixin_1_15 extends LivingEntityMixin implements PlayerEntityBridge {
|
||||
|
||||
// @formatter:off
|
||||
@Shadow public abstract Either<PlayerEntity.SleepResult, Unit> trySleep(BlockPos at);
|
||||
@Shadow public abstract void startSleeping(BlockPos p_213342_1_);
|
||||
@Shadow public int sleepTimer;
|
||||
@Shadow @Final public PlayerAbilities abilities;
|
||||
// @formatter:on
|
||||
|
||||
@Shadow
|
||||
public abstract void addStat(ResourceLocation stat);
|
||||
|
||||
@Override
|
||||
public CraftHumanEntity bridge$getBukkitEntity() {
|
||||
return (CraftHumanEntity) ((InternalEntityBridge) this).internal$getBukkitEntity();
|
||||
}
|
||||
|
||||
private boolean arclight$forceSleep = false;
|
||||
private Object arclight$processSleep = null;
|
||||
|
||||
private Either<PlayerEntity.SleepResult, Unit> getBedResult(BlockPos at, Direction direction) {
|
||||
arclight$processSleep = true;
|
||||
Either<PlayerEntity.SleepResult, Unit> either = this.trySleep(at);
|
||||
arclight$processSleep = null;
|
||||
return either;
|
||||
}
|
||||
|
||||
public Either<PlayerEntity.SleepResult, Unit> sleep(BlockPos at, boolean force) {
|
||||
arclight$forceSleep = force;
|
||||
try {
|
||||
return this.trySleep(at);
|
||||
} finally {
|
||||
arclight$forceSleep = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "trySleep", cancellable = true, at = @At(value = "HEAD"))
|
||||
public void arclight$onSleep(BlockPos at, CallbackInfoReturnable<Either<PlayerEntity.SleepResult, Unit>> cir) {
|
||||
if (arclight$processSleep == null) {
|
||||
Either<PlayerEntity.SleepResult, Unit> result = getBedResult(at, null);
|
||||
|
||||
if (result.left().orElse(null) == PlayerEntity.SleepResult.OTHER_PROBLEM) {
|
||||
cir.setReturnValue(result);
|
||||
return;
|
||||
}
|
||||
if (arclight$forceSleep) {
|
||||
result = Either.right(Unit.INSTANCE);
|
||||
}
|
||||
if (this.bridge$getBukkitEntity() instanceof Player) {
|
||||
result = CraftEventFactory.callPlayerBedEnterEvent((PlayerEntity) (Object) this, at, result);
|
||||
if (result.left().isPresent()) {
|
||||
cir.setReturnValue(result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.startSleeping(at);
|
||||
this.sleepTimer = 0;
|
||||
if (this.world instanceof ServerWorld) {
|
||||
((ServerWorld) this.world).updateAllPlayersSleepingFlag();
|
||||
}
|
||||
cir.setReturnValue(Either.right(Unit.INSTANCE));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "trySleep", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;startSleeping(Lnet/minecraft/util/math/BlockPos;)V"))
|
||||
public void arclight$preSleep(BlockPos at, CallbackInfoReturnable<Either<PlayerEntity.SleepResult, Unit>> cir) {
|
||||
if (arclight$processSleep != null) {
|
||||
cir.setReturnValue(Either.right(Unit.INSTANCE));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "stopSleepInBed", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/player/PlayerEntity;sleepTimer:I"))
|
||||
private void arclight$wakeup(boolean flag, boolean flag1, CallbackInfo ci) {
|
||||
BlockPos blockPos = this.getBedPosition().orElse(null);
|
||||
if (this.getBukkitEntity() instanceof Player) {
|
||||
Player player = (Player) this.getBukkitEntity();
|
||||
Block bed;
|
||||
if (blockPos != null) {
|
||||
bed = CraftBlock.at(this.world, blockPos);
|
||||
} else {
|
||||
bed = ((WorldBridge) this.world).bridge$getWorld().getBlockAt(player.getLocation());
|
||||
}
|
||||
PlayerBedLeaveEvent event = new PlayerBedLeaveEvent(player, bed, true);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "setSpawnPoint", remap = false, at = @At("RETURN"))
|
||||
private void arclight$updateSpawnpoint(BlockPos pos, boolean p_226560_2_, boolean p_226560_3_, DimensionType dim, CallbackInfo ci) {
|
||||
bridge$setSpawnWorld(pos == null ? "" : this.world.worldInfo.getWorldName());
|
||||
}
|
||||
|
||||
@Inject(method = "startFallFlying", cancellable = true, at = @At("HEAD"))
|
||||
private void arclight$startGlidingEvent(CallbackInfo ci) {
|
||||
if (CraftEventFactory.callToggleGlideEvent((PlayerEntity) (Object) this, true).isCancelled()) {
|
||||
this.setFlag(7, true);
|
||||
this.setFlag(7, false);
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "stopFallFlying", cancellable = true, at = @At("HEAD"))
|
||||
private void arclight$stopGlidingEvent(CallbackInfo ci) {
|
||||
if (CraftEventFactory.callToggleGlideEvent((PlayerEntity) (Object) this, false).isCancelled()) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Either<PlayerEntity.SleepResult, Unit> bridge$trySleep(BlockPos at, boolean force) {
|
||||
return sleep(at, force);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,326 @@
|
||||
package io.izzel.arclight.common.mixin.v1_15.entity.player;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import io.izzel.arclight.common.bridge.entity.InternalEntityBridge;
|
||||
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
||||
import io.izzel.arclight.common.bridge.network.play.ServerPlayNetHandlerBridge;
|
||||
import io.izzel.arclight.common.bridge.world.TeleporterBridge;
|
||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||
import io.izzel.arclight.common.bridge.world.dimension.DimensionTypeBridge;
|
||||
import io.izzel.arclight.common.bridge.world.server.ServerWorldBridge;
|
||||
import net.minecraft.advancements.CriteriaTriggers;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.pattern.BlockPattern;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.network.play.ServerPlayNetHandler;
|
||||
import net.minecraft.network.play.server.SChangeGameStatePacket;
|
||||
import net.minecraft.network.play.server.SPlayEntityEffectPacket;
|
||||
import net.minecraft.network.play.server.SPlaySoundEventPacket;
|
||||
import net.minecraft.network.play.server.SPlayerAbilitiesPacket;
|
||||
import net.minecraft.network.play.server.SRespawnPacket;
|
||||
import net.minecraft.network.play.server.SServerDifficultyPacket;
|
||||
import net.minecraft.potion.EffectInstance;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.management.PlayerInteractionManager;
|
||||
import net.minecraft.server.management.PlayerList;
|
||||
import net.minecraft.stats.Stats;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.Teleporter;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraft.world.storage.WorldInfo;
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
import net.minecraftforge.common.util.ITeleporter;
|
||||
import net.minecraftforge.fml.hooks.BasicEventHooks;
|
||||
import net.minecraftforge.fml.network.NetworkHooks;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.craftbukkit.v.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.v.util.BlockStateListPopulator;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
import org.bukkit.event.player.PlayerPortalEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.event.world.PortalCreateEvent;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
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 javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(ServerPlayerEntity.class)
|
||||
public abstract class ServerPlayerEntityMixin_1_15 extends PlayerEntityMixin_1_15 implements ServerPlayerEntityBridge {
|
||||
|
||||
// @formatter:off
|
||||
@Shadow public boolean invulnerableDimensionChange;
|
||||
@Shadow public abstract ServerWorld getServerWorld();
|
||||
@Shadow public boolean queuedEndExit;
|
||||
@Shadow public ServerPlayNetHandler connection;
|
||||
@Shadow private boolean seenCredits;
|
||||
@Shadow @Final public MinecraftServer server;
|
||||
@Shadow @Final public PlayerInteractionManager interactionManager;
|
||||
@Shadow @Nullable private Vec3d enteredNetherPosition;
|
||||
@Shadow public abstract void func_213846_b(ServerWorld p_213846_1_);
|
||||
@Shadow public int lastExperience;
|
||||
@Shadow private float lastHealth;
|
||||
@Shadow private int lastFoodLevel;
|
||||
// @formatter:on
|
||||
|
||||
@Override
|
||||
public CraftPlayer bridge$getBukkitEntity() {
|
||||
return (CraftPlayer) ((InternalEntityBridge) this).internal$getBukkitEntity();
|
||||
}
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
*/
|
||||
@Overwrite
|
||||
@Nullable
|
||||
public Entity changeDimension(DimensionType dim, ITeleporter teleporter) {
|
||||
final DimensionType[] destination = {dim};
|
||||
if (this.isSleeping()) return (ServerPlayerEntity) (Object) this;
|
||||
|
||||
if (!ForgeHooks.onTravelToDimension((ServerPlayerEntity) (Object) this, destination[0])) return null;
|
||||
|
||||
PlayerTeleportEvent.TeleportCause cause = bridge$getTeleportCause().orElse(PlayerTeleportEvent.TeleportCause.UNKNOWN);
|
||||
// this.invulnerableDimensionChange = true;
|
||||
DimensionType dimensiontype = this.dimension;
|
||||
if (((DimensionTypeBridge) dimensiontype).bridge$getType() == DimensionType.THE_END && ((DimensionTypeBridge) destination[0]).bridge$getType() == DimensionType.OVERWORLD && teleporter instanceof Teleporter) { //Forge: Fix non-vanilla teleporters triggering end credits
|
||||
this.invulnerableDimensionChange = true;
|
||||
this.detach();
|
||||
this.getServerWorld().removePlayer((ServerPlayerEntity) (Object) this, true); //Forge: The player entity is cloned so keep the data until after cloning calls copyFrom
|
||||
if (!this.queuedEndExit) {
|
||||
this.queuedEndExit = true;
|
||||
this.connection.sendPacket(new SChangeGameStatePacket(4, this.seenCredits ? 0.0F : 1.0F));
|
||||
this.seenCredits = true;
|
||||
}
|
||||
|
||||
return (ServerPlayerEntity) (Object) this;
|
||||
} else {
|
||||
ServerWorld serverworld = this.server.getWorld(dimensiontype);
|
||||
// this.dimension = destination;
|
||||
final ServerWorld[] serverworld1 = {this.server.getWorld(destination[0])};
|
||||
|
||||
/*
|
||||
WorldInfo worldinfo = serverworld1.getWorldInfo();
|
||||
NetworkHooks.sendDimensionDataPacket(this.connection.netManager, (ServerPlayerEntity) (Object) this);
|
||||
this.connection.sendPacket(new SRespawnPacket(destination, WorldInfo.byHashing(worldinfo.getSeed()), worldinfo.getGenerator(), this.interactionManager.getGameType()));
|
||||
this.connection.sendPacket(new SServerDifficultyPacket(worldinfo.getDifficulty(), worldinfo.isDifficultyLocked()));
|
||||
PlayerList playerlist = this.server.getPlayerList();
|
||||
playerlist.updatePermissionLevel((ServerPlayerEntity) (Object) this);
|
||||
serverworld.removeEntity((ServerPlayerEntity) (Object) this, true); //Forge: the player entity is moved to the new world, NOT cloned. So keep the data alive with no matching invalidate call.
|
||||
this.revive();
|
||||
*/
|
||||
final PlayerList[] playerlist = new PlayerList[1];
|
||||
|
||||
Entity e = teleporter.placeEntity((ServerPlayerEntity) (Object) this, serverworld, serverworld1[0], this.rotationYaw, spawnPortal -> {//Forge: Start vanilla logic
|
||||
double d0 = this.getPosX();
|
||||
double d1 = this.getPosY();
|
||||
double d2 = this.getPosZ();
|
||||
float f = this.rotationPitch;
|
||||
float f1 = this.rotationYaw;
|
||||
double d3 = 8.0D;
|
||||
float f2 = f1;
|
||||
serverworld.getProfiler().startSection("moving");
|
||||
|
||||
if (serverworld1[0] != null) {
|
||||
double moveFactor = serverworld.getDimension().getMovementFactor() / serverworld1[0].getDimension().getMovementFactor();
|
||||
d0 *= moveFactor;
|
||||
d2 *= moveFactor;
|
||||
if (dimensiontype == DimensionType.OVERWORLD && destination[0] == DimensionType.THE_NETHER) {
|
||||
this.enteredNetherPosition = this.getPositionVec();
|
||||
} else if (dimensiontype == DimensionType.OVERWORLD && destination[0] == DimensionType.THE_END) {
|
||||
BlockPos blockpos = serverworld1[0].getSpawnCoordinate();
|
||||
d0 = blockpos.getX();
|
||||
d1 = blockpos.getY();
|
||||
d2 = blockpos.getZ();
|
||||
f1 = 90.0F;
|
||||
f = 0.0F;
|
||||
}
|
||||
}
|
||||
|
||||
Location enter = this.getBukkitEntity().getLocation();
|
||||
Location exit = (serverworld1[0] == null) ? null : new Location(((ServerWorldBridge) serverworld1[0]).bridge$getWorld(), d0, d1, d2, f1, f);
|
||||
PlayerPortalEvent event = new PlayerPortalEvent((Player) this.getBukkitEntity(), enter, exit, cause, 128, true, ((DimensionTypeBridge) destination[0]).bridge$getType() == DimensionType.THE_END ? 0 : 16);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled() || event.getTo() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
exit = event.getTo();
|
||||
if (exit == null) {
|
||||
return null;
|
||||
}
|
||||
serverworld1[0] = ((CraftWorld) exit.getWorld()).getHandle();
|
||||
d0 = exit.getX();
|
||||
d1 = exit.getY();
|
||||
d2 = exit.getZ();
|
||||
|
||||
// this.setLocationAndAngles(d0, d1, d2, f1, f);
|
||||
serverworld.getProfiler().endSection();
|
||||
serverworld.getProfiler().startSection("placing");
|
||||
double d7 = Math.max(-2.9999872E7D, serverworld1[0].getWorldBorder().minX() + 16.0D);
|
||||
double d4 = Math.max(-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, d7, d5);
|
||||
d2 = MathHelper.clamp(d2, d4, d6);
|
||||
// this.setLocationAndAngles(d0, d1, d2, f1, f);
|
||||
|
||||
Vec3d exitVelocity = Vec3d.ZERO;
|
||||
BlockPos exitPosition = new BlockPos(d0, d1, d2);
|
||||
|
||||
if (((DimensionTypeBridge) destination[0]).bridge$getType() == DimensionType.THE_END) {
|
||||
int i = exitPosition.getX();
|
||||
int j = exitPosition.getY() - 1;
|
||||
int k = exitPosition.getZ();
|
||||
|
||||
if (event.getCanCreatePortal()) {
|
||||
|
||||
BlockStateListPopulator blockList = new BlockStateListPopulator(serverworld1[0]);
|
||||
|
||||
for (int j1 = -2; j1 <= 2; ++j1) {
|
||||
for (int k1 = -2; k1 <= 2; ++k1) {
|
||||
for (int l1 = -1; l1 < 3; ++l1) {
|
||||
int i2 = i + k1 * 1 + j1 * 0;
|
||||
int j2 = j + l1;
|
||||
int k2 = k + k1 * 0 - j1 * 1;
|
||||
boolean flag = l1 < 0;
|
||||
blockList.setBlockState(new BlockPos(i2, j2, k2), flag ? Blocks.OBSIDIAN.getDefaultState() : Blocks.AIR.getDefaultState(), 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
org.bukkit.World bworld = ((ServerWorldBridge) serverworld1[0]).bridge$getWorld();
|
||||
PortalCreateEvent portalEvent = new PortalCreateEvent((List<BlockState>) (List) blockList.getList(), bworld, this.getBukkitEntity(), PortalCreateEvent.CreateReason.END_PLATFORM);
|
||||
|
||||
Bukkit.getPluginManager().callEvent(portalEvent);
|
||||
if (!portalEvent.isCancelled()) {
|
||||
blockList.updateList();
|
||||
}
|
||||
}
|
||||
|
||||
// this.setLocationAndAngles(i, j, k, f1, 0.0F);
|
||||
exit.setX(i);
|
||||
exit.setY(j);
|
||||
exit.setZ(k);
|
||||
// this.setMotion(Vec3d.ZERO);
|
||||
exitVelocity = Vec3d.ZERO;
|
||||
} else {
|
||||
BlockPattern.PortalInfo portalInfo = ((TeleporterBridge) serverworld1[0].getDefaultTeleporter()).bridge$placeInPortal((ServerPlayerEntity) (Object) this, exitPosition, f2, event.getSearchRadius(), true);
|
||||
if (spawnPortal && portalInfo == null && event.getCanCreatePortal()) {
|
||||
if (((TeleporterBridge) serverworld1[0].getDefaultTeleporter()).bridge$makePortal((ServerPlayerEntity) (Object) this, exitPosition, event.getCreationRadius())) {
|
||||
// serverworld1.getDefaultTeleporter().placeInPortal((ServerPlayerEntity) (Object) this, f2);
|
||||
portalInfo = ((TeleporterBridge) serverworld1[0].getDefaultTeleporter()).bridge$placeInPortal((ServerPlayerEntity) (Object) this, exitPosition, f2, event.getSearchRadius(), true);
|
||||
}
|
||||
}
|
||||
if (portalInfo == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
exitVelocity = portalInfo.motion;
|
||||
exit.setX(portalInfo.pos.getX());
|
||||
exit.setY(portalInfo.pos.getY());
|
||||
exit.setZ(portalInfo.pos.getZ());
|
||||
exit.setYaw(f2 + (float) portalInfo.rotation);
|
||||
}
|
||||
|
||||
serverworld.getProfiler().endSection();
|
||||
|
||||
final PlayerTeleportEvent tpEvent = new PlayerTeleportEvent((Player) this.getBukkitEntity(), enter, exit, cause);
|
||||
Bukkit.getServer().getPluginManager().callEvent(tpEvent);
|
||||
if (tpEvent.isCancelled() || tpEvent.getTo() == null) {
|
||||
return null;
|
||||
}
|
||||
exit = tpEvent.getTo();
|
||||
if (exit == null) {
|
||||
return null;
|
||||
}
|
||||
serverworld1[0] = ((CraftWorld) exit.getWorld()).getHandle();
|
||||
this.invulnerableDimensionChange = true;
|
||||
|
||||
destination[0] = serverworld1[0].getDimension().getType();
|
||||
this.dimension = destination[0];
|
||||
|
||||
WorldInfo worldinfo = serverworld1[0].getWorldInfo();
|
||||
NetworkHooks.sendDimensionDataPacket(this.connection.netManager, (ServerPlayerEntity) (Object) this);
|
||||
this.connection.sendPacket(new SRespawnPacket(destination[0], WorldInfo.byHashing(worldinfo.getSeed()), worldinfo.getGenerator(), this.interactionManager.getGameType()));
|
||||
this.connection.sendPacket(new SServerDifficultyPacket(worldinfo.getDifficulty(), worldinfo.isDifficultyLocked()));
|
||||
|
||||
playerlist[0] = this.server.getPlayerList();
|
||||
playerlist[0].updatePermissionLevel((ServerPlayerEntity) (Object) this);
|
||||
|
||||
serverworld.removeEntity((ServerPlayerEntity) (Object) this, true); //Forge: the player entity is moved to the new world, NOT cloned. So keep the data alive with no matching invalidate call.
|
||||
this.revive();
|
||||
|
||||
this.setMotion(exitVelocity);
|
||||
|
||||
this.setWorld(serverworld1[0]);
|
||||
serverworld1[0].addDuringPortalTeleport((ServerPlayerEntity) (Object) this);
|
||||
this.func_213846_b(serverworld);
|
||||
|
||||
// this.connection.setPlayerLocation(this.getPosX(), this.getPosY(), this.getPosZ(), f1, f);
|
||||
((ServerPlayNetHandlerBridge) this.connection).bridge$teleport(exit);
|
||||
this.connection.captureCurrentPosition();
|
||||
|
||||
return (ServerPlayerEntity) (Object) this;//forge: this is part of the ITeleporter patch
|
||||
});//Forge: End vanilla logic
|
||||
if (e != (Object) this)
|
||||
throw new IllegalArgumentException(String.format("Teleporter %s returned not the player entity but instead %s, expected PlayerEntity %s", teleporter, e, this));
|
||||
this.interactionManager.setWorld(serverworld1[0]);
|
||||
this.connection.sendPacket(new SPlayerAbilitiesPacket(this.abilities));
|
||||
playerlist[0].sendWorldInfo((ServerPlayerEntity) (Object) this, serverworld1[0]);
|
||||
playerlist[0].sendInventory((ServerPlayerEntity) (Object) this);
|
||||
|
||||
for (EffectInstance effectinstance : this.getActivePotionEffects()) {
|
||||
this.connection.sendPacket(new SPlayEntityEffectPacket(this.getEntityId(), effectinstance));
|
||||
}
|
||||
|
||||
this.connection.sendPacket(new SPlaySoundEventPacket(1032, BlockPos.ZERO, 0, false));
|
||||
this.lastExperience = -1;
|
||||
this.lastHealth = -1.0F;
|
||||
this.lastFoodLevel = -1;
|
||||
BasicEventHooks.firePlayerChangedDimensionEvent((ServerPlayerEntity) (Object) this, dimensiontype, destination[0]);
|
||||
|
||||
PlayerChangedWorldEvent changeEvent = new PlayerChangedWorldEvent((Player) this.getBukkitEntity(), ((WorldBridge) serverworld).bridge$getWorld());
|
||||
Bukkit.getPluginManager().callEvent(changeEvent);
|
||||
return (ServerPlayerEntity) (Object) this;
|
||||
}
|
||||
}
|
||||
|
||||
public Entity a(DimensionType dimensionmanager, final PlayerTeleportEvent.TeleportCause cause) {
|
||||
bridge$pushChangeDimensionCause(cause);
|
||||
return this.changeDimension(dimensionmanager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Either<PlayerEntity.SleepResult, Unit> sleep(BlockPos at, boolean force) {
|
||||
return super.sleep(at, force).ifRight((p_213849_1_) -> {
|
||||
this.addStat(Stats.SLEEP_IN_BED);
|
||||
CriteriaTriggers.SLEPT_IN_BED.trigger((ServerPlayerEntity) (Object) this);
|
||||
});
|
||||
}
|
||||
|
||||
@Inject(method = "stopSleepInBed", cancellable = true, at = @At("HEAD"))
|
||||
private void arclight$notWake(boolean flag, boolean flag1, CallbackInfo ci) {
|
||||
if (!isSleeping()) ci.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity bridge$changeDimension(DimensionType dimensionType, PlayerTeleportEvent.TeleportCause cause) {
|
||||
return a(dimensionType, cause);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package io.izzel.arclight.common.mixin.v1_15.item.crafting;
|
||||
|
||||
import io.izzel.arclight.common.bridge.item.crafting.IRecipeBridge;
|
||||
import net.minecraft.item.crafting.SpecialRecipe;
|
||||
import org.bukkit.inventory.Recipe;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
@Mixin(SpecialRecipe.class)
|
||||
public class SpecialRecipeMixin implements IRecipeBridge {
|
||||
|
||||
@Override
|
||||
public Recipe bridge$toBukkitRecipe() {
|
||||
return new org.bukkit.craftbukkit.v.inventory.CraftComplexRecipe((SpecialRecipe) (Object) this);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,139 @@
|
||||
package io.izzel.arclight.common.mixin.v1_15.world;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import io.izzel.arclight.common.bridge.world.ExplosionBridge;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraft.world.storage.loot.LootContext;
|
||||
import net.minecraft.world.storage.loot.LootParameters;
|
||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||
import org.bukkit.event.block.BlockIgniteEvent;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
@Mixin(Explosion.class)
|
||||
public abstract class ExplosionMixin_1_15 implements ExplosionBridge {
|
||||
|
||||
// @formatter:off
|
||||
@Shadow @Final private World world;
|
||||
@Shadow @Final private Explosion.Mode mode;
|
||||
@Shadow @Mutable @Final private float size;
|
||||
@Shadow @Final private List<BlockPos> affectedBlockPositions;
|
||||
@Shadow @Final private double x;
|
||||
@Shadow @Final private double y;
|
||||
@Shadow @Final private double z;
|
||||
@Shadow @Final private boolean causesFire;
|
||||
@Shadow @Final private Random random;
|
||||
@Shadow @Final public Entity exploder;
|
||||
@Shadow private static void func_229976_a_(ObjectArrayList<Pair<ItemStack, BlockPos>> p_229976_0_, ItemStack p_229976_1_, BlockPos p_229976_2_) { }
|
||||
@Accessor("exploder") public abstract Entity bridge$getExploder();
|
||||
@Accessor("size") public abstract float bridge$getSize();
|
||||
@Accessor("size") public abstract void bridge$setSize(float size);
|
||||
@Accessor("mode") public abstract Explosion.Mode bridge$getMode();
|
||||
// @formatter:on
|
||||
|
||||
public boolean wasCanceled = false;
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
*/
|
||||
@Overwrite
|
||||
public void doExplosionB(boolean spawnParticles) {
|
||||
if (this.world.isRemote) {
|
||||
this.world.playSound(this.x, this.y, this.z, SoundEvents.ENTITY_GENERIC_EXPLODE, SoundCategory.BLOCKS, 4.0F, (1.0F + (this.world.rand.nextFloat() - this.world.rand.nextFloat()) * 0.2F) * 0.7F, false);
|
||||
}
|
||||
|
||||
boolean flag = this.mode != Explosion.Mode.NONE;
|
||||
if (spawnParticles) {
|
||||
if (!(this.size < 2.0F) && flag) {
|
||||
this.world.addParticle(ParticleTypes.EXPLOSION_EMITTER, this.x, this.y, this.z, 1.0D, 0.0D, 0.0D);
|
||||
} else {
|
||||
this.world.addParticle(ParticleTypes.EXPLOSION, this.x, this.y, this.z, 1.0D, 0.0D, 0.0D);
|
||||
}
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
ObjectArrayList<Pair<ItemStack, BlockPos>> objectarraylist = new ObjectArrayList<>();
|
||||
Collections.shuffle(this.affectedBlockPositions, this.world.rand);
|
||||
|
||||
float yield = this.bridge$callBlockExplodeEvent();
|
||||
|
||||
if (Float.isNaN(yield)) {
|
||||
this.wasCanceled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
for (BlockPos blockpos : this.affectedBlockPositions) {
|
||||
BlockState blockstate = this.world.getBlockState(blockpos);
|
||||
Block block = blockstate.getBlock();
|
||||
if (!blockstate.isAir(this.world, blockpos)) {
|
||||
BlockPos blockpos1 = blockpos.toImmutable();
|
||||
this.world.getProfiler().startSection("explosion_blocks");
|
||||
if (blockstate.canDropFromExplosion(this.world, blockpos, (Explosion) (Object) this) && this.world instanceof ServerWorld) {
|
||||
TileEntity tileentity = blockstate.hasTileEntity() ? this.world.getTileEntity(blockpos) : null;
|
||||
LootContext.Builder lootcontext$builder = (new LootContext.Builder((ServerWorld) this.world)).withRandom(this.world.rand).withParameter(LootParameters.POSITION, blockpos).withParameter(LootParameters.TOOL, ItemStack.EMPTY).withNullableParameter(LootParameters.BLOCK_ENTITY, tileentity).withNullableParameter(LootParameters.THIS_ENTITY, this.exploder);
|
||||
if (this.mode == Explosion.Mode.DESTROY || yield < 1.0F) {
|
||||
lootcontext$builder.withParameter(LootParameters.EXPLOSION_RADIUS, 1.0F / yield);
|
||||
}
|
||||
|
||||
blockstate.getDrops(lootcontext$builder).forEach((p_229977_2_) -> {
|
||||
func_229976_a_(objectarraylist, p_229977_2_, blockpos1);
|
||||
});
|
||||
}
|
||||
|
||||
blockstate.onBlockExploded(this.world, blockpos, (Explosion) (Object) this);
|
||||
this.world.getProfiler().endSection();
|
||||
}
|
||||
}
|
||||
|
||||
for (Pair<ItemStack, BlockPos> pair : objectarraylist) {
|
||||
Block.spawnAsEntity(this.world, pair.getSecond(), pair.getFirst());
|
||||
}
|
||||
}
|
||||
|
||||
if (this.causesFire) {
|
||||
for (BlockPos blockpos2 : this.affectedBlockPositions) {
|
||||
if (this.random.nextInt(3) == 0 && this.world.getBlockState(blockpos2).isAir() && this.world.getBlockState(blockpos2.down()).isOpaqueCube(this.world, blockpos2.down())) {
|
||||
BlockIgniteEvent event = CraftEventFactory.callBlockIgniteEvent(this.world, blockpos2.getX(), blockpos2.getY(), blockpos2.getZ(), (Explosion) (Object) this);
|
||||
if (!event.isCancelled()) {
|
||||
this.world.setBlockState(blockpos2, Blocks.FIRE.getDefaultState());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "func_229976_a_", cancellable = true, at = @At("HEAD"))
|
||||
private static void arclight$fix(ObjectArrayList<Pair<ItemStack, BlockPos>> p_229976_0_, ItemStack stack, BlockPos p_229976_2_, CallbackInfo ci) {
|
||||
if (stack.isEmpty()) ci.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bridge$wasCancelled() {
|
||||
return wasCanceled;
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package io.izzel.arclight.common.mixin.v1_15.world.dimension;
|
||||
|
||||
import io.izzel.arclight.common.bridge.world.dimension.DimensionTypeBridge;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.IBiomeMagnifier;
|
||||
import net.minecraft.world.dimension.Dimension;
|
||||
@ -9,7 +10,7 @@ import org.spongepowered.asm.mixin.Mixin;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
@Mixin(DimensionType.class)
|
||||
public class DimensionTypeMixin_1_15 {
|
||||
public class DimensionTypeMixin_1_15 implements DimensionTypeBridge {
|
||||
|
||||
protected void arclight$constructor(int idIn, String suffixIn, String directoryIn, BiFunction<World, DimensionType, ? extends Dimension> p_i49935_4_, boolean p_i49935_5_, IBiomeMagnifier p_i225789_6_) {
|
||||
throw new RuntimeException();
|
||||
@ -25,4 +26,9 @@ public class DimensionTypeMixin_1_15 {
|
||||
public DimensionType getType() {
|
||||
return (type == null) ? (DimensionType) (Object) this : type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DimensionType bridge$getType() {
|
||||
return getType();
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
"block.KelpTopBlockMixin_1_15",
|
||||
"block.LeavesBlockMixin_1_15",
|
||||
"block.LeverBlockMixin_1_15",
|
||||
"block.LilyPadBlockMixin_1_15",
|
||||
"block.MushroomBlockMixin_1_15",
|
||||
"block.NetherPortalBlockMixin_1_15",
|
||||
"block.NetherWartBlockMixin_1_15",
|
||||
@ -49,10 +50,20 @@
|
||||
"command.impl.TimeCommandMixin",
|
||||
"enchantment.FrostWalkerEnchantmentMixin_1_15",
|
||||
"entity.EntityMixin_1_15",
|
||||
"entity.LivingEntityMixin_1_15",
|
||||
"entity.boss.WitherEntityMixin_1_15",
|
||||
"entity.item.ArmorStandEntityMixin_1_15",
|
||||
"entity.item.ItemEntityMixin_1_15",
|
||||
"entity.monster.AbstractRaiderEntityMixin",
|
||||
"entity.monster.RavagerEntityMixin_1_15",
|
||||
"entity.monster.ShulkerEntityMixin_1_15",
|
||||
"entity.passive.BeeEntity_AngerGoalMixin",
|
||||
"entity.passive.BeeEntity_FindPollinationTargetGoalMixin",
|
||||
"entity.passive.BeeEntityMixin",
|
||||
"entity.player.PlayerEntityMixin_1_15",
|
||||
"entity.player.ServerPlayerEntityMixin_1_15",
|
||||
"item.crafting.SpecialRecipeMixin",
|
||||
"world.ExplosionMixin_1_15",
|
||||
"world.biome.BiomeContainerMixin",
|
||||
"world.chunk.ChunkMixin_1_15",
|
||||
"world.dimension.DimensionTypeMixin_1_15",
|
||||
|
||||
@ -48,7 +48,6 @@
|
||||
"block.IceBlockMixin",
|
||||
"block.JukeBoxBlockMixin",
|
||||
"block.LecternBlockMixin",
|
||||
"block.LilyPadBlockMixin",
|
||||
"block.MagmaBlockMixin",
|
||||
"block.NetherPortalBlock_SizeMixin",
|
||||
"block.NetherPortalBlockMixin",
|
||||
@ -79,9 +78,7 @@
|
||||
"command.arguments.EntitySelectorParserMixin",
|
||||
"command.impl.EffectCommandMixin",
|
||||
"command.impl.SummonCommandMixin",
|
||||
"command.impl.TeleportCommandMixin",
|
||||
"enchantment.DamageEnchantmentMixin",
|
||||
"enchantment.FrostWalkerEnchantmentMixin",
|
||||
"entity.AgeableEntityMixin",
|
||||
"entity.AreaEffectCloudEntityMixin",
|
||||
"entity.CreatureEntityMixin",
|
||||
@ -109,7 +106,6 @@
|
||||
"entity.ai.goal.TargetGoalMixin",
|
||||
"entity.ai.goal.TemptGoalMixin",
|
||||
"entity.ai.goal.TriggerSkeletonTrapGoalMixin",
|
||||
"entity.boss.WitherEntityMixin",
|
||||
"entity.boss.dragon.EnderDragonEntityMixin",
|
||||
"entity.boss.dragon.phase.PhaseManagerMixin",
|
||||
"entity.effect.LightningBoltEntityMixin",
|
||||
@ -147,9 +143,6 @@
|
||||
"entity.monster.IllusionerEntity_BlindnessSpellGoalMixin",
|
||||
"entity.monster.IllusionerEntity_MirrorSpellGoalMixin",
|
||||
"entity.monster.PhantomEntity_AttackPlayerGoalMixin",
|
||||
"entity.monster.PillagerEntityMixin",
|
||||
"entity.monster.RavagerEntityMixin",
|
||||
"entity.monster.ShulkerEntityMixin",
|
||||
"entity.monster.SilverfishEntity_HideInStoneGoalMixin",
|
||||
"entity.monster.SilverfishEntity_SummonSilverfishGoalMixin",
|
||||
"entity.monster.SlimeEntityMixin",
|
||||
@ -175,7 +168,6 @@
|
||||
"entity.passive.IronGolemEntityMixin",
|
||||
"entity.passive.MooshroomEntityMixin",
|
||||
"entity.passive.OcelotEntityMixin",
|
||||
"entity.passive.PandaEntity_MateGoalMixin",
|
||||
"entity.passive.PandaEntity_RevengeGoalMixin",
|
||||
"entity.passive.PandaEntityMixin",
|
||||
"entity.passive.ParrotEntityMixin",
|
||||
@ -206,6 +198,7 @@
|
||||
"entity.projectile.FishingBobberEntityMixin",
|
||||
"entity.projectile.LlamaSpitEntityMixin",
|
||||
"entity.projectile.PotionEntityMixin",
|
||||
"entity.projectile.ProjectileItemEntityMixin",
|
||||
"entity.projectile.ShulkerBulletEntityMixin",
|
||||
"entity.projectile.SmallFireballEntityMixin",
|
||||
"entity.projectile.SpectralArrowEntityMixin",
|
||||
@ -344,9 +337,9 @@
|
||||
"world.TrackedEntityMixin",
|
||||
"world.WorldMixin",
|
||||
"world.chunk.ChunkMixin",
|
||||
"world.chunk.storage.ChunkLoaderMixin",
|
||||
"world.chunk.storage.RegionFileCacheMixin",
|
||||
"world.dimension.DimensionMixin",
|
||||
"world.dimension.DimensionTypeMixin",
|
||||
"world.gen.WorldGenRegionMixin",
|
||||
"world.gen.feature.structure.SwampHutPieceMixin",
|
||||
"world.raid.RaidManagerMixin",
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package io.izzel.arclight.common.mixin.core.block;
|
||||
package io.izzel.arclight.impl.mixin.v1_14.block;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
@ -13,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(LilyPadBlock.class)
|
||||
public class LilyPadBlockMixin {
|
||||
public class LilyPadBlockMixin_1_14 {
|
||||
|
||||
@Inject(method = "onEntityCollision", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;destroyBlock(Lnet/minecraft/util/math/BlockPos;Z)Z"))
|
||||
public void arclight$entityChangeBlock(BlockState state, World worldIn, BlockPos pos, Entity entityIn, CallbackInfo ci) {
|
||||
@ -8,6 +8,7 @@ import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.MobEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.network.datasync.EntityDataManager;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@ -21,14 +22,16 @@ import net.minecraftforge.common.ForgeHooks;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v.CraftWorld;
|
||||
import org.bukkit.event.entity.EntityPortalEvent;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Random;
|
||||
|
||||
@Mixin(Entity.class)
|
||||
public abstract class EntityMixin_1_14 {
|
||||
public abstract class EntityMixin_1_14 implements EntityBridge {
|
||||
|
||||
// @formatter:off
|
||||
@Shadow public World world;
|
||||
@ -45,6 +48,12 @@ public abstract class EntityMixin_1_14 {
|
||||
@Shadow public abstract void detach();
|
||||
@Shadow public abstract EntityType<?> getType();
|
||||
@Shadow public abstract void remove(boolean keepData);
|
||||
@Shadow @Final protected EntityDataManager dataManager;
|
||||
@Shadow public abstract boolean isInvisible();
|
||||
@Shadow @Final protected Random rand;
|
||||
@Shadow public abstract float getWidth();
|
||||
@Shadow public abstract float getHeight();
|
||||
@Shadow public abstract float getEyeHeight();
|
||||
// @formatter:on
|
||||
|
||||
/**
|
||||
@ -143,4 +152,9 @@ public abstract class EntityMixin_1_14 {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double bridge$getEyeHeight() {
|
||||
return this.posY + (double) this.getEyeHeight();
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,278 @@
|
||||
package io.izzel.arclight.impl.mixin.v1_14.entity;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import io.izzel.arclight.common.bridge.entity.LivingEntityBridge;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.boss.WitherEntity;
|
||||
import net.minecraft.entity.item.ExperienceOrbEntity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.network.datasync.DataParameter;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.potion.Effect;
|
||||
import net.minecraft.potion.EffectInstance;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.GameRules;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.living.PotionEvent;
|
||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||
import org.bukkit.event.entity.EntityPotionEffectEvent;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
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.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(LivingEntity.class)
|
||||
public abstract class LivingEntityMixin_1_14 extends EntityMixin_1_14 implements LivingEntityBridge {
|
||||
|
||||
// @formatter:off
|
||||
@Shadow @Final private static DataParameter<Integer> POTION_EFFECTS;
|
||||
@Shadow @Final private static DataParameter<Boolean> HIDE_PARTICLES;
|
||||
@Shadow @Final public Map<Effect, EffectInstance> activePotionsMap;
|
||||
@Shadow public boolean potionsNeedUpdate;
|
||||
@Shadow protected abstract void onFinishedPotionEffect(EffectInstance effect);
|
||||
@Shadow protected abstract void onChangedPotionEffect(EffectInstance id, boolean reapply);
|
||||
@Shadow protected abstract void updatePotionMetadata();
|
||||
@Shadow public abstract boolean removePotionEffect(Effect effectIn);
|
||||
@Shadow public abstract boolean isPotionApplicable(EffectInstance potioneffectIn);
|
||||
@Shadow protected abstract void onNewPotionEffect(EffectInstance id);
|
||||
@Shadow @Nullable public abstract EffectInstance removeActivePotionEffect(@Nullable Effect potioneffectin);
|
||||
@Shadow public int deathTime;
|
||||
@Shadow protected abstract boolean isPlayer();
|
||||
@Shadow protected int recentlyHit;
|
||||
@Shadow protected abstract boolean canDropLoot();
|
||||
// @formatter:on
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
*/
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Overwrite
|
||||
protected void onDeathUpdate() {
|
||||
++this.deathTime;
|
||||
if (this.deathTime >= 20 && !this.removed) {
|
||||
|
||||
if (!this.world.isRemote && (this.isPlayer() || this.recentlyHit > 0 && this.canDropLoot() && this.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT))) {
|
||||
int i = this.bridge$getExpToDrop();
|
||||
while (i > 0) {
|
||||
int j = ExperienceOrbEntity.getXPSplit(i);
|
||||
i -= j;
|
||||
this.world.addEntity(new ExperienceOrbEntity(this.world, this.posX, this.posY, this.posZ, j));
|
||||
}
|
||||
this.bridge$setExpToDrop(0);
|
||||
}
|
||||
|
||||
this.remove((Object) this instanceof ServerPlayerEntity); //Forge keep data until we revive player
|
||||
|
||||
for (int k = 0; k < 20; ++k) {
|
||||
double d2 = this.rand.nextGaussian() * 0.02D;
|
||||
double d0 = this.rand.nextGaussian() * 0.02D;
|
||||
double d1 = this.rand.nextGaussian() * 0.02D;
|
||||
this.world.addParticle(ParticleTypes.POOF, this.posX + (double) (this.rand.nextFloat() * this.getWidth() * 2.0F) - (double) this.getWidth(), this.posY + (double) (this.rand.nextFloat() * this.getHeight()), this.posZ + (double) (this.rand.nextFloat() * this.getWidth() * 2.0F) - (double) this.getWidth(), d2, d0, d1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isTickingEffects = false;
|
||||
private List<Map.Entry<Either<EffectInstance, Effect>, EntityPotionEffectEvent.Cause>> effectsToProcess = Lists.newArrayList();
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
*/
|
||||
@Overwrite
|
||||
protected void updatePotionEffects() {
|
||||
this.isTickingEffects = true;
|
||||
Iterator<Effect> iterator = this.activePotionsMap.keySet().iterator();
|
||||
|
||||
try {
|
||||
while (iterator.hasNext()) {
|
||||
Effect effect = iterator.next();
|
||||
EffectInstance effectinstance = this.activePotionsMap.get(effect);
|
||||
if (!effectinstance.tick((LivingEntity) (Object) this)) {
|
||||
if (!this.world.isRemote && !MinecraftForge.EVENT_BUS.post(new PotionEvent.PotionExpiryEvent((LivingEntity) (Object) this, effectinstance))) {
|
||||
|
||||
EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent((LivingEntity) (Object) this, effectinstance, null, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.EXPIRATION);
|
||||
if (event.isCancelled()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
iterator.remove();
|
||||
this.onFinishedPotionEffect(effectinstance);
|
||||
}
|
||||
} else if (effectinstance.getDuration() % 600 == 0) {
|
||||
this.onChangedPotionEffect(effectinstance, false);
|
||||
}
|
||||
}
|
||||
} catch (ConcurrentModificationException ignored) {
|
||||
}
|
||||
|
||||
isTickingEffects = false;
|
||||
for (Map.Entry<Either<EffectInstance, Effect>, EntityPotionEffectEvent.Cause> e : effectsToProcess) {
|
||||
Either<EffectInstance, Effect> either = e.getKey();
|
||||
EntityPotionEffectEvent.Cause cause = e.getValue();
|
||||
bridge$pushEffectCause(cause);
|
||||
if (either.left().isPresent()) {
|
||||
addPotionEffect(either.left().get());
|
||||
} else {
|
||||
removePotionEffect(either.right().get());
|
||||
}
|
||||
}
|
||||
effectsToProcess.clear();
|
||||
|
||||
if (this.potionsNeedUpdate) {
|
||||
if (!this.world.isRemote) {
|
||||
this.updatePotionMetadata();
|
||||
}
|
||||
|
||||
this.potionsNeedUpdate = false;
|
||||
}
|
||||
|
||||
int i = this.dataManager.get(POTION_EFFECTS);
|
||||
boolean flag1 = this.dataManager.get(HIDE_PARTICLES);
|
||||
if (i > 0) {
|
||||
boolean flag;
|
||||
if (this.isInvisible()) {
|
||||
flag = this.rand.nextInt(15) == 0;
|
||||
} else {
|
||||
flag = this.rand.nextBoolean();
|
||||
}
|
||||
|
||||
if (flag1) {
|
||||
flag &= this.rand.nextInt(5) == 0;
|
||||
}
|
||||
|
||||
if (flag && i > 0) {
|
||||
double d0 = (double) (i >> 16 & 255) / 255.0D;
|
||||
double d1 = (double) (i >> 8 & 255) / 255.0D;
|
||||
double d2 = (double) (i >> 0 & 255) / 255.0D;
|
||||
this.world.addParticle(flag1 ? ParticleTypes.AMBIENT_ENTITY_EFFECT : ParticleTypes.ENTITY_EFFECT, this.posX + (this.rand.nextDouble() - 0.5D) * (double) this.getWidth(), this.posY + this.rand.nextDouble() * (double) this.getHeight(), this.posZ + (this.rand.nextDouble() - 0.5D) * (double) this.getWidth(), d0, d1, d2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
*/
|
||||
@Overwrite
|
||||
public boolean addPotionEffect(EffectInstance effectInstanceIn) {
|
||||
EntityPotionEffectEvent.Cause cause = bridge$getEffectCause().orElse(EntityPotionEffectEvent.Cause.UNKNOWN);
|
||||
if (isTickingEffects) {
|
||||
effectsToProcess.add(Maps.immutableEntry(Either.left(effectInstanceIn), cause));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!this.isPotionApplicable(effectInstanceIn)) {
|
||||
return false;
|
||||
} else {
|
||||
EffectInstance effectinstance = this.activePotionsMap.get(effectInstanceIn.getPotion());
|
||||
|
||||
boolean override = false;
|
||||
if (effectinstance != null) {
|
||||
override = new EffectInstance(effectinstance).combine(effectInstanceIn);
|
||||
}
|
||||
|
||||
EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent((LivingEntity) (Object) this, effectinstance, effectInstanceIn, cause, override);
|
||||
if (event.isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MinecraftForge.EVENT_BUS.post(new PotionEvent.PotionAddedEvent((LivingEntity) (Object) this, effectinstance, effectInstanceIn));
|
||||
if (effectinstance == null) {
|
||||
this.activePotionsMap.put(effectInstanceIn.getPotion(), effectInstanceIn);
|
||||
this.onNewPotionEffect(effectInstanceIn);
|
||||
return true;
|
||||
} else if (event.isOverride()) {
|
||||
effectinstance.combine(effectInstanceIn);
|
||||
this.onChangedPotionEffect(effectinstance, true);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused") // mock
|
||||
public EffectInstance c(@Nullable Effect potioneffectin, EntityPotionEffectEvent.Cause cause) {
|
||||
bridge$pushEffectCause(cause);
|
||||
return removeActivePotionEffect(potioneffectin);
|
||||
}
|
||||
|
||||
@Inject(method = "removeActivePotionEffect", at = @At("HEAD"))
|
||||
public void arclight$clearActive(Effect effect, CallbackInfoReturnable<EffectInstance> cir) {
|
||||
EntityPotionEffectEvent.Cause cause = bridge$getEffectCause().orElse(EntityPotionEffectEvent.Cause.UNKNOWN);
|
||||
if (isTickingEffects) {
|
||||
effectsToProcess.add(Maps.immutableEntry(Either.right(effect), cause));
|
||||
cir.setReturnValue(null);
|
||||
return;
|
||||
}
|
||||
|
||||
EffectInstance effectInstance = this.activePotionsMap.get(effect);
|
||||
if (effectInstance == null) {
|
||||
cir.setReturnValue(null);
|
||||
return;
|
||||
}
|
||||
|
||||
EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent((LivingEntity) (Object) this, effectInstance, null, cause);
|
||||
if (event.isCancelled()) {
|
||||
cir.setReturnValue(null);
|
||||
}
|
||||
}
|
||||
|
||||
private transient boolean arclight$fallSuccess;
|
||||
|
||||
@Inject(method = "fall", 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, CallbackInfo ci) {
|
||||
if (!arclight$fallSuccess) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(method = "fall", 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bridge$dropExperience() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bridge$createWitherRose(LivingEntity entity) {
|
||||
if (!this.world.isRemote && entity instanceof WitherEntity) {
|
||||
boolean flag3 = false;
|
||||
if (net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, (ServerPlayerEntity) (Object) this)) {
|
||||
BlockPos blockposition = new BlockPos(this.posX, this.posY, this.posZ);
|
||||
BlockState iblockdata = Blocks.WITHER_ROSE.getDefaultState();
|
||||
if (this.world.getBlockState(blockposition).isAir() && iblockdata.isValidPosition(this.world, blockposition)) {
|
||||
this.world.setBlockState(blockposition, iblockdata, 3);
|
||||
flag3 = true;
|
||||
}
|
||||
}
|
||||
if (!flag3) {
|
||||
ItemEntity entityitem = new ItemEntity(this.world, this.posX, this.posY, this.posZ, new ItemStack(Items.WITHER_ROSE));
|
||||
this.world.addEntity(entityitem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package io.izzel.arclight.common.mixin.core.entity.boss;
|
||||
package io.izzel.arclight.impl.mixin.v1_14.entity.boss;
|
||||
|
||||
import io.izzel.arclight.common.mixin.core.entity.CreatureEntityMixin;
|
||||
import net.minecraft.block.BlockState;
|
||||
@ -27,7 +27,7 @@ import org.spongepowered.asm.mixin.Shadow;
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(WitherEntity.class)
|
||||
public abstract class WitherEntityMixin extends CreatureEntityMixin {
|
||||
public abstract class WitherEntityMixin_1_14 extends CreatureEntityMixin {
|
||||
|
||||
// @formatter:off
|
||||
@Shadow public abstract int getInvulTime();
|
||||
@ -0,0 +1,18 @@
|
||||
package io.izzel.arclight.impl.mixin.v1_14.entity.item;
|
||||
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(ItemEntity.class)
|
||||
public class ItemEntityMixin_1_14 {
|
||||
|
||||
@Redirect(method = "func_213858_a", at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/entity/item/ItemEntity;setItem(Lnet/minecraft/item/ItemStack;)V"))
|
||||
private static void arclight$setNonEmpty(ItemEntity itemEntity, ItemStack stack) {
|
||||
if (!stack.isEmpty()) {
|
||||
itemEntity.setItem(stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package io.izzel.arclight.common.mixin.core.entity.monster;
|
||||
package io.izzel.arclight.impl.mixin.v1_14.entity.monster;
|
||||
|
||||
import io.izzel.arclight.common.mixin.core.entity.CreatureEntityMixin;
|
||||
import net.minecraft.entity.monster.PillagerEntity;
|
||||
@ -10,7 +10,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(PillagerEntity.class)
|
||||
public abstract class PillagerEntityMixin extends CreatureEntityMixin {
|
||||
public abstract class PillagerEntityMixin_1_14 extends CreatureEntityMixin {
|
||||
|
||||
// @formatter:off
|
||||
@Shadow public abstract Inventory getInventory();
|
||||
@ -1,4 +1,4 @@
|
||||
package io.izzel.arclight.common.mixin.core.entity.monster;
|
||||
package io.izzel.arclight.impl.mixin.v1_14.entity.monster;
|
||||
|
||||
import io.izzel.arclight.common.mixin.core.entity.CreatureEntityMixin;
|
||||
import net.minecraft.block.Blocks;
|
||||
@ -11,7 +11,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(RavagerEntity.class)
|
||||
public abstract class RavagerEntityMixin extends CreatureEntityMixin {
|
||||
public abstract class RavagerEntityMixin_1_14 extends CreatureEntityMixin {
|
||||
|
||||
@Redirect(method = "livingTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;destroyBlock(Lnet/minecraft/util/math/BlockPos;Z)Z"))
|
||||
private boolean arclight$entityChangeBlock(World world, BlockPos pos, boolean dropBlock) {
|
||||
@ -1,4 +1,4 @@
|
||||
package io.izzel.arclight.common.mixin.core.entity.monster;
|
||||
package io.izzel.arclight.impl.mixin.v1_14.entity.monster;
|
||||
|
||||
import io.izzel.arclight.common.mixin.core.entity.CreatureEntityMixin;
|
||||
import net.minecraft.entity.monster.ShulkerEntity;
|
||||
@ -10,7 +10,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(ShulkerEntity.class)
|
||||
public abstract class ShulkerEntityMixin extends CreatureEntityMixin {
|
||||
public abstract class ShulkerEntityMixin_1_14 extends CreatureEntityMixin {
|
||||
|
||||
@Inject(method = "notifyDataManagerChange", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/monster/ShulkerEntity;prevPosX:D"))
|
||||
private void arclight$chunkCheck(DataParameter<?> key, CallbackInfo ci) {
|
||||
@ -0,0 +1,56 @@
|
||||
package io.izzel.arclight.impl.mixin.v1_14.entity.monster;
|
||||
|
||||
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
||||
import io.izzel.arclight.common.mixin.core.entity.monster.ZombieEntityMixin;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.monster.ZombiePigmanEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.PigZombie;
|
||||
import org.bukkit.event.entity.PigZombieAngerEvent;
|
||||
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.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(ZombiePigmanEntity.class)
|
||||
public abstract class ZombiePigmanEntityMixin_1_14 extends ZombieEntityMixin {
|
||||
|
||||
// @formatter:off
|
||||
@Shadow protected abstract boolean becomeAngryAt(Entity p_70835_1_);
|
||||
@Shadow protected abstract int func_223336_ef();
|
||||
// @formatter:on
|
||||
|
||||
public boolean attackEntityFrom(DamageSource damagesource, float f) {
|
||||
if (this.isInvulnerableTo(damagesource)) {
|
||||
return false;
|
||||
}
|
||||
Entity entity = damagesource.getTrueSource();
|
||||
boolean result = super.attackEntityFrom(damagesource, f);
|
||||
if (result && entity instanceof PlayerEntity && !((PlayerEntity) entity).isCreative() && this.canEntityBeSeen(entity)) {
|
||||
this.becomeAngryAt(entity);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Inject(method = "becomeAngryAt", cancellable = true, at = @At("HEAD"))
|
||||
private void arclight$anger(Entity entity, CallbackInfoReturnable<Boolean> cir) {
|
||||
PigZombieAngerEvent event = new PigZombieAngerEvent((PigZombie) this.getBukkitEntity(), (entity == null) ? null : ((EntityBridge) entity).bridge$getBukkitEntity(), this.func_223336_ef());
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
cir.setReturnValue(false);
|
||||
} else {
|
||||
arclight$capture = event.getNewAnger();
|
||||
}
|
||||
}
|
||||
|
||||
private transient int arclight$capture;
|
||||
|
||||
@Redirect(method = "becomeAngryAt", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/monster/ZombiePigmanEntity;func_223336_ef()I"))
|
||||
private int arclight$useAnger(ZombiePigmanEntity pigmanEntity) {
|
||||
return arclight$capture;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package io.izzel.arclight.impl.mixin.v1_14.entity.passive;
|
||||
|
||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||
import io.izzel.arclight.impl.mixin.v1_14.entity.EntityMixin_1_14;
|
||||
import net.minecraft.entity.passive.OcelotEntity;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(OcelotEntity.class)
|
||||
public abstract class OcelotEntityMixin_1_14 extends EntityMixin_1_14 {
|
||||
|
||||
@Inject(method = "func_213525_dW", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;addEntity(Lnet/minecraft/entity/Entity;)Z"))
|
||||
private void arclight$spawnBaby(CallbackInfo ci) {
|
||||
((WorldBridge) this.world).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.OCELOT_BABY);
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package io.izzel.arclight.common.mixin.core.entity.passive;
|
||||
package io.izzel.arclight.impl.mixin.v1_14.entity.passive;
|
||||
|
||||
import io.izzel.arclight.common.bridge.entity.MobEntityBridge;
|
||||
import net.minecraft.entity.passive.PandaEntity;
|
||||
@ -0,0 +1,138 @@
|
||||
package io.izzel.arclight.impl.mixin.v1_14.entity.player;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import io.izzel.arclight.common.bridge.entity.InternalEntityBridge;
|
||||
import io.izzel.arclight.common.bridge.entity.player.PlayerEntityBridge;
|
||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||
import io.izzel.arclight.common.mixin.core.entity.LivingEntityMixin;
|
||||
import net.minecraft.entity.player.PlayerAbilities;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v.block.CraftBlock;
|
||||
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerBedLeaveEvent;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
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.ModifyVariable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Mixin(PlayerEntity.class)
|
||||
public abstract class PlayerEntityMixin_1_14 extends LivingEntityMixin implements PlayerEntityBridge {
|
||||
|
||||
// @formatter:off
|
||||
@Shadow public abstract Either<PlayerEntity.SleepResult, Unit> trySleep(BlockPos at);
|
||||
@Shadow public abstract void startSleeping(BlockPos p_213342_1_);
|
||||
@Shadow public int sleepTimer;
|
||||
@Shadow public abstract void addStat(ResourceLocation stat);
|
||||
@Shadow @Final public PlayerAbilities abilities;
|
||||
// @formatter:on
|
||||
|
||||
@Override
|
||||
public CraftHumanEntity bridge$getBukkitEntity() {
|
||||
return (CraftHumanEntity) ((InternalEntityBridge) this).internal$getBukkitEntity();
|
||||
}
|
||||
|
||||
private boolean arclight$forceSleep = false;
|
||||
private Object arclight$processSleep = null;
|
||||
|
||||
private Either<PlayerEntity.SleepResult, Unit> getBedResult(BlockPos at, Direction direction) {
|
||||
arclight$processSleep = true;
|
||||
Either<PlayerEntity.SleepResult, Unit> either = this.trySleep(at);
|
||||
arclight$processSleep = null;
|
||||
return either;
|
||||
}
|
||||
|
||||
public Either<PlayerEntity.SleepResult, Unit> sleep(BlockPos at, boolean force) {
|
||||
arclight$forceSleep = force;
|
||||
try {
|
||||
return this.trySleep(at);
|
||||
} finally {
|
||||
arclight$forceSleep = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "trySleep", cancellable = true, at = @At(value = "HEAD"))
|
||||
public void arclight$onSleep(BlockPos at, CallbackInfoReturnable<Either<PlayerEntity.SleepResult, Unit>> cir) {
|
||||
if (arclight$processSleep == null) {
|
||||
Either<PlayerEntity.SleepResult, Unit> result = getBedResult(at, null);
|
||||
|
||||
if (result.left().orElse(null) == PlayerEntity.SleepResult.OTHER_PROBLEM) {
|
||||
cir.setReturnValue(result);
|
||||
return;
|
||||
}
|
||||
if (arclight$forceSleep) {
|
||||
result = Either.right(Unit.INSTANCE);
|
||||
}
|
||||
if (this.bridge$getBukkitEntity() instanceof Player) {
|
||||
result = CraftEventFactory.callPlayerBedEnterEvent((PlayerEntity) (Object) this, at, result);
|
||||
if (result.left().isPresent()) {
|
||||
cir.setReturnValue(result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.startSleeping(at);
|
||||
this.sleepTimer = 0;
|
||||
if (this.world instanceof ServerWorld) {
|
||||
((ServerWorld) this.world).updateAllPlayersSleepingFlag();
|
||||
}
|
||||
cir.setReturnValue(Either.right(Unit.INSTANCE));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "trySleep", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;startSleeping(Lnet/minecraft/util/math/BlockPos;)V"))
|
||||
public void arclight$preSleep(BlockPos at, CallbackInfoReturnable<Either<PlayerEntity.SleepResult, Unit>> cir) {
|
||||
if (arclight$processSleep != null) {
|
||||
cir.setReturnValue(Either.right(Unit.INSTANCE));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "wakeUpPlayer", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "FIELD", target = "Lnet/minecraft/entity/player/PlayerEntity;sleepTimer:I"))
|
||||
private void arclight$wakeup(boolean immediately, boolean updateWorldFlag, boolean setSpawn, CallbackInfo ci, Optional<BlockPos> optional) {
|
||||
if (this.getBukkitEntity() instanceof Player) {
|
||||
Player player = (Player) this.getBukkitEntity();
|
||||
BlockPos blockposition2 = optional.orElse(null);
|
||||
Block bed;
|
||||
if (blockposition2 != null) {
|
||||
bed = CraftBlock.at(this.world, blockposition2);
|
||||
} else {
|
||||
bed = ((WorldBridge) this.world).bridge$getWorld().getBlockAt(player.getLocation());
|
||||
}
|
||||
PlayerBedLeaveEvent event = new PlayerBedLeaveEvent(player, bed, setSpawn);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
arclight$setSpawn = event.shouldSetSpawnLocation();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean arclight$setSpawn;
|
||||
|
||||
@ModifyVariable(method = "wakeUpPlayer", index = 3, name = "setSpawn", at = @At(value = "FIELD", shift = At.Shift.AFTER, target = "Lnet/minecraft/entity/player/PlayerEntity;sleepTimer:I"))
|
||||
private boolean arclight$modifySpawn(boolean setSpawn) {
|
||||
return arclight$setSpawn;
|
||||
}
|
||||
|
||||
@Inject(method = "setSpawnPoint(Lnet/minecraft/util/math/BlockPos;Z)V", at = @At("RETURN"))
|
||||
private void arclight$updateSpawnpoint(BlockPos pos, boolean forced, CallbackInfo ci) {
|
||||
bridge$setSpawnWorld(pos == null ? "" : this.world.worldInfo.getWorldName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Either<PlayerEntity.SleepResult, Unit> bridge$trySleep(BlockPos at, boolean force) {
|
||||
return sleep(at, force);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,264 @@
|
||||
package io.izzel.arclight.impl.mixin.v1_14.entity.player;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import io.izzel.arclight.common.bridge.entity.InternalEntityBridge;
|
||||
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||
import io.izzel.arclight.common.bridge.world.dimension.DimensionTypeBridge;
|
||||
import net.minecraft.advancements.CriteriaTriggers;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.network.play.ServerPlayNetHandler;
|
||||
import net.minecraft.network.play.server.SChangeGameStatePacket;
|
||||
import net.minecraft.network.play.server.SPlayEntityEffectPacket;
|
||||
import net.minecraft.network.play.server.SPlaySoundEventPacket;
|
||||
import net.minecraft.network.play.server.SPlayerAbilitiesPacket;
|
||||
import net.minecraft.network.play.server.SRespawnPacket;
|
||||
import net.minecraft.network.play.server.SServerDifficultyPacket;
|
||||
import net.minecraft.potion.EffectInstance;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.management.PlayerInteractionManager;
|
||||
import net.minecraft.server.management.PlayerList;
|
||||
import net.minecraft.stats.Stats;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraft.world.storage.WorldInfo;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||
import org.bukkit.craftbukkit.v.util.BlockStateListPopulator;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
import org.bukkit.event.player.PlayerPortalEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.event.world.PortalCreateEvent;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
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 javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(ServerPlayerEntity.class)
|
||||
public abstract class ServerPlayerEntityMixin_1_14 extends PlayerEntityMixin_1_14 implements ServerPlayerEntityBridge {
|
||||
|
||||
// @formatter:off
|
||||
@Shadow public boolean invulnerableDimensionChange;
|
||||
@Shadow public abstract ServerWorld func_71121_q();
|
||||
@Shadow public boolean queuedEndExit;
|
||||
@Shadow public ServerPlayNetHandler connection;
|
||||
@Shadow private boolean seenCredits;
|
||||
@Shadow @Final public MinecraftServer server;
|
||||
@Shadow @Final public PlayerInteractionManager interactionManager;
|
||||
@Shadow @Nullable private Vec3d enteredNetherPosition;
|
||||
@Shadow public abstract void func_213846_b(ServerWorld p_213846_1_);
|
||||
@Shadow public int lastExperience;
|
||||
@Shadow private float lastHealth;
|
||||
@Shadow private int lastFoodLevel;
|
||||
// @formatter:on
|
||||
|
||||
@Override
|
||||
public CraftPlayer bridge$getBukkitEntity() {
|
||||
return (CraftPlayer) ((InternalEntityBridge) this).internal$getBukkitEntity();
|
||||
}
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
*/
|
||||
@Nullable
|
||||
@Overwrite
|
||||
public Entity changeDimension(DimensionType dimensionmanager) {
|
||||
PlayerTeleportEvent.TeleportCause cause = bridge$getTeleportCause().orElse(PlayerTeleportEvent.TeleportCause.UNKNOWN);
|
||||
if (!net.minecraftforge.common.ForgeHooks.onTravelToDimension((ServerPlayerEntity) (Object) this, dimensionmanager))
|
||||
return null;
|
||||
if (this.isSleeping()) {
|
||||
return (ServerPlayerEntity) (Object) this;
|
||||
}
|
||||
DimensionType dimensionmanager2 = this.dimension;
|
||||
if (((DimensionTypeBridge) dimensionmanager2).bridge$getType() == DimensionType.THE_END && ((DimensionTypeBridge) dimensionmanager).bridge$getType() == DimensionType.OVERWORLD) {
|
||||
this.invulnerableDimensionChange = true;
|
||||
this.detach();
|
||||
this.func_71121_q().removePlayer((ServerPlayerEntity) (Object) this, true);
|
||||
if (!this.queuedEndExit) {
|
||||
this.queuedEndExit = true;
|
||||
this.connection.sendPacket(new SChangeGameStatePacket(4, this.seenCredits ? 0.0f : 1.0f));
|
||||
this.seenCredits = true;
|
||||
}
|
||||
return (ServerPlayerEntity) (Object) this;
|
||||
}
|
||||
ServerWorld worldserver = this.server.func_71218_a(dimensionmanager2);
|
||||
ServerWorld worldserver2 = this.server.func_71218_a(dimensionmanager);
|
||||
WorldInfo worlddata = this.world.getWorldInfo();
|
||||
double d0 = this.posX;
|
||||
double d2 = this.posY;
|
||||
double d3 = this.posZ;
|
||||
float f = this.rotationPitch;
|
||||
float f2 = this.rotationYaw;
|
||||
double d4 = 8.0;
|
||||
float f3 = f2;
|
||||
worldserver.getProfiler().startSection("moving");
|
||||
if (worldserver2 != null) {
|
||||
if (dimensionmanager2 == DimensionType.OVERWORLD && dimensionmanager == DimensionType.THE_NETHER) {
|
||||
this.enteredNetherPosition = new Vec3d(this.posX, this.posY, this.posZ);
|
||||
d0 /= 8.0;
|
||||
d3 /= 8.0;
|
||||
} else if (dimensionmanager2 == DimensionType.THE_NETHER && dimensionmanager == DimensionType.OVERWORLD) {
|
||||
d0 *= 8.0;
|
||||
d3 *= 8.0;
|
||||
} else if (dimensionmanager2 == DimensionType.OVERWORLD && dimensionmanager == DimensionType.THE_END) {
|
||||
BlockPos blockposition = worldserver2.getSpawnCoordinate();
|
||||
d0 = blockposition.getX();
|
||||
d2 = blockposition.getY();
|
||||
d3 = blockposition.getZ();
|
||||
f2 = 90.0f;
|
||||
f = 0.0f;
|
||||
}
|
||||
}
|
||||
Location enter = this.getBukkitEntity().getLocation();
|
||||
Location exit = (worldserver2 == null) ? null : new Location(((WorldBridge) worldserver2).bridge$getWorld(), d0, d2, d3, f2, f);
|
||||
PlayerPortalEvent event = new PlayerPortalEvent((Player) this.getBukkitEntity(), enter, exit, cause);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled() || event.getTo() == null) {
|
||||
return null;
|
||||
}
|
||||
exit = event.getTo();
|
||||
if (exit == null) {
|
||||
return null;
|
||||
}
|
||||
PlayerTeleportEvent tpEvent = new PlayerTeleportEvent((Player) this.getBukkitEntity(), enter, exit, cause);
|
||||
Bukkit.getServer().getPluginManager().callEvent(tpEvent);
|
||||
if (tpEvent.isCancelled() || tpEvent.getTo() == null) {
|
||||
return null;
|
||||
}
|
||||
exit = tpEvent.getTo();
|
||||
if (exit == null) {
|
||||
return null;
|
||||
}
|
||||
worldserver2 = ((CraftWorld) exit.getWorld()).getHandle();
|
||||
d0 = exit.getX();
|
||||
d2 = exit.getY();
|
||||
d3 = exit.getZ();
|
||||
f2 = exit.getYaw();
|
||||
f = exit.getPitch();
|
||||
this.invulnerableDimensionChange = true;
|
||||
dimensionmanager = worldserver2.getDimension().getType();
|
||||
this.dimension = dimensionmanager;
|
||||
net.minecraftforge.fml.network.NetworkHooks.sendDimensionDataPacket(this.connection.netManager, (ServerPlayerEntity) (Object) this);
|
||||
this.connection.sendPacket(new SRespawnPacket(worldserver2.dimension.getType(), this.world.getWorldInfo().getGenerator(), this.interactionManager.getGameType()));
|
||||
this.connection.sendPacket(new SServerDifficultyPacket(this.world.getDifficulty(), this.world.getWorldInfo().isDifficultyLocked()));
|
||||
PlayerList playerlist = this.server.getPlayerList();
|
||||
playerlist.updatePermissionLevel((ServerPlayerEntity) (Object) this);
|
||||
worldserver.removePlayer((ServerPlayerEntity) (Object) this, true);
|
||||
this.removed = false;
|
||||
this.setLocationAndAngles(d0, d2, d3, f2, f);
|
||||
worldserver.getProfiler().endSection();
|
||||
worldserver.getProfiler().startSection("placing");
|
||||
double d5 = Math.min(-2.9999872E7, worldserver2.getWorldBorder().minX() + 16.0);
|
||||
double d6 = Math.min(-2.9999872E7, worldserver2.getWorldBorder().minZ() + 16.0);
|
||||
double d7 = Math.min(2.9999872E7, worldserver2.getWorldBorder().maxX() - 16.0);
|
||||
double d8 = Math.min(2.9999872E7, worldserver2.getWorldBorder().maxZ() - 16.0);
|
||||
d0 = MathHelper.clamp(d0, d5, d7);
|
||||
d3 = MathHelper.clamp(d3, d6, d8);
|
||||
this.setLocationAndAngles(d0, d2, d3, f2, f);
|
||||
if (((DimensionTypeBridge) dimensionmanager).bridge$getType() == DimensionType.THE_END) {
|
||||
int i = MathHelper.floor(this.posX);
|
||||
int j = MathHelper.floor(this.posY) - 1;
|
||||
int k = MathHelper.floor(this.posZ);
|
||||
boolean flag = true;
|
||||
boolean flag2 = false;
|
||||
BlockStateListPopulator blockList = new BlockStateListPopulator(worldserver2);
|
||||
for (int l = -2; l <= 2; ++l) {
|
||||
for (int i2 = -2; i2 <= 2; ++i2) {
|
||||
for (int j2 = -1; j2 < 3; ++j2) {
|
||||
int k2 = i + i2 * 1 + l * 0;
|
||||
int l2 = j + j2;
|
||||
int i3 = k + i2 * 0 - l * 1;
|
||||
boolean flag3 = j2 < 0;
|
||||
blockList.setBlockState(new BlockPos(k2, l2, i3), flag3 ? Blocks.OBSIDIAN.getDefaultState() : Blocks.AIR.getDefaultState(), 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
org.bukkit.World bworld = ((WorldBridge) worldserver2).bridge$getWorld();
|
||||
PortalCreateEvent portalEvent = new PortalCreateEvent((List) blockList.getList(), bworld, this.getBukkitEntity(), PortalCreateEvent.CreateReason.END_PLATFORM);
|
||||
Bukkit.getPluginManager().callEvent(portalEvent);
|
||||
if (!portalEvent.isCancelled()) {
|
||||
blockList.updateList();
|
||||
}
|
||||
this.setLocationAndAngles(i, j, k, f2, 0.0f);
|
||||
this.setMotion(Vec3d.ZERO);
|
||||
} else if (!worldserver2.getDefaultTeleporter().placeInPortal((ServerPlayerEntity) (Object) this, f3)) {
|
||||
worldserver2.getDefaultTeleporter().makePortal((ServerPlayerEntity) (Object) this);
|
||||
worldserver2.getDefaultTeleporter().placeInPortal((ServerPlayerEntity) (Object) this, f3);
|
||||
}
|
||||
worldserver.getProfiler().endSection();
|
||||
this.setWorld(worldserver2);
|
||||
worldserver2.func_217447_b((ServerPlayerEntity) (Object) this);
|
||||
this.func_213846_b(worldserver);
|
||||
this.connection.setPlayerLocation(this.posX, this.posY, this.posZ, f2, f);
|
||||
this.interactionManager.func_73080_a(worldserver2);
|
||||
this.connection.sendPacket(new SPlayerAbilitiesPacket(this.abilities));
|
||||
playerlist.func_72354_b((ServerPlayerEntity) (Object) this, worldserver2);
|
||||
playerlist.sendInventory((ServerPlayerEntity) (Object) this);
|
||||
for (EffectInstance mobeffect : this.getActivePotionEffects()) {
|
||||
this.connection.sendPacket(new SPlayEntityEffectPacket(this.getEntityId(), mobeffect));
|
||||
}
|
||||
this.connection.sendPacket(new SPlaySoundEventPacket(1032, BlockPos.ZERO, 0, false));
|
||||
this.lastExperience = -1;
|
||||
this.lastHealth = -1.0f;
|
||||
this.lastFoodLevel = -1;
|
||||
PlayerChangedWorldEvent changeEvent = new PlayerChangedWorldEvent((Player) this.getBukkitEntity(), ((WorldBridge) worldserver).bridge$getWorld());
|
||||
Bukkit.getPluginManager().callEvent(changeEvent);
|
||||
net.minecraftforge.fml.hooks.BasicEventHooks.firePlayerChangedDimensionEvent((ServerPlayerEntity) (Object) this, dimensionmanager2, dimensionmanager);
|
||||
return (ServerPlayerEntity) (Object) this;
|
||||
}
|
||||
|
||||
public Entity a(DimensionType dimensionmanager, final PlayerTeleportEvent.TeleportCause cause) {
|
||||
bridge$pushChangeDimensionCause(cause);
|
||||
return this.changeDimension(dimensionmanager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Either<PlayerEntity.SleepResult, Unit> sleep(BlockPos at, boolean force) {
|
||||
return super.sleep(at, force).ifRight((p_213849_1_) -> {
|
||||
this.addStat(Stats.SLEEP_IN_BED);
|
||||
CriteriaTriggers.SLEPT_IN_BED.trigger((ServerPlayerEntity) (Object) this);
|
||||
});
|
||||
}
|
||||
|
||||
@Inject(method = "wakeUpPlayer", cancellable = true, at = @At("HEAD"))
|
||||
private void arclight$notWake(boolean immediately, boolean updateWorldFlag, boolean setSpawn, CallbackInfo ci) {
|
||||
if (!isSleeping()) ci.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity bridge$changeDimension(DimensionType dimensionType, PlayerTeleportEvent.TeleportCause cause) {
|
||||
return a(dimensionType, cause);
|
||||
}
|
||||
|
||||
@Inject(method = "setElytraFlying", cancellable = true, at = @At("HEAD"))
|
||||
private void arclight$beginGlide(CallbackInfo ci) {
|
||||
if (CraftEventFactory.callToggleGlideEvent((ServerPlayerEntity) (Object) this, true).isCancelled()) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "clearElytraFlying", cancellable = true, at = @At("HEAD"))
|
||||
private void arclight$endGlide(CallbackInfo ci) {
|
||||
if (CraftEventFactory.callToggleGlideEvent((ServerPlayerEntity) (Object) this, false).isCancelled()) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
package io.izzel.arclight.impl.mixin.v1_14.world;
|
||||
|
||||
import io.izzel.arclight.common.bridge.world.ExplosionBridge;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraft.world.storage.loot.LootContext;
|
||||
import net.minecraft.world.storage.loot.LootParameters;
|
||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||
import org.bukkit.event.block.BlockIgniteEvent;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
@Mixin(Explosion.class)
|
||||
public abstract class ExplosionMixin_1_14 implements ExplosionBridge {
|
||||
|
||||
// @formatter:off
|
||||
@Shadow @Final private World world;
|
||||
@Shadow @Final private Explosion.Mode mode;
|
||||
@Shadow @Mutable @Final private float size;
|
||||
@Shadow @Final private List<BlockPos> affectedBlockPositions;
|
||||
@Shadow @Final private double x;
|
||||
@Shadow @Final private double y;
|
||||
@Shadow @Final private double z;
|
||||
@Shadow @Final private boolean causesFire;
|
||||
@Shadow @Final private Random random;
|
||||
@Accessor("exploder") public abstract Entity bridge$getExploder();
|
||||
@Accessor("size") public abstract float bridge$getSize();
|
||||
@Accessor("size") public abstract void bridge$setSize(float size);
|
||||
@Accessor("mode") public abstract Explosion.Mode bridge$getMode();
|
||||
// @formatter:on
|
||||
|
||||
public boolean wasCanceled = false;
|
||||
|
||||
/**
|
||||
* @author IzzelAliz
|
||||
* @reason
|
||||
*/
|
||||
@Overwrite
|
||||
public void doExplosionB(boolean spawnParticles) {
|
||||
if (world.isRemote) {
|
||||
this.world.playSound(this.x, this.y, this.z, SoundEvents.ENTITY_GENERIC_EXPLODE, SoundCategory.BLOCKS, 4.0F, (1.0F + (this.world.rand.nextFloat() - this.world.rand.nextFloat()) * 0.2F) * 0.7F, false);
|
||||
}
|
||||
boolean flag = this.mode != Explosion.Mode.NONE;
|
||||
|
||||
if (spawnParticles) {
|
||||
if (!(this.size < 2.0F) && flag) {
|
||||
this.world.addParticle(ParticleTypes.EXPLOSION_EMITTER, this.x, this.y, this.z, 1.0D, 0.0D, 0.0D);
|
||||
} else {
|
||||
this.world.addParticle(ParticleTypes.EXPLOSION, this.x, this.y, this.z, 1.0D, 0.0D, 0.0D);
|
||||
}
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
|
||||
float yield = this.bridge$callBlockExplodeEvent();
|
||||
|
||||
if (Float.isNaN(yield)) {
|
||||
this.wasCanceled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
for (BlockPos blockpos : this.affectedBlockPositions) {
|
||||
BlockState blockstate = this.world.getBlockState(blockpos);
|
||||
Block block = blockstate.getBlock();
|
||||
if (spawnParticles) {
|
||||
double d0 = ((float) blockpos.getX() + this.world.rand.nextFloat());
|
||||
double d1 = ((float) blockpos.getY() + this.world.rand.nextFloat());
|
||||
double d2 = ((float) blockpos.getZ() + this.world.rand.nextFloat());
|
||||
double d3 = d0 - this.x;
|
||||
double d4 = d1 - this.y;
|
||||
double d5 = d2 - this.z;
|
||||
double d6 = MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5);
|
||||
d3 = d3 / d6;
|
||||
d4 = d4 / d6;
|
||||
d5 = d5 / d6;
|
||||
double d7 = 0.5D / (d6 / (double) this.size + 0.1D);
|
||||
d7 = d7 * (double) (this.world.rand.nextFloat() * this.world.rand.nextFloat() + 0.3F);
|
||||
d3 = d3 * d7;
|
||||
d4 = d4 * d7;
|
||||
d5 = d5 * d7;
|
||||
this.world.addParticle(ParticleTypes.POOF, (d0 + this.x) / 2.0D, (d1 + this.y) / 2.0D, (d2 + this.z) / 2.0D, d3, d4, d5);
|
||||
this.world.addParticle(ParticleTypes.SMOKE, d0, d1, d2, d3, d4, d5);
|
||||
}
|
||||
|
||||
if (!blockstate.isAir(this.world, blockpos)) {
|
||||
if (this.world instanceof ServerWorld && blockstate.canDropFromExplosion(this.world, blockpos, (Explosion) (Object) this)) {
|
||||
TileEntity tileentity = blockstate.hasTileEntity() ? this.world.getTileEntity(blockpos) : null;
|
||||
LootContext.Builder lootcontext$builder = (new LootContext.Builder((ServerWorld) this.world)).withRandom(this.world.rand).withParameter(LootParameters.POSITION, blockpos).withParameter(LootParameters.TOOL, ItemStack.EMPTY).withNullableParameter(LootParameters.BLOCK_ENTITY, tileentity);
|
||||
if (this.mode == Explosion.Mode.DESTROY || yield < 1.0F) {
|
||||
lootcontext$builder.withParameter(LootParameters.EXPLOSION_RADIUS, 1.0F / yield);
|
||||
}
|
||||
|
||||
Block.spawnDrops(blockstate, lootcontext$builder);
|
||||
}
|
||||
|
||||
blockstate.onBlockExploded(this.world, blockpos, (Explosion) (Object) this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.causesFire) {
|
||||
for (BlockPos blockPos : this.affectedBlockPositions) {
|
||||
if (this.world.getBlockState(blockPos).isAir(world, blockPos) && this.world.getBlockState(blockPos.down()).isOpaqueCube(this.world, blockPos.down()) && this.random.nextInt(3) == 0) {
|
||||
BlockIgniteEvent event = CraftEventFactory.callBlockIgniteEvent(this.world, blockPos.getX(), blockPos.getY(), blockPos.getZ(), (Explosion) (Object) this);
|
||||
if (!event.isCancelled()) {
|
||||
this.world.setBlockState(blockPos, Blocks.FIRE.getDefaultState());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bridge$wasCancelled() {
|
||||
return wasCanceled;
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package io.izzel.arclight.impl.mixin.v1_14.world.dimension;
|
||||
|
||||
import io.izzel.arclight.common.bridge.world.dimension.DimensionTypeBridge;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.dimension.Dimension;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
@ -8,7 +9,7 @@ import org.spongepowered.asm.mixin.Mixin;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
@Mixin(DimensionType.class)
|
||||
public class DimensionTypeMixin_1_14 {
|
||||
public class DimensionTypeMixin_1_14 implements DimensionTypeBridge {
|
||||
|
||||
protected void arclight$constructor(int idIn, String suffixIn, String directoryIn, BiFunction<World, DimensionType, ? extends Dimension> p_i49935_4_, boolean p_i49935_5_) {
|
||||
throw new RuntimeException();
|
||||
@ -24,4 +25,9 @@ public class DimensionTypeMixin_1_14 {
|
||||
public DimensionType getType() {
|
||||
return (type == null) ? (DimensionType) (Object) this : type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DimensionType bridge$getType() {
|
||||
return getType();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
package io.izzel.arclight.server;
|
||||
|
||||
import io.izzel.arclight.api.Unsafe;
|
||||
import io.izzel.arclight.forgeinstaller.ForgeInstaller;
|
||||
import io.izzel.arclight.common.mod.util.remapper.ArclightRemapper;
|
||||
import io.izzel.arclight.api.ArclightVersion;
|
||||
import io.izzel.arclight.api.EnumHelper;
|
||||
import io.izzel.arclight.api.Unsafe;
|
||||
import io.izzel.arclight.common.mod.util.remapper.ArclightRemapper;
|
||||
import io.izzel.arclight.forgeinstaller.ForgeInstaller;
|
||||
import net.minecraftforge.server.ServerMain;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
@ -29,6 +30,7 @@ public class Main {
|
||||
System.setProperty("log4j.jul.LoggerAdapter", "io.izzel.arclight.common.mod.util.ArclightLoggerAdapter");
|
||||
LogManager.getLogger("Arclight").info("Loading mappings ...");
|
||||
Objects.requireNonNull(ArclightRemapper.INSTANCE);
|
||||
ArclightVersion.setVersion(ArclightVersion.v1_14);
|
||||
ServerMain.main(args);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
"block.KelpTopBlockMixin_1_14",
|
||||
"block.LeavesBlockMixin_1_14",
|
||||
"block.LeverBlockMixin_1_14",
|
||||
"block.LilyPadBlockMixin_1_14",
|
||||
"block.MushroomBlockMixin_1_14",
|
||||
"block.NetherPortalBlockMixin_1_14",
|
||||
"block.NetherWartBlockMixin_1_14",
|
||||
@ -48,7 +49,19 @@
|
||||
"command.impl.TeleportCommandMixin_1_14",
|
||||
"enchantment.FrostWalkerEnchantmentMixin_1_14",
|
||||
"entity.EntityMixin_1_14",
|
||||
"entity.LivingEntityMixin_1_14",
|
||||
"entity.boss.WitherEntityMixin_1_14",
|
||||
"entity.item.ArmorStandEntityMixin_1_14",
|
||||
"entity.item.ItemEntityMixin_1_14",
|
||||
"entity.monster.PillagerEntityMixin_1_14",
|
||||
"entity.monster.RavagerEntityMixin_1_14",
|
||||
"entity.monster.ShulkerEntityMixin_1_14",
|
||||
"entity.monster.ZombiePigmanEntityMixin_1_14",
|
||||
"entity.passive.OcelotEntityMixin_1_14",
|
||||
"entity.passive.PandaEntity_MateGoalMixin",
|
||||
"entity.player.PlayerEntityMixin_1_14",
|
||||
"entity.player.ServerPlayerEntityMixin_1_14",
|
||||
"world.ExplosionMixin_1_14",
|
||||
"world.chunk.ChunkMixin_1_14",
|
||||
"world.dimension.DimensionTypeMixin_1_14",
|
||||
"world.server.TicketManagerMixin_1_14"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user