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();
}
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;
}
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;
}
Aggregations