use of org.spongepowered.api.world.server.ServerLocation in project SpongeCommon by SpongePowered.
the class SpongeTeleportHelper method getBlockLocations.
private Stream<Vector3i> getBlockLocations(ServerLocation worldLocation, int height, int width) {
// We don't want to warp outside of the world border, so we want to check that we're within it.
final WorldBorder.Settings worldBorder = (WorldBorder.Settings) worldLocation.world().properties().worldBorder();
final double radius = worldBorder.getSize() / 2.0D;
int worldBorderMinX = GenericMath.floor(worldBorder.getCenterX() - radius);
int worldBorderMinZ = GenericMath.floor(worldBorder.getCenterZ() - radius);
int worldBorderMaxX = GenericMath.floor(worldBorder.getCenterX() + radius);
int worldBorderMaxZ = GenericMath.floor(worldBorder.getCenterZ() + radius);
// Get the World and get the maximum Y value.
int worldMaxY = worldLocation.world().max().y();
Vector3i vectorLocation = worldLocation.blockPosition();
// We use clamp to remain within the world confines, so we don't waste time checking blocks outside of the
// world border and the world height.
int minY = GenericMath.clamp(vectorLocation.y() - height, 0, worldMaxY);
int maxY = GenericMath.clamp(vectorLocation.y() + height, 0, worldMaxY);
int minX = GenericMath.clamp(vectorLocation.x() - width, worldBorderMinX, worldBorderMaxX);
int maxX = GenericMath.clamp(vectorLocation.x() + width, worldBorderMinX, worldBorderMaxX);
int minZ = GenericMath.clamp(vectorLocation.z() - width, worldBorderMinZ, worldBorderMaxZ);
int maxZ = GenericMath.clamp(vectorLocation.z() + width, worldBorderMinZ, worldBorderMaxZ);
// We now iterate over all possible x, y and z positions to get all possible vectors.
List<Vector3i> vectors = new ArrayList<>();
for (int y = minY; y <= maxY; y++) {
for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) {
vectors.add(new Vector3i(x, y, z));
}
}
}
Comparator<Vector3i> c = Comparator.comparingInt(vectorLocation::distanceSquared);
// The compiler seems to need this to be a new line.
// We check to see what the y location is, preferring changes in Y over X and Z, and higher over lower locations.
c = c.thenComparing(x -> -Math.abs(vectorLocation.y() - x.y())).thenComparing(x -> -x.y());
// Sort them according to the distance to the provided worldLocation.
return vectors.stream().sorted(c);
}
use of org.spongepowered.api.world.server.ServerLocation in project SpongeCommon by SpongePowered.
the class ServerLevelMixin method impl$constructPostEventForEntityAdd.
@Inject(method = "addEntity", at = @At("HEAD"))
private void impl$constructPostEventForEntityAdd(final Entity entity, final CallbackInfoReturnable<Boolean> cir) {
if (!(entity instanceof EntityBridge)) {
return;
}
if (!((EntityBridge) entity).bridge$isConstructing()) {
return;
}
((EntityBridge) entity).bridge$fireConstructors();
final Vec3 position = entity.position();
final ServerLocation location = ServerLocation.of((ServerWorld) this, position.x(), position.y(), position.z());
final Vec2 rotationVector = entity.getRotationVector();
final Vector3d rotation = new Vector3d(rotationVector.x, rotationVector.y, 0);
try (final CauseStackManager.StackFrame frame = PhaseTracker.SERVER.pushCauseFrame()) {
frame.pushCause(entity);
final Event construct = SpongeEventFactory.createConstructEntityEventPost(frame.currentCause(), (org.spongepowered.api.entity.Entity) entity, location, rotation, ((EntityType<?>) entity.getType()));
SpongeCommon.post(construct);
}
}
use of org.spongepowered.api.world.server.ServerLocation in project SpongeCommon by SpongePowered.
the class CommandSourceStackMixin method impl$updateCauseOnWithPosition.
@Inject(method = "withPosition", at = @At("RETURN"))
private void impl$updateCauseOnWithPosition(final Vec3 pos, final CallbackInfoReturnable<CommandSourceStack> cir) {
if (cir.getReturnValue() != (Object) this) {
final org.spongepowered.math.vector.Vector3d position = VecHelper.toVector3d(pos);
final ServerLocation location = this.impl$cause.context().get(EventContextKeys.LOCATION).map(x -> ServerLocation.of(x.world(), position)).orElseGet(() -> ServerLocation.of((org.spongepowered.api.world.server.ServerWorld) cir.getReturnValue().getLevel(), position));
((CommandSourceStackBridge) cir.getReturnValue()).bridge$setCause(this.impl$applyToCause(EventContextKeys.LOCATION, location));
}
}
use of org.spongepowered.api.world.server.ServerLocation in project SpongeCommon by SpongePowered.
the class CactusBlockMixin method impl$reAssignForBlockDamageSource.
@Redirect(method = "entityInside", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;hurt(Lnet/minecraft/world/damagesource/DamageSource;F)Z"))
private boolean impl$reAssignForBlockDamageSource(final Entity self, final DamageSource source, float damage, final net.minecraft.world.level.block.state.BlockState state, final net.minecraft.world.level.Level world, final BlockPos pos, final Entity entity) {
if (world.isClientSide()) {
return entity.hurt(source, damage);
}
try {
final ServerLocation location = ServerLocation.of((ServerWorld) world, pos.getX(), pos.getY(), pos.getZ());
final MinecraftBlockDamageSource cactus = new MinecraftBlockDamageSource("cactus", location);
((DamageSourceBridge) (Object) cactus).bridge$setCactusSource();
return entity.hurt(DamageSource.CACTUS, damage);
} finally {
((DamageSourceBridge) source).bridge$setCactusSource();
}
}
use of org.spongepowered.api.world.server.ServerLocation in project SpongeCommon by SpongePowered.
the class CampfireBlockMixin method impl$spongeRedirectForFireDamage.
@Redirect(method = "entityInside", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;hurt(Lnet/minecraft/world/damagesource/DamageSource;F)Z"))
private boolean impl$spongeRedirectForFireDamage(final Entity self, final DamageSource source, final float damage, final BlockState blockState, final Level world, final BlockPos blockPos, final Entity entity) {
if (self.level.isClientSide) {
// Short Circuit
return self.hurt(source, damage);
}
try {
final ServerLocation location = ServerLocation.of((ServerWorld) world, blockPos.getX(), blockPos.getY(), blockPos.getZ());
final DamageSource fire = MinecraftBlockDamageSource.ofFire("inFire", location, true);
((DamageSourceBridge) fire).bridge$setFireSource();
return self.hurt(DamageSource.IN_FIRE, damage);
} finally {
// Since "source" is already the DamageSource.IN_FIRE object, we can re-use it to re-assign.
((DamageSourceBridge) source).bridge$setFireSource();
}
}
Aggregations