Search in sources :

Example 1 with EventContextKey

use of org.spongepowered.api.event.cause.EventContextKey in project SpongeForge by SpongePowered.

the class StaticMixinForgeHelper method createArmorModifiers.

private static Optional<List<DamageFunction>> createArmorModifiers(List<ISpecialArmor.ArmorProperties> dmgVals, List<ItemStack> inventory, double damage) {
    if (dmgVals.size() > 0) {
        final List<DamageFunction> list = new ArrayList<>();
        ISpecialArmor.ArmorProperties[] props = dmgVals.toArray(new ISpecialArmor.ArmorProperties[dmgVals.size()]);
        sortProperties(props, damage);
        boolean first = true;
        int level = props[0].Priority;
        double ratio = 0;
        for (ISpecialArmor.ArmorProperties prop : props) {
            EquipmentType type = DamageEventHandler.resolveEquipment(prop.Slot);
            final DamageEventObject object = new DamageEventObject();
            object.previousLevel = prop.Priority;
            object.previousRatio = ratio;
            if (first) {
                object.previousDamage = damage;
                object.augment = true;
            }
            DoubleUnaryOperator function = incomingDamage -> {
                incomingDamage *= 25;
                if (object.augment) {
                    damageToHandle = incomingDamage;
                }
                double functionDamage = damageToHandle;
                object.previousDamage = functionDamage;
                object.level = prop.Priority;
                object.ratio = prop.AbsorbRatio;
                if (object.previousLevel != prop.Priority) {
                    functionDamage -= (functionDamage * object.previousRatio);
                    damageToHandle = functionDamage;
                    object.ratio = 0;
                    object.level = prop.Priority;
                }
                object.ratio += prop.AbsorbRatio;
                return -((functionDamage * prop.AbsorbRatio) / 25);
            };
            // We still need to "simulate" the original function so that the ratios are handled
            if (level != prop.Priority) {
                damage -= (damage * ratio);
                ratio = 0;
                level = prop.Priority;
            }
            ratio += prop.AbsorbRatio;
            EventContextKey<ItemStackSnapshot> contextKey = ARMOR_KEYS.get("armor:" + type.getId());
            if (contextKey == null) {
                contextKey = new EventContextKey<ItemStackSnapshot>() {

                    @Override
                    public Class<ItemStackSnapshot> getAllowedType() {
                        return ItemStackSnapshot.class;
                    }

                    @Override
                    public String getId() {
                        return "armor:" + type.getId();
                    }

                    @Override
                    public String getName() {
                        return type.getName();
                    }
                };
                ARMOR_KEYS.put("armor: " + type.getId(), contextKey);
            }
            final ItemStack itemStack = inventory.get(prop.Slot);
            DamageModifier modifier = DamageModifier.builder().cause(Cause.of(EventContext.builder().add(contextKey, ItemStackUtil.snapshotOf(itemStack)).add(ARMOR_PROPERTY, prop).add(DAMAGE_MODIFIER_OBJECT, object).build(), itemStack)).type(DamageModifierTypes.ARMOR).build();
            list.add(DamageFunction.of(modifier, function));
            first = false;
        }
        return Optional.of(list);
    }
    return Optional.empty();
}
Also used : SpongeEntityType(org.spongepowered.common.entity.SpongeEntityType) Arrays(java.util.Arrays) Loader(net.minecraftforge.fml.common.Loader) EntityEntry(net.minecraftforge.fml.common.registry.EntityEntry) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) DamageModifierTypes(org.spongepowered.api.event.cause.entity.damage.DamageModifierTypes) ItemStackUtil(org.spongepowered.common.item.inventory.util.ItemStackUtil) DoubleUnaryOperator(java.util.function.DoubleUnaryOperator) ArrayList(java.util.ArrayList) ItemStack(net.minecraft.item.ItemStack) Lists(com.google.common.collect.Lists) Map(java.util.Map) NonNullList(net.minecraft.util.NonNullList) EventContextKey(org.spongepowered.api.event.cause.EventContextKey) ItemArmor(net.minecraft.item.ItemArmor) Nullable(javax.annotation.Nullable) Entity(net.minecraft.entity.Entity) EquipmentType(org.spongepowered.api.item.inventory.equipment.EquipmentType) EntityList(net.minecraft.entity.EntityList) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) SpongeMod(org.spongepowered.mod.SpongeMod) EntityTypeRegistryModule(org.spongepowered.common.registry.type.entity.EntityTypeRegistryModule) DamageSource(net.minecraft.util.DamageSource) ISpecialArmor(net.minecraftforge.common.ISpecialArmor) IBlockState(net.minecraft.block.state.IBlockState) DamageEventHandler(org.spongepowered.common.event.damage.DamageEventHandler) Cause(org.spongepowered.api.event.cause.Cause) List(java.util.List) DamageFunction(org.spongepowered.api.event.cause.entity.damage.DamageFunction) DamageModifier(org.spongepowered.api.event.cause.entity.damage.DamageModifier) EntityLivingBase(net.minecraft.entity.EntityLivingBase) EntityPlayer(net.minecraft.entity.player.EntityPlayer) Optional(java.util.Optional) ModContainer(net.minecraftforge.fml.common.ModContainer) EventContext(org.spongepowered.api.event.cause.EventContext) ArrayList(java.util.ArrayList) EquipmentType(org.spongepowered.api.item.inventory.equipment.EquipmentType) ISpecialArmor(net.minecraftforge.common.ISpecialArmor) DamageModifier(org.spongepowered.api.event.cause.entity.damage.DamageModifier) DamageFunction(org.spongepowered.api.event.cause.entity.damage.DamageFunction) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) ItemStack(net.minecraft.item.ItemStack) DoubleUnaryOperator(java.util.function.DoubleUnaryOperator)

