use of org.spongepowered.common.bridge.world.entity.PlatformEntityBridge in project SpongeCommon by SpongePowered.
the class ServerPlayerMixin_Tracker method tracker$throwItemDrop.
/**
* @author gabizou - June 4th, 2016
* @author i509VCB - February 17th, 2020 - 1.14.4
* @author gabizou - December 31st, 2021 - 1.16.5
* @reason We inject a construct event for the item drop and conveniently
* can redirect the super call.
*/
@Redirect(method = "drop", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;drop(Lnet/minecraft/world/item/ItemStack;ZZ)Lnet/minecraft/world/entity/item/ItemEntity;"))
@Nullable
private ItemEntity tracker$throwItemDrop(final Player thisPlayer, final ItemStack droppedItem, final boolean dropAround, final boolean traceItem) {
if (droppedItem.isEmpty()) {
return null;
}
if (((PlatformEntityBridge) this).bridge$isFakePlayer()) {
return super.shadow$drop(droppedItem, dropAround, traceItem);
}
if (((LevelBridge) this.level).bridge$isFake()) {
return super.shadow$drop(droppedItem, dropAround, traceItem);
}
final double posX1 = this.shadow$getX();
final double posY1 = this.shadow$getEyeY() - (double) 0.3F;
final double posZ1 = this.shadow$getZ();
// Now the real fun begins.
final ItemStack item;
final ItemStackSnapshot snapshot = ItemStackUtil.snapshotOf(droppedItem);
final List<ItemStackSnapshot> original = new ArrayList<>();
original.add(snapshot);
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
item = SpongeCommonEventFactory.throwDropItemAndConstructEvent((ServerPlayer) (Object) this, posX1, posY1, posZ1, snapshot, original, frame);
if (item == null || item.isEmpty()) {
return null;
}
// Here is where we would potentially perform item pre-merging (merge the item stacks with previously captured item stacks
// and only if those stacks can be stacked (count increased). Otherwise, we'll just continue to throw the entity item.
// For now, due to refactoring a majority of all of this code, pre-merging is disabled entirely.
final ItemEntity itemEntity = new ItemEntity(this.level, posX1, posY1, posZ1, droppedItem);
itemEntity.setPickUpDelay(40);
if (traceItem) {
itemEntity.setThrower(this.shadow$getUUID());
}
final Random random = this.shadow$getRandom();
if (dropAround) {
final float f = random.nextFloat() * 0.5F;
final float f1 = random.nextFloat() * ((float) Math.PI * 2F);
itemEntity.setDeltaMovement(-Mth.sin(f1) * f, 0.2F, Mth.cos(f1) * f);
} else {
final float f8 = Mth.sin(this.xRot * ((float) Math.PI / 180F));
final float f2 = Mth.cos(this.xRot * ((float) Math.PI / 180F));
final float f3 = Mth.sin(this.yRot * ((float) Math.PI / 180F));
final float f4 = Mth.cos(this.yRot * ((float) Math.PI / 180F));
final float f5 = this.random.nextFloat() * ((float) Math.PI * 2F);
final float f6 = 0.02F * this.random.nextFloat();
itemEntity.setDeltaMovement((double) (-f3 * f2 * 0.3F) + Math.cos(f5) * (double) f6, (-f8 * 0.3F + 0.1F + (this.random.nextFloat() - this.random.nextFloat()) * 0.1F), (double) (f4 * f2 * 0.3F) + Math.sin(f5) * (double) f6);
}
return itemEntity;
}
}
use of org.spongepowered.common.bridge.world.entity.PlatformEntityBridge in project SpongeCommon by SpongePowered.
the class EntityActivationRange method checkIfActive.
/**
* Checks if the entity is active for this tick.
*
* @param entity The entity to check for activity
* @return Whether the given entity should be active
*/
public static boolean checkIfActive(final Entity entity) {
// Never safe to skip fireworks or entities not yet added to chunk
if (entity instanceof Player || entity.level.isClientSide() || !entity.inChunk || entity instanceof FireworkRocketEntity) {
return true;
}
final LevelChunkBridge activeChunk = ((ActiveChunkReferantBridge) entity).bridge$getActiveChunk();
if (activeChunk == null) {
// Should never happen but just in case for mods, always tick
return true;
}
if (!activeChunk.bridge$isActive()) {
return false;
}
// If in forced chunk or is player
if (activeChunk.bridge$isPersistedChunk() || ((PlatformEntityBridge) entity).bridge$isFakePlayer() && entity instanceof ServerPlayer) {
return true;
}
final long currentTick = SpongeCommon.server().getTickCount();
final ActivationCapabilityBridge spongeEntity = (ActivationCapabilityBridge) entity;
boolean isActive = spongeEntity.activation$getActivatedTick() >= currentTick || spongeEntity.activation$getDefaultActivationState();
// Should this entity tick?
if (!isActive) {
if ((currentTick - spongeEntity.activation$getActivatedTick() - 1) % 20 == 0) {
// Check immunities every 20 ticks.
if (EntityActivationRange.checkEntityImmunities(entity)) {
// Triggered some sort of immunity, give 20 full ticks before we check again.
spongeEntity.activation$setActivatedTick(currentTick + 20);
}
isActive = true;
}
// Add a little performance juice to active entities. Skip 1/4 if not immune.
} else if (!spongeEntity.activation$getDefaultActivationState() && entity.tickCount % 4 == 0 && !EntityActivationRange.checkEntityImmunities(entity)) {
isActive = false;
}
if (isActive && !activeChunk.bridge$areNeighborsLoaded()) {
isActive = false;
}
return isActive;
}
use of org.spongepowered.common.bridge.world.entity.PlatformEntityBridge in project SpongeCommon by SpongePowered.
the class EntityUtil method performPostChangePlayerWorldLogic.
public static void performPostChangePlayerWorldLogic(final ServerPlayer player, final ServerLevel fromWorld, final ServerLevel originalToWorld, final ServerLevel toWorld, final boolean isPortal) {
// Sponge Start - Send any platform dimension data
((ServerPlayerBridge) player).bridge$sendDimensionData(player.connection.connection, toWorld.dimensionType(), toWorld.dimension());
// Sponge End
final LevelData worldinfo = toWorld.getLevelData();
// We send dimension change for portals before loading chunks
if (!isPortal) {
// Sponge Start - Allow the platform to handle how dimension changes are sent down
((ServerPlayerBridge) player).bridge$sendChangeDimension(toWorld.dimensionType(), toWorld.dimension(), BiomeManager.obfuscateSeed(toWorld.getSeed()), player.gameMode.getGameModeForPlayer(), player.gameMode.getPreviousGameModeForPlayer(), toWorld.isDebug(), toWorld.isFlat(), true);
}
// Sponge End
player.connection.send(new ClientboundChangeDifficultyPacket(worldinfo.getDifficulty(), worldinfo.isDifficultyLocked()));
final PlayerList playerlist = player.getServer().getPlayerList();
playerlist.sendPlayerPermissionLevel(player);
// Sponge Start - Have the platform handle removing the entity from the world. Move this to after the event call so
// that we do not remove the player from the world unless we really have teleported..
((PlatformServerLevelBridge) fromWorld).bridge$removeEntity(player, true);
((PlatformEntityBridge) player).bridge$revive();
// Sponge End
player.setLevel(toWorld);
toWorld.addDuringPortalTeleport(player);
if (isPortal) {
((ServerPlayerAccessor) player).invoker$triggerDimensionChangeTriggers(toWorld);
}
player.gameMode.setLevel(toWorld);
player.connection.send(new ClientboundPlayerAbilitiesPacket(player.abilities));
playerlist.sendLevelInfo(player, toWorld);
playerlist.sendAllPlayerInfo(player);
for (final MobEffectInstance effectinstance : player.getActiveEffects()) {
player.connection.send(new ClientboundUpdateMobEffectPacket(player.getId(), effectinstance));
}
if (isPortal) {
player.connection.send(new ClientboundLevelEventPacket(1032, BlockPos.ZERO, 0, false));
}
((ServerLevelBridge) fromWorld).bridge$getBossBarManager().onPlayerDisconnect(player);
((ServerLevelBridge) toWorld).bridge$getBossBarManager().onPlayerDisconnect(player);
((ServerPlayerAccessor) player).accessor$lastSentExp(-1);
((ServerPlayerAccessor) player).accessor$lastSentHealth(-1.0f);
((ServerPlayerAccessor) player).accessor$lastSentFood(-1);
if (!isPortal) {
player.connection.teleport(player.getX(), player.getY(), player.getZ(), player.yRot, player.xRot);
player.connection.resetPosition();
}
if (player.containerMenu != player.inventoryMenu) {
player.closeContainer();
}
// Sponge Start - Call event
Sponge.eventManager().post(SpongeEventFactory.createChangeEntityWorldEventPost(PhaseTracker.getCauseStackManager().currentCause(), (org.spongepowered.api.entity.Entity) player, (ServerWorld) fromWorld, (ServerWorld) originalToWorld, (ServerWorld) toWorld));
// Sponge End
}
use of org.spongepowered.common.bridge.world.entity.PlatformEntityBridge in project SpongeCommon by SpongePowered.
the class PlayerAdvancementsMixin method impl$updateProgressOnUnregister.
@Nullable
@Redirect(method = "unregisterListeners", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/advancements/AdvancementProgress;getCriterion(Ljava/lang/String;)Lnet/minecraft/advancements/CriterionProgress;"))
private CriterionProgress impl$updateProgressOnUnregister(final AdvancementProgress advancementProgress, final String criterion) {
if (((PlatformEntityBridge) this.player).bridge$isFakePlayer()) {
return advancementProgress.getCriterion(criterion);
}
final org.spongepowered.api.advancement.Advancement advancement = ((org.spongepowered.api.advancement.AdvancementProgress) advancementProgress).advancement();
final AdvancementCriterion advancementCriterion = (AdvancementCriterion) ((Advancement) advancement).getCriteria().get(criterion);
final CriterionBridge criterionBridge = (CriterionBridge) advancementCriterion;
// Only remove the trigger once the goal is reached
if (criterionBridge.bridge$getScoreCriterion() != null && !((org.spongepowered.api.advancement.AdvancementProgress) advancementProgress).get(criterionBridge.bridge$getScoreCriterion()).get().achieved()) {
return null;
}
return advancementProgress.getCriterion(criterion);
}
Aggregations