use of net.minecraft.world.item.ItemStack in project SpongeCommon by SpongePowered.
the class LivingEntityMixin method bridge$damageEntity.
@Override
public boolean bridge$damageEntity(final DamageSource damageSource, float damage) {
if (this.shadow$isInvulnerableTo(damageSource)) {
return false;
}
final boolean isHuman = (LivingEntity) (Object) this instanceof Player;
// Sponge Start - Call platform hook for adjusting damage
damage = this.bridge$applyModDamage((LivingEntity) (Object) this, damageSource, damage);
// Sponge End
final float originalDamage = damage;
if (damage <= 0) {
return false;
}
final List<DamageFunction> originalFunctions = new ArrayList<>();
final Optional<DamageFunction> hardHatFunction = DamageEventUtil.createHardHatModifier((LivingEntity) (Object) this, damageSource);
final Optional<DamageFunction> armorFunction = DamageEventUtil.createArmorModifiers((LivingEntity) (Object) this, damageSource);
final Optional<DamageFunction> resistanceFunction = DamageEventUtil.createResistanceModifier((LivingEntity) (Object) this, damageSource);
final Optional<List<DamageFunction>> armorEnchantments = DamageEventUtil.createEnchantmentModifiers((LivingEntity) (Object) this, damageSource);
final Optional<DamageFunction> absorptionFunction = DamageEventUtil.createAbsorptionModifier((LivingEntity) (Object) this);
final Optional<DamageFunction> shieldFunction = DamageEventUtil.createShieldFunction((LivingEntity) (Object) this, damageSource, damage);
hardHatFunction.ifPresent(originalFunctions::add);
shieldFunction.ifPresent(originalFunctions::add);
armorFunction.ifPresent(originalFunctions::add);
resistanceFunction.ifPresent(originalFunctions::add);
armorEnchantments.ifPresent(originalFunctions::addAll);
absorptionFunction.ifPresent(originalFunctions::add);
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
DamageEventUtil.generateCauseFor(damageSource, frame);
final DamageEntityEvent event = SpongeEventFactory.createDamageEntityEvent(frame.currentCause(), (org.spongepowered.api.entity.Entity) this, originalFunctions, originalDamage);
if (damageSource != SpongeDamageSources.IGNORED) {
// Basically, don't throw an event if it's our own damage source
SpongeCommon.post(event);
}
if (event.isCancelled()) {
return false;
}
damage = (float) event.finalDamage();
// Sponge Start - Allow the platform to adjust damage before applying armor/etc
damage = this.bridge$applyModDamageBeforeFunctions((LivingEntity) (Object) this, damageSource, damage);
// Sponge End
// Helmet
final ItemStack helmet = this.shadow$getItemBySlot(EquipmentSlot.HEAD);
// without using our mixin redirects in EntityFallingBlockMixin.
if ((damageSource instanceof FallingBlockDamageSource) || damageSource == DamageSource.ANVIL || damageSource == DamageSource.FALLING_BLOCK && !helmet.isEmpty()) {
helmet.hurtAndBreak((int) (event.baseDamage() * 4.0F + this.random.nextFloat() * event.baseDamage() * 2.0F), (LivingEntity) (Object) this, (entity) -> entity.broadcastBreakEvent(EquipmentSlot.HEAD));
}
boolean hurtStack = false;
// Shield
if (shieldFunction.isPresent()) {
this.shadow$hurtCurrentlyUsedShield((float) event.baseDamage());
hurtStack = true;
if (!damageSource.isProjectile()) {
final Entity entity = damageSource.getDirectEntity();
if (entity instanceof LivingEntity) {
this.shadow$blockUsingShield((LivingEntity) entity);
}
}
}
// Armor
if (!damageSource.isBypassArmor() && armorFunction.isPresent()) {
this.shadow$hurtArmor(damageSource, (float) event.baseDamage());
hurtStack = true;
}
// Sponge start - log inventory change due to taking damage
if (hurtStack && isHuman) {
PhaseTracker.SERVER.getPhaseContext().getTransactor().logPlayerInventoryChange((Player) (Object) this, PlayerInventoryTransaction.EventCreator.STANDARD);
// capture
((Player) (Object) this).inventoryMenu.broadcastChanges();
}
// Resistance modifier post calculation
if (resistanceFunction.isPresent()) {
final float f2 = (float) event.damage(resistanceFunction.get().modifier()) - damage;
if (f2 > 0.0F && f2 < 3.4028235E37F) {
if (((LivingEntity) (Object) this) instanceof net.minecraft.server.level.ServerPlayer) {
((net.minecraft.server.level.ServerPlayer) ((LivingEntity) (Object) this)).awardStat(Stats.DAMAGE_RESISTED, Math.round(f2 * 10.0F));
} else if (damageSource.getEntity() instanceof net.minecraft.server.level.ServerPlayer) {
((net.minecraft.server.level.ServerPlayer) damageSource.getEntity()).awardStat(Stats.DAMAGE_DEALT_RESISTED, Math.round(f2 * 10.0F));
}
}
}
double absorptionModifier = absorptionFunction.map(function -> event.damage(function.modifier())).orElse(0d);
if (absorptionFunction.isPresent()) {
absorptionModifier = event.damage(absorptionFunction.get().modifier());
}
final float f = (float) event.finalDamage() - (float) absorptionModifier;
this.shadow$setAbsorptionAmount(Math.max(this.shadow$getAbsorptionAmount() + (float) absorptionModifier, 0.0F));
if (f > 0.0F && f < 3.4028235E37F && ((LivingEntity) (Object) this) instanceof net.minecraft.server.level.ServerPlayer) {
((Player) (Object) this).awardStat(Stats.DAMAGE_DEALT_ABSORBED, Math.round(f * 10.0F));
}
if (damage != 0.0F) {
if (isHuman) {
((Player) (Object) this).causeFoodExhaustion(damageSource.getFoodExhaustion());
}
final float f2 = this.shadow$getHealth();
this.shadow$setHealth(f2 - damage);
this.shadow$getCombatTracker().recordDamage(damageSource, f2, damage);
if (isHuman) {
if (damage < 3.4028235E37F) {
((Player) (Object) this).awardStat(Stats.DAMAGE_TAKEN, Math.round(damage * 10.0F));
}
return true;
}
this.shadow$setAbsorptionAmount(this.shadow$getAbsorptionAmount() - damage);
}
return true;
}
}
use of net.minecraft.world.item.ItemStack in project SpongeCommon by SpongePowered.
the class OcelotMixin method impl$ThrowTameEvent.
@Redirect(method = "mobInteract", at = @At(value = "INVOKE", target = "Ljava/util/Random;nextInt(I)I", ordinal = 0, remap = false))
private int impl$ThrowTameEvent(Random rand, int bound, Player player, InteractionHand hand) {
ItemStack stack = player.getItemInHand(hand);
int random = rand.nextInt(bound);
if (random == 0) {
stack.setCount(stack.getCount() + 1);
try (CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
frame.pushCause(player);
if (!SpongeCommon.post(SpongeEventFactory.createTameEntityEvent(frame.currentCause(), (Ocelot) this))) {
stack.setCount(stack.getCount() - 1);
return random;
}
}
}
return 1;
}
use of net.minecraft.world.item.ItemStack in project SpongeCommon by SpongePowered.
the class LivingEntityMixin_Inventory method inventory$onHandleEquipmentChanges.
@Inject(method = "handleEquipmentChanges", at = @At(value = "INVOKE", remap = false, target = "Ljava/util/Map;forEach(Ljava/util/function/BiConsumer;)V"))
protected void inventory$onHandleEquipmentChanges(final Map<EquipmentSlot, ItemStack> map, final CallbackInfo ci) {
map.entrySet().removeIf(entry -> {
final Slot slotAdapter = this.impl$getSpongeSlot(entry.getKey());
ItemStack oldStack = null;
switch(entry.getKey().getType()) {
case HAND:
oldStack = this.shadow$getLastHandItem(entry.getKey());
break;
case ARMOR:
oldStack = this.shadow$getLastArmorItem(entry.getKey());
break;
}
return this.impl$throwEquipmentEvent(entry.getKey(), slotAdapter, entry.getValue(), oldStack);
});
}
use of net.minecraft.world.item.ItemStack in project SpongeCommon by SpongePowered.
the class ServerGamePacketListenerImplMixin_Inventory method impl$onBroadcastCreativeActionResult.
@Redirect(method = "handleSetCreativeModeSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/InventoryMenu;broadcastChanges()V"))
private void impl$onBroadcastCreativeActionResult(final InventoryMenu inventoryMenu, final ServerboundSetCreativeModeSlotPacket packetIn) {
final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext();
final TransactionalCaptureSupplier transactor = context.getTransactor();
final ItemStack itemstack = packetIn.getItem();
// TODO handle vanilla sending a bunch of creative events (previously ignoring events within 100ms)
try (final EffectTransactor ignored = transactor.logCreativeClickContainer(packetIn.getSlotNum(), ItemStackUtil.snapshotOf(itemstack), this.player)) {
}
inventoryMenu.broadcastChanges();
}
use of net.minecraft.world.item.ItemStack in project SpongeCommon by SpongePowered.
the class ContainerMixin_Inventory_API method setCursor.
@Override
public boolean setCursor(org.spongepowered.api.item.inventory.ItemStack item) {
if (!this.isOpen()) {
return false;
}
ItemStack nativeStack = ItemStackUtil.toNative(item);
this.listeners().stream().findFirst().ifPresent(p -> p.inventory.setCarried(nativeStack));
return true;
}
Aggregations