use of org.spongepowered.api.world.Location in project SpongeCommon by SpongePowered.
the class DamageEventHandler method generateCauseFor.
public static void generateCauseFor(DamageSource damageSource) {
if (damageSource instanceof EntityDamageSourceIndirect) {
net.minecraft.entity.Entity source = damageSource.getTrueSource();
if (!(source instanceof EntityPlayer) && source != null) {
final IMixinEntity mixinEntity = EntityUtil.toMixin(source);
mixinEntity.getNotifierUser().ifPresent(notifier -> Sponge.getCauseStackManager().addContext(EventContextKeys.NOTIFIER, notifier));
mixinEntity.getCreatorUser().ifPresent(owner -> Sponge.getCauseStackManager().addContext(EventContextKeys.OWNER, owner));
}
} else if (damageSource instanceof EntityDamageSource) {
net.minecraft.entity.Entity source = damageSource.getTrueSource();
if (!(source instanceof EntityPlayer) && source != null) {
final IMixinEntity mixinEntity = EntityUtil.toMixin(source);
// TODO only have a UUID, want a user
mixinEntity.getNotifierUser().ifPresent(notifier -> Sponge.getCauseStackManager().addContext(EventContextKeys.NOTIFIER, notifier));
mixinEntity.getCreatorUser().ifPresent(creator -> Sponge.getCauseStackManager().addContext(EventContextKeys.CREATOR, creator));
}
} else if (damageSource instanceof BlockDamageSource) {
Location<org.spongepowered.api.world.World> location = ((BlockDamageSource) damageSource).getLocation();
BlockPos blockPos = ((IMixinLocation) (Object) location).getBlockPos();
final IMixinChunk mixinChunk = (IMixinChunk) ((net.minecraft.world.World) location.getExtent()).getChunkFromBlockCoords(blockPos);
mixinChunk.getBlockNotifier(blockPos).ifPresent(notifier -> Sponge.getCauseStackManager().addContext(EventContextKeys.NOTIFIER, notifier));
mixinChunk.getBlockOwner(blockPos).ifPresent(owner -> Sponge.getCauseStackManager().addContext(EventContextKeys.CREATOR, owner));
}
Sponge.getCauseStackManager().pushCause(damageSource);
}
use of org.spongepowered.api.world.Location in project SpongeCommon by SpongePowered.
the class MixinWorldGenTallGrass method populate.
@Override
public void populate(org.spongepowered.api.world.World worldIn, Extent extent, Random random) {
Vector3i min = extent.getBlockMin();
Vector3i size = extent.getBlockSize();
World world = (World) worldIn;
BlockPos position = new BlockPos(min.getX(), min.getY(), min.getZ());
ShrubType stype = ShrubTypes.TALL_GRASS;
List<ShrubType> result;
// The vanilla populator places down grass in batches of 128, which is a
// decent enough amount in order to get nice 'patches' of grass so we
// divide the total count into batches of 128.
int n = (int) Math.ceil(this.count.getFlooredAmount(random) / 128f);
for (int i = 0; i < n; i++) {
BlockPos pos = position.add(random.nextInt(size.getX()), 0, random.nextInt(size.getZ()));
pos = world.getTopSolidOrLiquidBlock(pos).add(0, 1, 0);
if (this.override != null) {
Location<Extent> pos2 = new Location<>(extent, VecHelper.toVector3i(pos));
stype = this.override.apply(pos2);
} else {
result = this.types.get(random);
if (result.isEmpty()) {
continue;
}
stype = result.get(0);
}
BlockTallGrass.EnumType type = (BlockTallGrass.EnumType) (Object) stype;
this.tallGrassState = Blocks.TALLGRASS.getDefaultState().withProperty(BlockTallGrass.TYPE, type);
generate(world, random, pos);
}
}
use of org.spongepowered.api.world.Location in project SpongeCommon by SpongePowered.
the class PlaceBlockPacketState method addNotifierToBlockEvent.
@Override
public void addNotifierToBlockEvent(BasicPacketContext context, IMixinWorldServer mixinWorldServer, BlockPos pos, IMixinBlockEventData blockEvent) {
final Player player = Sponge.getCauseStackManager().getCurrentCause().first(Player.class).get();
final Location<World> location = new Location<>(player.getWorld(), pos.getX(), pos.getY(), pos.getZ());
final LocatableBlock locatableBlock = LocatableBlock.builder().location(location).state(location.getBlock()).build();
blockEvent.setTickBlock(locatableBlock);
blockEvent.setSourceUser(player);
}
use of org.spongepowered.api.world.Location in project SpongeCommon by SpongePowered.
the class MixinExplosion method doExplosionA.
// TODO fix this whereever it was called from?
// @Override
// public Cause createCause() {
// if (this.createdCause != null) {
// return this.createdCause;
// }
// Object source;
// Object projectileSource = null;
// Object igniter = null;
// if (this.exploder == null) {
// source = getWorld().getBlock(getLocation().getPosition().toInt());
// } else {
// source = this.exploder;
// if (source instanceof Projectile) {
// projectileSource = ((Projectile) this.exploder).getShooter();
// }
//
// // Don't use the exploder itself as igniter
// igniter = getExplosivePlacedBy();
// if (this.exploder == igniter) {
// igniter = null;
// }
// }
//
// final Cause.Builder builder = Cause.source(source);
// if (projectileSource != null) {
// if (igniter != null) {
// builder.named(NamedCause.of("ProjectileSource", projectileSource)).named(NamedCause.of("Igniter", igniter));
// } else {
// builder.named(NamedCause.of("ProjectileSource", projectileSource));
// }
// } else if (igniter != null) {
// builder.named(NamedCause.of("Igniter", igniter));
// }
// if (PhaseTracker.ENABLED) {
// final PhaseData phaseData = PhaseTracker.getInstance().getCurrentPhaseData();
// phaseData.state.getPhase().appendExplosionCause(phaseData);
// }
// return this.createdCause = builder.build();
// }
//
// @Override
// public Cause getCreatedCause() {
// if (this.createdCause == null) {
// createCause();
// }
// return this.createdCause;
// }
/**
* @author gabizou - September 8th, 2016
* @reason Rewrites to use our own hooks that will patch with forge perfectly well,
* and allows for maximal capability.
*/
@Final
@Overwrite
public void doExplosionA() {
// Sponge Start - If the explosion should not break blocks, don't bother calculating it
if (this.shouldBreakBlocks) {
// Sponge End
Set<BlockPos> set = Sets.<BlockPos>newHashSet();
int i = 16;
for (int j = 0; j < 16; ++j) {
for (int k = 0; k < 16; ++k) {
for (int l = 0; l < 16; ++l) {
if (j == 0 || j == 15 || k == 0 || k == 15 || l == 0 || l == 15) {
double d0 = (double) ((float) j / 15.0F * 2.0F - 1.0F);
double d1 = (double) ((float) k / 15.0F * 2.0F - 1.0F);
double d2 = (double) ((float) l / 15.0F * 2.0F - 1.0F);
double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
d0 = d0 / d3;
d1 = d1 / d3;
d2 = d2 / d3;
float f = this.size * (0.7F + this.world.rand.nextFloat() * 0.6F);
double d4 = this.x;
double d6 = this.y;
double d8 = this.z;
for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) {
BlockPos blockpos = new BlockPos(d4, d6, d8);
IBlockState iblockstate = this.world.getBlockState(blockpos);
if (iblockstate.getMaterial() != Material.AIR) {
float f2 = this.exploder != null ? this.exploder.getExplosionResistance((net.minecraft.world.Explosion) (Object) this, this.world, blockpos, iblockstate) : iblockstate.getBlock().getExplosionResistance((Entity) null);
f -= (f2 + 0.3F) * 0.3F;
}
if (f > 0.0F && (this.exploder == null || this.exploder.canExplosionDestroyBlock((net.minecraft.world.Explosion) (Object) this, this.world, blockpos, iblockstate, f))) {
set.add(blockpos);
}
d4 += d0 * 0.30000001192092896D;
d6 += d1 * 0.30000001192092896D;
d8 += d2 * 0.30000001192092896D;
}
}
}
}
}
this.affectedBlockPositions.addAll(set);
}
// Sponge - Finish if statement
float f3 = this.size * 2.0F;
int k1 = MathHelper.floor(this.x - (double) f3 - 1.0D);
int l1 = MathHelper.floor(this.x + (double) f3 + 1.0D);
int i2 = MathHelper.floor(this.y - (double) f3 - 1.0D);
int i1 = MathHelper.floor(this.y + (double) f3 + 1.0D);
int j2 = MathHelper.floor(this.z - (double) f3 - 1.0D);
int j1 = MathHelper.floor(this.z + (double) f3 + 1.0D);
// Sponge Start - Check if this explosion should damage entities
List<Entity> list = this.shouldDamageEntities ? this.world.getEntitiesWithinAABBExcludingEntity(this.exploder, new AxisAlignedBB((double) k1, (double) i2, (double) j2, (double) l1, (double) i1, (double) j1)) : Collections.emptyList();
// Now we can throw our Detonate Event
final List<Location<World>> blockPositions = new ArrayList<>(this.affectedBlockPositions.size());
final List<org.spongepowered.api.entity.Entity> entities = new ArrayList<>(list.size());
for (BlockPos pos : this.affectedBlockPositions) {
blockPositions.add(new Location<>((World) this.world, pos.getX(), pos.getY(), pos.getZ()));
}
for (Entity entity : list) {
entities.add((org.spongepowered.api.entity.Entity) entity);
}
ExplosionEvent.Detonate detonate = SpongeEventFactory.createExplosionEventDetonate(Sponge.getCauseStackManager().getCurrentCause(), blockPositions, entities, this, (World) this.world);
SpongeImpl.postEvent(detonate);
if (detonate.isCancelled()) {
this.affectedBlockPositions.clear();
return;
}
this.affectedBlockPositions.clear();
if (this.shouldBreakBlocks) {
for (Location<World> worldLocation : detonate.getAffectedLocations()) {
this.affectedBlockPositions.add(((IMixinLocation) (Object) worldLocation).getBlockPos());
}
}
list.clear();
if (this.shouldDamageEntities) {
for (org.spongepowered.api.entity.Entity entity : detonate.getEntities()) {
try {
list.add(EntityUtil.toNative(entity));
} catch (Exception e) {
// Do nothing, a plugin tried to use the wrong entity somehow.
}
}
}
// Sponge End
Vec3d vec3d = new Vec3d(this.x, this.y, this.z);
for (int k2 = 0; k2 < list.size(); ++k2) {
Entity entity = list.get(k2);
if (!entity.isImmuneToExplosions()) {
double d12 = entity.getDistance(this.x, this.y, this.z) / (double) f3;
if (d12 <= 1.0D) {
double d5 = entity.posX - this.x;
double d7 = entity.posY + (double) entity.getEyeHeight() - this.y;
double d9 = entity.posZ - this.z;
double d13 = (double) MathHelper.sqrt(d5 * d5 + d7 * d7 + d9 * d9);
if (d13 != 0.0D) {
d5 = d5 / d13;
d7 = d7 / d13;
d9 = d9 / d13;
double d14 = (double) this.world.getBlockDensity(vec3d, entity.getEntityBoundingBox());
double d10 = (1.0D - d12) * d14;
entity.attackEntityFrom(DamageSource.causeExplosionDamage((net.minecraft.world.Explosion) (Object) this), (float) ((int) ((d10 * d10 + d10) / 2.0D * 7.0D * (double) f3 + 1.0D)));
double d11 = 1.0D;
if (entity instanceof EntityLivingBase) {
d11 = EnchantmentProtection.getBlastDamageReduction((EntityLivingBase) entity, d10);
}
entity.motionX += d5 * d11;
entity.motionY += d7 * d11;
entity.motionZ += d9 * d11;
if (entity instanceof EntityPlayer) {
EntityPlayer entityplayer = (EntityPlayer) entity;
if (!entityplayer.isSpectator() && (!entityplayer.isCreative() || !entityplayer.capabilities.isFlying)) {
this.playerKnockbackMap.put(entityplayer, new Vec3d(d5 * d10, d7 * d10, d9 * d10));
}
}
}
}
}
}
}
use of org.spongepowered.api.world.Location in project SpongeCommon by SpongePowered.
the class ForestPopulator method populate.
@Override
public void populate(org.spongepowered.api.world.World world, Extent extent, Random random) {
Vector3i min = extent.getBlockMin();
Vector3i size = extent.getBlockSize();
int n = this.count.getFlooredAmount(random);
int x;
int z;
BlockPos pos;
List<PopulatorObject> result;
PopulatorObject type;
for (int i = 0; i < n; i++) {
x = random.nextInt(size.getX());
z = random.nextInt(size.getZ());
pos = ((net.minecraft.world.World) world).getTopSolidOrLiquidBlock(new BlockPos(min.getX() + x, min.getY(), min.getZ() + z));
if (this.override != null) {
Location<Extent> pos2 = new Location<>(extent, VecHelper.toVector3i(pos));
type = this.override.apply(pos2);
} else {
result = this.types.get(random);
if (result.isEmpty()) {
continue;
}
type = result.get(0);
}
if (type.canPlaceAt(world, pos.getX(), pos.getY(), pos.getZ())) {
type.placeObject(world, random, pos.getX(), pos.getY(), pos.getZ());
}
}
}
Aggregations