use of org.spongepowered.api.event.Cause in project SpongeCommon by SpongePowered.
the class EnderMan_EndermanLeaveBlockGoalMixin method impl$onPlaceBlockCancel.
/**
* @reason Makes Endermen check for block changes before they can place their blocks.
* This allows plugins to cancel the event regardless without issue.
*/
@Redirect(method = "canPlaceBlock(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;isCollisionShapeFullBlock(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Z"))
private boolean impl$onPlaceBlockCancel(BlockState blockState, BlockGetter blockReaderIn, BlockPos blockPosIn) {
if (blockState.isCollisionShapeFullBlock(blockReaderIn, blockPosIn)) {
// Sponge start
if (ShouldFire.CHANGE_BLOCK_EVENT_PRE) {
final ServerLocation location = ServerLocation.of((ServerWorld) blockReaderIn, blockPosIn.getX(), blockPosIn.getY(), blockPosIn.getZ());
final List<ServerLocation> list = new ArrayList<>(1);
list.add(location);
final Cause cause = PhaseTracker.getCauseStackManager().currentCause();
final ChangeBlockEvent.Pre event = SpongeEventFactory.createChangeBlockEventPre(cause, list, ((ServerWorld) this.enderman.level));
return !SpongeCommon.post(event);
}
// Sponge end
return true;
}
return false;
}
use of org.spongepowered.api.event.Cause in project SpongeCommon by SpongePowered.
the class SpongeCommandCauseFactory method create.
@Override
@NonNull
public CommandCause create() {
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
final Cause cause = frame.currentCause();
final CommandSource iCommandSource = cause.first(CommandSource.class).orElseGet(() -> SpongeCommon.game().systemSubject());
final CommandSourceStack commandSource;
if (iCommandSource instanceof CommandSourceProviderBridge) {
// We know about this one so we can create it using the factory method on the source.
commandSource = ((CommandSourceProviderBridge) iCommandSource).bridge$getCommandSource(cause);
} else {
// try to create a command cause from the given ICommandSource, but as Mojang did not see fit to
// put any identifying characteristics on the object, we have to go it alone...
final EventContext context = cause.context();
@Nullable final Locatable locatable = iCommandSource instanceof Locatable ? (Locatable) iCommandSource : null;
final Component displayName;
if (iCommandSource instanceof Entity) {
displayName = ((Entity) iCommandSource).get(Keys.DISPLAY_NAME).map(SpongeAdventure::asVanilla).orElseGet(() -> new TextComponent(iCommandSource instanceof Nameable ? ((Nameable) iCommandSource).name() : iCommandSource.getClass().getSimpleName()));
} else {
displayName = new TextComponent(iCommandSource instanceof Nameable ? ((Nameable) iCommandSource).name() : iCommandSource.getClass().getSimpleName());
}
final String name = displayName.getString();
commandSource = new CommandSourceStack(iCommandSource, context.get(EventContextKeys.LOCATION).map(x -> VecHelper.toVanillaVector3d(x.position())).orElseGet(() -> locatable == null ? Vec3.ZERO : VecHelper.toVanillaVector3d(locatable.location().position())), context.get(EventContextKeys.ROTATION).map(rot -> new Vec2((float) rot.x(), (float) rot.y())).orElse(Vec2.ZERO), context.get(EventContextKeys.LOCATION).map(x -> (ServerLevel) x.world()).orElseGet(() -> locatable == null ? SpongeCommon.server().getLevel(Level.OVERWORLD) : (ServerLevel) locatable.serverLocation().world()), 4, name, displayName, SpongeCommon.server(), iCommandSource instanceof Entity ? (net.minecraft.world.entity.Entity) iCommandSource : null);
}
// We don't want the command source to have altered the cause here (unless there is the special case of the
// server), so we reset it back to what it was (in the ctor of CommandSource, it will add the current source
// to the cause - that's for if the source is created elsewhere, not here)
((CommandSourceStackBridge) commandSource).bridge$setCause(frame.currentCause());
return (CommandCause) commandSource;
}
}
use of org.spongepowered.api.event.Cause in project SpongeCommon by SpongePowered.
the class SpongeCommandManager method prettyPrintThrowableError.
private void prettyPrintThrowableError(final Throwable thr, final String commandNoArgs, final String args, final CommandCause cause) {
final String commandString;
if (args != null && !args.isEmpty()) {
commandString = commandNoArgs + " " + args;
} else {
commandString = commandNoArgs;
}
final SpongeCommandMapping mapping = this.commandMappings.get(commandNoArgs.toLowerCase());
final PrettyPrinter prettyPrinter = new PrettyPrinter(100).add("Unexpected error occurred while executing command '%s'", commandString).centre().hr().addWrapped("While trying to run '%s', an error occurred that the command processor was not expecting. " + "This usually indicates an error in the plugin that owns this command. Report this error " + "to the plugin developer first - this is usually not a Sponge error.", commandString).hr().add().add("Command: %s", commandString).add("Owning Plugin: %s", mapping.plugin().map(x -> x.metadata().id()).orElse("unknown")).add("Owning Registrar: %s", mapping.registrar().getClass().getName()).add().add("Exception Details: ");
if (thr instanceof SpongeCommandSyntaxException) {
// we know the inner exception was wrapped by us.
prettyPrinter.add(thr.getCause());
} else {
prettyPrinter.add(thr);
}
prettyPrinter.add().add("CommandCause details: ").addWrapped(cause.cause().toString()).log(SpongeCommon.logger(), Level.ERROR);
}
use of org.spongepowered.api.event.Cause in project SpongeCommon by SpongePowered.
the class SpongeScoreCriterionProgress method set.
@Override
public Optional<Instant> set(final int score) {
checkState(score >= 0 && score <= this.goal(), "Score cannot be negative or greater than the goal.");
int lastScore = this.score();
if (lastScore == score) {
return this.get();
}
final CriterionEvent.Score.Change event;
final Cause cause = PhaseTracker.getCauseStackManager().currentCause();
final Advancement advancement = this.progress.advancement();
final ServerPlayer player = ((PlayerAdvancementsBridge) ((AdvancementProgressBridge) this.progress).bridge$getPlayerAdvancements()).bridge$getPlayer();
if (lastScore == this.goal()) {
event = SpongeEventFactory.createCriterionEventScoreRevoke(cause, advancement, this.criterion(), player, lastScore, score);
} else if (score == this.goal()) {
event = SpongeEventFactory.createCriterionEventScoreGrant(cause, advancement, this.criterion(), player, Instant.now(), lastScore, score);
} else {
event = SpongeEventFactory.createCriterionEventScoreChange(cause, advancement, this.criterion(), player, lastScore, score);
}
if (SpongeCommon.post(event)) {
return this.get();
}
SpongeScoreCriterion.BYPASS_EVENT = true;
// This is the only case a instant will be returned
if (score == this.goal()) {
Instant instant = null;
for (final AdvancementCriterion criterion : this.criterion.internalCriteria) {
final org.spongepowered.api.advancement.criteria.CriterionProgress progress = this.progress.get(criterion).get();
if (!progress.achieved()) {
instant = progress.grant();
}
}
this.score = score;
return Optional.of(instant == null ? Instant.now() : instant);
}
for (final AdvancementCriterion criterion : this.criterion.internalCriteria) {
final org.spongepowered.api.advancement.criteria.CriterionProgress progress = this.progress.get(criterion).get();
// We don't have enough score, grant more criteria
if (lastScore < score && !progress.achieved()) {
progress.grant();
lastScore++;
// We have too much score, revoke more criteria
} else if (lastScore > score && progress.achieved()) {
progress.revoke();
lastScore--;
}
// We reached the target score
if (lastScore == score) {
break;
}
}
this.score = score;
SpongeScoreCriterion.BYPASS_EVENT = false;
return Optional.empty();
}
use of org.spongepowered.api.event.Cause in project SpongeCommon by SpongePowered.
the class SpongeCriterionTrigger method bridge$trigger.
@Override
public void bridge$trigger(final ServerPlayer player) {
final PlayerAdvancements playerAdvancements = ((net.minecraft.server.level.ServerPlayer) player).getAdvancements();
final Cause cause = PhaseTracker.getCauseStackManager().currentCause();
// correct type verified in builder
@SuppressWarnings("unchecked") final TypeToken<FilteredTriggerConfiguration> typeToken = (TypeToken<FilteredTriggerConfiguration>) TypeToken.get(this.triggerConfigurationType);
for (final Listener listener : new ArrayList<>(this.listeners.get(playerAdvancements))) {
final CriterionTrigger_ListenerAccessor mixinListener = (CriterionTrigger_ListenerAccessor) listener;
final Advancement advancement = (Advancement) mixinListener.accessor$advancement();
final AdvancementCriterion advancementCriterion = (AdvancementCriterion) ((net.minecraft.advancements.Advancement) advancement).getCriteria().get(mixinListener.accessor$criterion());
final CriterionEvent.Trigger event = SpongeEventFactory.createCriterionEventTrigger(cause, advancement, advancementCriterion, typeToken, player, (FilteredTrigger) listener.getTriggerInstance(), this.eventHandler == null);
if (this.eventHandler != null) {
this.eventHandler.accept(event);
if (!event.result()) {
continue;
}
}
SpongeCommon.post(event);
if (event.result()) {
listener.run(playerAdvancements);
}
}
}
Aggregations