Example 2 with EventContextKey

use of org.spongepowered.api.event.cause.EventContextKey in project LanternServer by LanternPowered.

the class LanternCauseStack method popCauseFrame.

@Override
public void popCauseFrame(StackFrame oldFrame) {
    checkNotNull(oldFrame, "oldFrame");
    final CauseStackFrameImpl frame = this.frames.peek();
    if (frame != oldFrame) {
        if (frame.stack != this) {
            throw new IllegalStateException("Cause Stack Frame Corruption! Attempted to pop a frame from a different stack.");
        }
        // If the given frame is not the top frame then some form of
        // corruption of the stack has occurred and we do our best to correct
        // it.
        // If the target frame is still in the stack then we can pop frames
        // off the stack until we reach it, otherwise we have no choice but
        // to simply throw an error.
        int offset = -1;
        int i = 0;
        for (CauseStackFrameImpl f : this.frames) {
            if (f == oldFrame) {
                offset = i;
                break;
            }
            i++;
        }
        final String name = Thread.currentThread().getName();
        if (!DEBUG_CAUSE_FRAMES && offset == -1) {
            // that was erroneously popped.
            throw new IllegalStateException("Cause Stack Frame Corruption on the Thread \"" + name + "\"! Attempted to pop a frame that was not on the stack.");
        }
        final PrettyPrinter printer = new PrettyPrinter(100).add("Cause Stack Frame Corruption on the Thread \"%s\"!", name).centre().hr().add("Found %d frames left on the stack. Clearing them all.", new Object[] { offset + 1 });
        if (!DEBUG_CAUSE_FRAMES) {
            printer.add().add("Please add -Dsponge.debugcauseframes=true to your startup flags to enable further debugging output.");
            Lantern.getLogger().warn("  Add -Dsponge.debugcauseframes=true to your startup flags to enable further debugging output.");
        } else {
            printer.add();
            printer.add("> Attempting to pop frame:");
            printStack(printer, frame.debugStack);
            printer.add();
            printer.add("> Frames being popped are:");
            printStack(printer, ((CauseStackFrameImpl) oldFrame).debugStack);
        }
        while (offset >= 0) {
            CauseStackFrameImpl f = this.frames.peek();
            if (DEBUG_CAUSE_FRAMES && offset > 0) {
                printer.add();
                printer.add(String.format("> Stack frame in position %s:", offset));
                printStack(printer, f.debugStack);
            }
            popCauseFrame(f);
            offset--;
        }
        printer.trace(System.err);
        if (offset == -1) {
            // so we throw an exception.
            throw new IllegalStateException("Cause Stack Frame Corruption! Attempted to pop a frame that was not on the stack.");
        }
        return;
    }
    this.frames.pop();
    // Remove new values
    boolean ctxInvalid = false;
    if (frame.hasNew()) {
        frame.getNew().forEach(this.ctx::remove);
        ctxInvalid = true;
    }
    // Restore old values
    if (frame.hasStoredValues()) {
        for (Map.Entry<EventContextKey<?>, Object> e : frame.getStoredValues()) {
            this.ctx.put(e.getKey(), e.getValue());
        }
        ctxInvalid = true;
    }
    if (ctxInvalid) {
        this.cachedCtx = null;
    }
    // If there were any objects left on the stack then we pop them off
    while (this.cause.size() > this.minDepth) {
        this.cause.pop();
    }
    this.minDepth = frame.oldMinDepth;
}
Also used : PrettyPrinter(org.lanternpowered.server.util.PrettyPrinter) EventContextKey(org.spongepowered.api.event.cause.EventContextKey) HashMap(java.util.HashMap) Map(java.util.Map)

