@Redirect( method = "interact", at = @At( value = "INVOKE", target = "Ljava/util/Random;nextInt(I)I", ordinal = 0, remap = false)) public int onTame(Random rand, int bound, EntityPlayer player) { int random = rand.nextInt(bound); if (random == 0 && !SpongeImpl.postEvent( SpongeEventFactory.createTameEntityEvent( Cause.of( NamedCause.source(player), NamedCause.of( TameEntityEvent.USED_ITEM, ((org.spongepowered.api.item.inventory.ItemStack) this.currentItemStack) .createSnapshot())), this))) { this.currentItemStack = null; return random; } this.currentItemStack = null; return 1; }
/** * @author gabizou - February 7th, 2016 * <p>This will short circuit all other patches such that we control the entities being loaded * by chunkloading and can throw our bulk entity event. This will bypass Forge's hook for * individual entity events, but the SpongeModEventManager will still successfully throw the * appropriate event and cancel the entities otherwise contained. * @param entities The entities being loaded * @param callbackInfo The callback info */ @Final @Inject(method = "loadEntities", at = @At("HEAD"), cancellable = true) private void spongeLoadEntities( Collection<net.minecraft.entity.Entity> entities, CallbackInfo callbackInfo) { if (entities.isEmpty()) { // just return, no entities to load! callbackInfo.cancel(); return; } List<Entity> entityList = new ArrayList<>(); ImmutableList.Builder<EntitySnapshot> snapshotBuilder = ImmutableList.builder(); for (net.minecraft.entity.Entity entity : entities) { entityList.add((Entity) entity); snapshotBuilder.add(((Entity) entity).createSnapshot()); } SpawnCause cause = SpawnCause.builder().type(InternalSpawnTypes.CHUNK_LOAD).build(); List<NamedCause> causes = new ArrayList<>(); causes.add(NamedCause.source(cause)); causes.add(NamedCause.of("World", this)); SpawnEntityEvent.ChunkLoad chunkLoad = SpongeEventFactory.createSpawnEntityEventChunkLoad( Cause.of(causes), entityList, snapshotBuilder.build(), this); SpongeImpl.postEvent(chunkLoad); if (!chunkLoad.isCancelled()) { for (Entity successful : chunkLoad.getEntities()) { this.loadedEntityList.add((net.minecraft.entity.Entity) successful); this.onEntityAdded((net.minecraft.entity.Entity) successful); } } callbackInfo.cancel(); }
public static Cause generateCauseFor(DamageSource damageSource) { if (damageSource instanceof EntityDamageSourceIndirect) { net.minecraft.entity.Entity source = damageSource.getEntity(); Optional<User> owner = ((IMixinEntity) source).getTrackedPlayer(NbtDataUtil.SPONGE_ENTITY_CREATOR); if (owner.isPresent()) { return Cause.of( NamedCause.of(DamageEntityEvent.SOURCE, damageSource), NamedCause.of(DamageEntityEvent.CREATOR, owner.get())); } else { return Cause.of(NamedCause.of(DamageEntityEvent.SOURCE, damageSource)); } } else if (damageSource instanceof EntityDamageSource) { net.minecraft.entity.Entity source = damageSource.getEntity(); Optional<User> owner = ((IMixinEntity) source).getTrackedPlayer(NbtDataUtil.SPONGE_ENTITY_CREATOR); Optional<User> notifier = ((IMixinEntity) source).getTrackedPlayer(NbtDataUtil.SPONGE_ENTITY_NOTIFIER); List<Object> causeObjects = new ArrayList<>(); causeObjects.add(NamedCause.of(DamageEntityEvent.SOURCE, damageSource)); if (notifier.isPresent()) { causeObjects.add(NamedCause.of(DamageEntityEvent.NOTIFIER, notifier.get())); } if (owner.isPresent()) { causeObjects.add(NamedCause.of(DamageEntityEvent.CREATOR, owner.get())); } return Cause.of(causeObjects.toArray()); } else if (damageSource instanceof BlockDamageSource) { List<Object> causeObjects = new ArrayList<>(); Location<org.spongepowered.api.world.World> location = ((BlockDamageSource) damageSource).getLocation(); BlockPos blockPos = VecHelper.toBlockPos(location); Optional<User> owner = ((IMixinChunk) ((net.minecraft.world.World) location.getExtent()) .getChunkFromBlockCoords(blockPos)) .getBlockOwner(blockPos); Optional<User> notifier = ((IMixinChunk) ((net.minecraft.world.World) location.getExtent()) .getChunkFromBlockCoords(blockPos)) .getBlockNotifier(blockPos); causeObjects.add(NamedCause.of(DamageEntityEvent.SOURCE, damageSource)); if (notifier.isPresent()) { causeObjects.add(NamedCause.of(DamageEntityEvent.NOTIFIER, notifier.get())); } if (owner.isPresent()) { causeObjects.add(NamedCause.of(DamageEntityEvent.CREATOR, owner.get())); } return Cause.of(causeObjects.toArray()); } else { return Cause.of(NamedCause.of(DamageEntityEvent.SOURCE, damageSource)); } }
@Inject( method = "dropItem", at = @At( value = "FIELD", opcode = Opcodes.GETFIELD, target = "Lnet/minecraft/entity/player/EntityPlayer;posY:D"), cancellable = true) private void onDropTop( ItemStack itemStack, boolean a, boolean b, CallbackInfoReturnable<EntityItem> callbackInfoReturnable) { final double height = this.posY - 0.3D + (double) this.getEyeHeight(); Transform<org.spongepowered.api.world.World> transform = new Transform<>(this.getWorld(), new Vector3d(this.posX, height, this.posZ)); SpawnCause cause = EntitySpawnCause.builder().entity(this).type(SpawnTypes.DROPPED_ITEM).build(); ConstructEntityEvent.Pre event = SpongeEventFactory.createConstructEntityEventPre( Cause.of(NamedCause.source(cause)), EntityTypes.ITEM, transform); SpongeImpl.postEvent(event); if (event.isCancelled()) { callbackInfoReturnable.setReturnValue(null); } }
public CommandResult execute(CommandSource src, CommandContext ctx) throws CommandException { if (src instanceof Player) { Player player = (Player) src; String playerTeamName = ConfigManager.getTeam(player.getUniqueId()); if (playerTeamName != null && !ConfigManager.getMembers(playerTeamName).contains(player.getUniqueId().toString())) { BigDecimal money = ConfigManager.getClaimCost() .multiply(new BigDecimal(ConfigManager.getClaims(playerTeamName))); Polis.economyService .getOrCreateAccount(playerTeamName) .get() .deposit( Polis.economyService.getDefaultCurrency(), money, Cause.of(NamedCause.source(player))); ConfigManager.depositToTownBank(money, playerTeamName); ConfigManager.removeClaims(playerTeamName); player.sendMessage( Text.of( TextColors.GREEN, "[Polis]: ", TextColors.GOLD, "Successfully removed all claims!")); } else if (playerTeamName != null) { player.sendMessage( Text.of( TextColors.GREEN, "[Polis]: ", TextColors.DARK_RED, "Error! ", TextColors.RED, "Ask your leader to remove all claims!")); } else { player.sendMessage( Text.of( TextColors.GREEN, "[Polis]: ", TextColors.DARK_RED, "Error! ", TextColors.RED, "You're not part of a town!")); } } else { src.sendMessage( Text.of( TextColors.DARK_RED, "Error! ", TextColors.RED, "Must be an in-game player to use /polis unclaimall!")); } return CommandResult.success(); }
public static Optional<Tuple<DamageModifier, Function<? super Double, Double>>> createAbsorptionModifier(EntityLivingBase entityLivingBase, DamageSource damageSource) { if (entityLivingBase.isPotionActive(Potion.absorption)) { Function<? super Double, Double> function = damage -> -(Math.max( damage - Math.max(damage - entityLivingBase.getAbsorptionAmount(), 0.0F), 0.0F)); DamageModifier modifier = DamageModifier.builder() .cause( Cause.of( NamedCause.of( DamageEntityEvent.ABSORPTION, entityLivingBase.getActivePotionEffect(Potion.absorption)), NamedCause.of(DamageEntityEvent.CREATOR, entityLivingBase))) .type(DamageModifierTypes.ABSORPTION) .build(); return Optional.of(new Tuple<>(modifier, function)); } return Optional.empty(); }
public void submitInventory(Class owner, boolean openInventory) { this.owner = owner; em.registerListener(owner, this); if (openInventory) { for (UUID user : users) { Optional<Player> player = Sponge.getServer().getPlayer(user); if (player.isPresent()) { this.container = player .get() .openInventory(this.inventory, Cause.of(NamedCause.source(player))) .orElse(null); // TODO check if not opened } } } }
/** * @author gabizou - January 30th, 2016 * @author blood - May 12th, 2016 * @reason If capturing is enabled, captures the item and avoids spawn. If capturing is not * enabled, redirects the dropped item spawning to use our world spawning since we know the * cause. */ @Overwrite public void joinEntityItemWithWorld(EntityItem itemIn) { if (this.worldObj.isRemote) { this.worldObj.spawnEntityInWorld(itemIn); return; } if (this.captureItemDrops) { this.capturedItemDrops.add(itemIn); return; } SpawnCause spawnCause = EntitySpawnCause.builder().entity(this).type(SpawnTypes.DROPPED_ITEM).build(); ((org.spongepowered.api.world.World) this.worldObj) .spawnEntity((Entity) itemIn, Cause.of(NamedCause.source(spawnCause))); }
public static Optional<Tuple<DamageModifier, Function<? super Double, Double>>> createHardHatModifier(EntityLivingBase entityLivingBase, DamageSource damageSource) { if ((damageSource instanceof FallingBlockDamageSource) && entityLivingBase.getEquipmentInSlot(4) != null) { DamageModifier modifier = DamageModifier.builder() .cause( Cause.of( NamedCause.of( DamageEntityEvent.HARD_HAT_ARMOR, ((ItemStack) entityLivingBase.getEquipmentInSlot(4)).createSnapshot()))) .type(DamageModifierTypes.HARD_HAT) .build(); return Optional.of(new Tuple<>(modifier, HARD_HAT_FUNCTION)); } return Optional.empty(); }
public static Optional<Tuple<DamageModifier, Function<? super Double, Double>>> createResistanceModifier(EntityLivingBase entityLivingBase, DamageSource damageSource) { if (!damageSource.isDamageAbsolute() && entityLivingBase.isPotionActive(Potion.resistance) && damageSource != DamageSource.outOfWorld) { PotionEffect effect = ((PotionEffect) entityLivingBase.getActivePotionEffect(Potion.resistance)); return Optional.of( new Tuple<>( DamageModifier.builder() .cause(Cause.of(NamedCause.of(DamageEntityEvent.RESISTANCE, effect))) .type(DamageModifierTypes.DEFENSIVE_POTION_EFFECT) .build(), createResistanceFunction(effect.getAmplifier()))); } return Optional.empty(); }
@Listener(order = Order.POST) public void onAffectSlotEvent(AffectSlotEvent event, @Root Player player) { for (SlotTransaction transaction : event.getTransactions()) { ItemStack itemStack = transaction.getFinal().createStack(); BigDecimal amount = WalletDrop.getValue(itemStack); if (amount.compareTo(BigDecimal.ZERO) == 0) { continue; } WorldSettings settings = WorldSettings.get(player.getWorld()); if (player.gameMode().get().equals(GameModes.CREATIVE) && !settings.isCreativeModeAllowed()) { event.setCancelled(true); return; } if (settings.isUsePermissions()) { if (!player.hasPermission("walletdrop.enable")) { return; } } WalletPickupEvent moneyPickupEvent = new WalletPickupEvent(itemStack, amount, Cause.of(NamedCause.source(player))); if (!Sponge.getEventManager().post(moneyPickupEvent)) { Sponge.getScheduler() .createTaskBuilder() .delayTicks(2) .execute( c -> { player.getInventory().query(itemStack).clear(); }) .submit(Main.getPlugin()); WalletDrop.depositOrWithdraw(player, moneyPickupEvent.getAmount()); WalletDrop.sendPickupMessage(player, amount); } } }
public static Optional<Tuple<DamageModifier, Function<? super Double, Double>>> createBlockingModifier(EntityLivingBase entityLivingBase, DamageSource damageSource) { if (!damageSource.isUnblockable() && (entityLivingBase instanceof EntityPlayer && ((EntityPlayer) entityLivingBase).isBlocking())) { DamageModifier modifier = DamageModifier.builder() .cause( Cause.of( NamedCause.of( DamageEntityEvent.BLOCKING, ((ItemStack) ((EntityPlayer) entityLivingBase).getCurrentEquippedItem()) .createSnapshot()))) .type(DamageModifierTypes.BLOCKING) .build(); return Optional.of(new Tuple<>(modifier, BLOCKING_FUNCTION)); } return Optional.empty(); }
@Inject( method = "randomTick", at = @At(value = "HEAD"), locals = LocalCapture.CAPTURE_FAILEXCEPTION, cancellable = true) public void callRandomTickEvent( net.minecraft.world.World world, BlockPos pos, IBlockState state, Random rand, CallbackInfo ci) { BlockSnapshot blockSnapshot = ((World) world).createSnapshot(VecHelper.toVector(pos)); final TickBlockEvent event = SpongeEventFactory.createTickBlockEvent(Cause.of(NamedCause.source(world)), blockSnapshot); SpongeImpl.postEvent(event); if (event.isCancelled()) { ci.cancel(); } }
@Redirect( method = "onUpdate", at = @At( value = "INVOKE", target = "Lnet/minecraft/entity/player/EntityPlayer;isPlayerSleeping()Z")) public boolean onIsPlayerSleeping(EntityPlayer self) { if (self.isPlayerSleeping()) { if (!this.worldObj.isRemote) { SpongeImpl.postEvent( SpongeEventFactory.createSleepingEventTick( Cause.of(NamedCause.source(this)), this.getWorld().createSnapshot(VecHelper.toVector(this.playerLocation)), this)); } return true; } return false; }
@Redirect( method = "onUpdate()V", at = @At( value = "INVOKE", target = "Lnet/minecraft/entity/Entity;attackEntityFrom(Lnet/minecraft/util/DamageSource;F)Z")) public boolean onAttackEntityFrom( net.minecraft.entity.Entity entity, DamageSource damageSource, float damage) { EntitySnapshot fishHookSnapshot = this.createSnapshot(); FishingEvent.HookEntity event = SpongeEventFactory.createFishingEventHookEntity( Cause.of(NamedCause.source(this.angler)), this.createSnapshot(), this, (Entity) entity); if (!SpongeImpl.postEvent(event)) { if (this.getShooter() instanceof Entity) { DamageSource.causeThrownDamage( (net.minecraft.entity.Entity) (Object) this, (net.minecraft.entity.Entity) this.getShooter()); } return entity.attackEntityFrom(damageSource, (float) this.getDamage()); } return false; }
@Inject( method = "combineItems", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/item/EntityItem;setDead()V")) public void onCombineItems(EntityItem other, CallbackInfoReturnable<Boolean> cir) { this.destructCause = Cause.of(NamedCause.of("CombinedItem", other)); }
@Inject( method = "onUpdate()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/item/EntityItem;setDead()V")) public void onEntityItemUpdate(CallbackInfo ci) { this.destructCause = Cause.of(NamedCause.of("ExpiredItem", this)); }
/** * @author Aaron1011 - February 6th, 2015 * @reason This needs to handle for both cases where a fish and/or an entity is being caught. * There's no real good way to do this with an injection. */ @Overwrite public int handleHookRetraction() { if (this.worldObj.isRemote) { return 0; } // Sponge start byte b0 = 0; net.minecraft.item.ItemStack itemStack = null; int exp = 0; if (this.ticksCatchable > 0) { itemStack = this.getFishingResult(); exp = this.rand.nextInt(6) + 1; } EntitySnapshot fishHookSnapshot = this.createSnapshot(); Transaction<ItemStackSnapshot> transaction = null; if (itemStack != null) { ItemStackSnapshot original = ((ItemStack) itemStack).createSnapshot(); ItemStackSnapshot replacement = ((ItemStack) itemStack).createSnapshot(); transaction = new Transaction<>(original, replacement); } else { transaction = new Transaction<>(ItemStackSnapshot.NONE, ItemStackSnapshot.NONE); } FishingEvent.Stop event = SpongeEventFactory.createFishingEventStop( Cause.of(NamedCause.source(this.angler)), exp, exp, fishHookSnapshot, this, transaction, (Player) this.angler); if (!SpongeImpl.postEvent(event)) { // Sponge end if (this.caughtEntity != null) { double d0 = this.angler.posX - this.posX; double d2 = this.angler.posY - this.posY; double d4 = this.angler.posZ - this.posZ; double d6 = (double) MathHelper.sqrt_double(d0 * d0 + d2 * d2 + d4 * d4); double d8 = 0.1D; this.caughtEntity.motionX += d0 * d8; this.caughtEntity.motionY += d2 * d8 + (double) MathHelper.sqrt_double(d6) * 0.08D; this.caughtEntity.motionZ += d4 * d8; b0 = 3; } // Sponge Start if (!event.getItemStackTransaction().getFinal().getType().equals(ItemTypes.NONE)) { ItemStackSnapshot itemSnapshot = event.getItemStackTransaction().getFinal(); EntityItem entityitem1 = new EntityItem( this.worldObj, this.posX, this.posY, this.posZ, (net.minecraft.item.ItemStack) itemSnapshot.createStack()); double d1 = this.angler.posX - this.posX; double d3 = this.angler.posY - this.posY; double d5 = this.angler.posZ - this.posZ; double d7 = MathHelper.sqrt_double(d1 * d1 + d3 * d3 + d5 * d5); double d9 = 0.1D; entityitem1.motionX = d1 * d9; entityitem1.motionY = d3 * d9 + MathHelper.sqrt_double(d7) * 0.08D; entityitem1.motionZ = d5 * d9; this.worldObj.spawnEntityInWorld(entityitem1); this.angler.worldObj.spawnEntityInWorld( new EntityXPOrb( this.angler.worldObj, this.angler.posX, this.angler.posY + 0.5D, this.angler.posZ + 0.5D, event.getExperience())); // Sponge End b0 = 1; } if (this.inGround) { b0 = 2; } this.setDead(); this.angler.fishEntity = null; // Sponge Start if (this.fishingRod != null) { this.fishingRod.damageItem(b0, this.angler); this.angler.swingItem(); this.fishingRod = null; } // Sponge End } return b0; }
public static Optional<List<Tuple<DamageModifier, Function<? super Double, Double>>>> createArmorModifiers( EntityLivingBase entityLivingBase, DamageSource damageSource, double damage) { if (!damageSource.isDamageAbsolute()) { damage *= 25; net.minecraft.item.ItemStack[] inventory = entityLivingBase instanceof EntityPlayer ? ((EntityPlayer) entityLivingBase).inventory.armorInventory : entityLivingBase.getInventory(); List<Tuple<DamageModifier, Function<? super Double, Double>>> modifiers = new ArrayList<>(); List<DamageObject> damageObjects = new ArrayList<>(); for (int index = 0; index < inventory.length; index++) { net.minecraft.item.ItemStack itemStack = inventory[index]; if (itemStack == null) { continue; } Item item = itemStack.getItem(); if (item instanceof ItemArmor) { ItemArmor armor = (ItemArmor) item; double reduction = armor.damageReduceAmount / 25D; DamageObject object = new DamageObject(); object.slot = index; object.ratio = reduction; damageObjects.add(object); } } boolean first = true; double ratio = 0; for (DamageObject prop : damageObjects) { EquipmentType type = resolveEquipment(prop.slot); final DamageObject object = new DamageObject(); object.ratio = ratio; if (first) { object.previousDamage = damage; object.augment = true; } Function<? super Double, Double> function = incomingDamage -> { incomingDamage *= 25; if (object.augment) { // This is the damage that needs to be archived for the "first" armor modifier // function since the armor modifiers work based on the initial damage and not as // a chain one after another. damageToHandle = incomingDamage; } double functionDamage = damageToHandle; object.previousDamage = functionDamage; object.ratio = prop.ratio; object.ratio += prop.ratio; return -((functionDamage * prop.ratio) / 25); }; ratio += prop.ratio; DamageModifier modifier = DamageModifier.builder() .cause( Cause.of( NamedCause.of( DamageEntityEvent.GENERAL_ARMOR + ":" + type.getId(), ((org.spongepowered.api.item.inventory.ItemStack) inventory[prop.slot]) .createSnapshot()), NamedCause.of( "ArmorProperty", prop), // We need this property to refer to the slot. NamedCause.of("0xDEADBEEF", object))) // We need this object later on. .type(DamageModifierTypes.ARMOR) .build(); modifiers.add(new Tuple<>(modifier, function)); first = false; } if (modifiers.isEmpty()) { return Optional.empty(); } else { return Optional.of(modifiers); } } return Optional.empty(); }
public static Optional<List<Tuple<DamageModifier, Function<? super Double, Double>>>> createEnchantmentModifiers(EntityLivingBase entityLivingBase, DamageSource damageSource) { net.minecraft.item.ItemStack[] inventory = entityLivingBase instanceof EntityPlayer ? ((EntityPlayer) entityLivingBase).inventory.armorInventory : entityLivingBase.getInventory(); if (EnchantmentHelper.getEnchantmentModifierDamage(inventory, damageSource) == 0) { return Optional.empty(); } List<Tuple<DamageModifier, Function<? super Double, Double>>> modifiers = new ArrayList<>(); boolean first = true; int totalModifier = 0; for (net.minecraft.item.ItemStack itemStack : inventory) { if (itemStack == null) { continue; } NBTTagList enchantmentList = itemStack.getEnchantmentTagList(); if (enchantmentList == null) { continue; } for (int i = 0; i < enchantmentList.tagCount(); ++i) { final short enchantmentId = enchantmentList.getCompoundTagAt(i).getShort(NbtDataUtil.ITEM_ENCHANTMENT_ID); final short level = enchantmentList.getCompoundTagAt(i).getShort(NbtDataUtil.ITEM_ENCHANTMENT_LEVEL); if (Enchantment.getEnchantmentById(enchantmentId) != null) { // Ok, we have an enchantment! final Enchantment enchantment = Enchantment.getEnchantmentById(enchantmentId); final int temp = enchantment.calcModifierDamage(level, damageSource); if (temp != 0) { ItemStackSnapshot snapshot = ((ItemStack) itemStack).createSnapshot(); // Now we can actually consider this as a modifier! final DamageObject object = new DamageObject(); int modifier = enchantment.calcModifierDamage(level, damageSource); object.previousDamage = totalModifier; if (object.previousDamage > 25) { object.previousDamage = 25; } totalModifier += modifier; object.augment = first; object.ratio = modifier; Function<? super Double, Double> enchantmentFunction = damageIn -> { if (object.augment) { enchantmentDamageTracked = damageIn; } if (damageIn <= 0) { return 0D; } double actualDamage = enchantmentDamageTracked; if (object.previousDamage > 25) { return 0D; } double modifierDamage = actualDamage; double magicModifier; if (modifier > 0 && modifier <= 20) { int j = 25 - modifier; magicModifier = modifierDamage * (float) j; modifierDamage = magicModifier / 25.0F; } return -Math.max(actualDamage - modifierDamage, 0.0D); }; if (first) { first = false; } DamageModifier enchantmentModifier = DamageModifier.builder() .cause( Cause.of( NamedCause.of("ArmorEnchantment", enchantment), NamedCause.of("ItemStack", snapshot), NamedCause.of(DamageEntityEvent.SOURCE, entityLivingBase))) .type(DamageModifierTypes.ARMOR_ENCHANTMENT) .build(); modifiers.add(new Tuple<>(enchantmentModifier, enchantmentFunction)); } } } } if (!modifiers.isEmpty()) { return Optional.of(modifiers); } else { return Optional.empty(); } }