Example 3 with EventContextKey

use of org.spongepowered.api.event.cause.EventContextKey in project SpongeCommon by SpongePowered.

the class SpongeCauseStackManager method popCauseFrame.

@Override
public void popCauseFrame(StackFrame oldFrame) {
    enforceMainThread();
    checkNotNull(oldFrame, "oldFrame");
    CauseStackFrameImpl frame = this.frames.peek();
    if (frame != oldFrame) {
        // If the given frame is not the top frame then some form of
        // corruption of the stack has occured and we do our best to correct
        // it.
        // If the target frame is still in the stack then we can pop frames
        // off the stack until we reach it, otherwise we have no choice but
        // to simply throw an error.
        int offset = -1;
        int i = 0;
        for (CauseStackFrameImpl f : this.frames) {
            if (f == oldFrame) {
                offset = i;
                break;
            }
            i++;
        }
        if (!DEBUG_CAUSE_FRAMES && offset == -1) {
            // that was erroneously popped.
            throw new IllegalStateException("Cause Stack Frame Corruption! Attempted to pop a frame that was not on the stack.");
        }
        final PrettyPrinter printer = new PrettyPrinter(100).add("Cause Stack Frame Corruption!").centre().hr().add("Found %d frames left on the stack. Clearing them all.", new Object[] { offset + 1 });
        if (!DEBUG_CAUSE_FRAMES) {
            printer.add().add("Please add -Dsponge.debugcauseframes=true to your startup flags to enable further debugging output.");
            SpongeImpl.getLogger().warn("  Add -Dsponge.debugcauseframes to your startup flags to enable further debugging output.");
        } else {
            printer.add().add("Attempting to pop frame:").add(frame.stack_debug).add().add("Frames being popped are:").add(((CauseStackFrameImpl) oldFrame).stack_debug);
        }
        while (offset >= 0) {
            CauseStackFrameImpl f = this.frames.peek();
            if (DEBUG_CAUSE_FRAMES && offset > 0) {
                printer.add("   Stack frame in position %n:", offset);
                printer.add(f.stack_debug);
            }
            popCauseFrame(f);
            offset--;
        }
        printer.trace(System.err, SpongeImpl.getLogger(), Level.ERROR);
        if (offset == -1) {
            // so we throw an exception.
            throw new IllegalStateException("Cause Stack Frame Corruption! Attempted to pop a frame that was not on the stack.");
        }
        return;
    }
    this.frames.pop();
    // Remove new values
    boolean ctx_invalid = false;
    if (frame.hasNew()) {
        for (EventContextKey<?> key : frame.getNew()) {
            this.ctx.remove(key);
        }
        ctx_invalid = true;
    }
    // Restore old values
    if (frame.hasStoredValues()) {
        for (Map.Entry<EventContextKey<?>, Object> e : frame.getStoredValues()) {
            this.ctx.put(e.getKey(), e.getValue());
        }
        ctx_invalid = true;
    }
    if (ctx_invalid) {
        this.cached_ctx = null;
    }
    // If there were any objects left on the stack then we pop them off
    while (this.cause.size() > this.min_depth) {
        this.cause.pop();
        // and clear the cached causes
        this.cached_cause = null;
    }
    this.min_depth = frame.old_min_depth;
}
Also used : PrettyPrinter(org.spongepowered.asm.util.PrettyPrinter) EventContextKey(org.spongepowered.api.event.cause.EventContextKey) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

Map (java.util.Map)3 EventContextKey (org.spongepowered.api.event.cause.EventContextKey)3 HashMap (java.util.HashMap)2 Lists (com.google.common.collect.Lists)1 ArrayList (java.util.ArrayList)1 Arrays (java.util.Arrays)1 List (java.util.List)1 Optional (java.util.Optional)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 DoubleUnaryOperator (java.util.function.DoubleUnaryOperator)1 Nullable (javax.annotation.Nullable)1 IBlockState (net.minecraft.block.state.IBlockState)1 Entity (net.minecraft.entity.Entity)1 EntityList (net.minecraft.entity.EntityList)1 EntityLivingBase (net.minecraft.entity.EntityLivingBase)1 EntityPlayer (net.minecraft.entity.player.EntityPlayer)1 ItemArmor (net.minecraft.item.ItemArmor)1 ItemStack (net.minecraft.item.ItemStack)1 DamageSource (net.minecraft.util.DamageSource)1 NonNullList (net.minecraft.util.NonNullList)1