<commit_before>/*
 * This file is part of Nucleus, licensed under the MIT License (MIT). See the LICENSE.txt file
 * at the root of this project for more details.
 */
package io.github.nucleuspowered.nucleus.modules.fun.commands;

import com.flowpowered.math.vector.Vector3d;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import io.github.nucleuspowered.nucleus.Util;
import io.github.nucleuspowered.nucleus.argumentparsers.SelectorWrapperArgument;
import io.github.nucleuspowered.nucleus.internal.annotations.Permissions;
import io.github.nucleuspowered.nucleus.internal.annotations.RegisterCommand;
import io.github.nucleuspowered.nucleus.internal.command.AbstractCommand;
import io.github.nucleuspowered.nucleus.internal.command.ReturnMessageException;
import io.github.nucleuspowered.nucleus.internal.messages.MessageProvider;
import io.github.nucleuspowered.nucleus.internal.permissions.PermissionInformation;
import io.github.nucleuspowered.nucleus.internal.permissions.SuggestedLevel;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandResult;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.command.args.CommandContext;
import org.spongepowered.api.command.args.CommandElement;
import org.spongepowered.api.command.args.GenericArguments;
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.data.type.OcelotType;
import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.entity.EntityTypes;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.cause.Cause;
import org.spongepowered.api.event.cause.NamedCause;
import org.spongepowered.api.event.cause.entity.spawn.SpawnCause;
import org.spongepowered.api.event.cause.entity.spawn.SpawnTypes;
import org.spongepowered.api.scheduler.Task;
import org.spongepowered.api.text.Text;
import org.spongepowered.api.world.World;
import org.spongepowered.api.world.explosion.Explosion;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.UUID;
import java.util.function.Consumer;

@Permissions(supportsSelectors = true, supportsOthers = true)
@RegisterCommand({"kittycannon", "kc"})
public class KittyCannonCommand extends AbstractCommand<CommandSource> {

    private final Random random = new Random();
    private final String playerKey = "player";
    private final List<OcelotType> ocelotTypes;

    @Override protected Map<String, PermissionInformation> permissionSuffixesToRegister() {
        return new HashMap<String, PermissionInformation>() {{
            MessageProvider provider = plugin.getMessageProvider();
            put("damage", new PermissionInformation(provider.getMessageWithFormat("permission.kittycannon.damage"), SuggestedLevel.ADMIN));
            put("break", new PermissionInformation(provider.getMessageWithFormat("permission.kittycannon.break"), SuggestedLevel.ADMIN));
            put("fire", new PermissionInformation(provider.getMessageWithFormat("permission.kittycannon.fire"), SuggestedLevel.ADMIN));
        }};
    }

    @Inject
    public KittyCannonCommand() {
        this.ocelotTypes = Lists.newArrayList(Sponge.getRegistry().getAllOf(OcelotType.class));
    }

    @Override public CommandElement[] getArguments() {
        return new CommandElement[] {
            GenericArguments.flags()
                .permissionFlag(permissions.getPermissionWithSuffix("damage"), "d", "-damageentities")
                .permissionFlag(permissions.getPermissionWithSuffix("break"), "b", "-breakblocks")
                .permissionFlag(permissions.getPermissionWithSuffix("fire"), "f", "-fire")
                .buildWith(
                    GenericArguments.optional(
                        GenericArguments.requiringPermission(
                            new SelectorWrapperArgument(GenericArguments.player(Text.of(playerKey)), permissions, SelectorWrapperArgument.ALL_SELECTORS),
                            permissions.getOthers())))
        };
    }

    @Override
    public CommandResult executeCommand(CommandSource src, CommandContext args) throws Exception {
        Collection<Player> playerList = args.getAll(playerKey);
        if (playerList.isEmpty()) {
            if (src instanceof Player) {
                playerList = Lists.newArrayList((Player)src);
            } else {
                throw new ReturnMessageException(plugin.getMessageProvider().getTextMessageWithFormat("command.playeronly"));
            }
        }

        // For each player, create a kitten, throw it out in the direction of the player, and make it explode after between 2 and 5 seconds
        playerList.forEach(x -> getACat(src, x, args.hasAny("d"), args.hasAny("b"), args.hasAny("f")));
        return CommandResult.success();
    }

    private void getACat(CommandSource source, Player spawnAt, boolean damageEntities, boolean breakBlocks, boolean causeFire) {
        // Fire it in the direction that the player is facing with a speed of 0.5 to 3.5, plus the player's current velocity.
        Vector3d velocity = spawnAt.getVelocity().add(
            Util.getDirectionFromRotation(spawnAt.getHeadRotation()).mul(2 * random.nextDouble() + 1));
        World world = spawnAt.getWorld();
        Entity cat = world.createEntity(EntityTypes.OCELOT, spawnAt.getLocation()
            .getPosition().add(0, 1, 0).add(spawnAt.getTransform().getRotationAsQuaternion().getDirection()));
        cat.offer(Keys.OCELOT_TYPE, ocelotTypes.get(random.nextInt(ocelotTypes.size())));

        Sponge.getScheduler().createTaskBuilder().intervalTicks(5).delayTicks(5)
            .execute(new CatTimer(world.getUniqueId(), cat.getUniqueId(), spawnAt, random.nextInt(60) + 20, damageEntities, breakBlocks, causeFire))
            .submit(plugin);

        world.spawnEntity(cat, Cause.of(NamedCause.owner(SpawnCause.builder().type(SpawnTypes.PLUGIN).build()), NamedCause.source(source)));
        cat.offer(Keys.VELOCITY, velocity);
    }

    private class CatTimer implements Consumer<Task> {<commit_msg>Make felines fly faster. Use Quaterions.<commit_after>/*
 * This file is part of Nucleus, licensed under the MIT License (MIT). See the LICENSE.txt file
 * at the root of this project for more details.
 */
package io.github.nucleuspowered.nucleus.modules.fun.commands;

import com.flowpowered.math.imaginary.Quaterniond;
import com.flowpowered.math.vector.Vector3d;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import io.github.nucleuspowered.nucleus.argumentparsers.SelectorWrapperArgument;
import io.github.nucleuspowered.nucleus.internal.annotations.Permissions;
import io.github.nucleuspowered.nucleus.internal.annotations.RegisterCommand;
import io.github.nucleuspowered.nucleus.internal.command.AbstractCommand;
import io.github.nucleuspowered.nucleus.internal.command.ReturnMessageException;
import io.github.nucleuspowered.nucleus.internal.messages.MessageProvider;
import io.github.nucleuspowered.nucleus.internal.permissions.PermissionInformation;
import io.github.nucleuspowered.nucleus.internal.permissions.SuggestedLevel;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandResult;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.command.args.CommandContext;
import org.spongepowered.api.command.args.CommandElement;
import org.spongepowered.api.command.args.GenericArguments;
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.data.type.OcelotType;
import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.entity.EntityTypes;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.cause.Cause;
import org.spongepowered.api.event.cause.NamedCause;
import org.spongepowered.api.event.cause.entity.spawn.SpawnCause;
import org.spongepowered.api.event.cause.entity.spawn.SpawnTypes;
import org.spongepowered.api.scheduler.Task;
import org.spongepowered.api.text.Text;
import org.spongepowered.api.world.World;
import org.spongepowered.api.world.explosion.Explosion;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.UUID;
import java.util.function.Consumer;

@Permissions(supportsSelectors = true, supportsOthers = true)
@RegisterCommand({"kittycannon", "kc"})
public class KittyCannonCommand extends AbstractCommand<CommandSource> {

    private final Random random = new Random();
    private final String playerKey = "player";
    private final List<OcelotType> ocelotTypes;

    @Override protected Map<String, PermissionInformation> permissionSuffixesToRegister() {
        return new HashMap<String, PermissionInformation>() {{
            MessageProvider provider = plugin.getMessageProvider();
            put("damage", new PermissionInformation(provider.getMessageWithFormat("permission.kittycannon.damage"), SuggestedLevel.ADMIN));
            put("break", new PermissionInformation(provider.getMessageWithFormat("permission.kittycannon.break"), SuggestedLevel.ADMIN));
            put("fire", new PermissionInformation(provider.getMessageWithFormat("permission.kittycannon.fire"), SuggestedLevel.ADMIN));
        }};
    }

    @Inject
    public KittyCannonCommand() {
        this.ocelotTypes = Lists.newArrayList(Sponge.getRegistry().getAllOf(OcelotType.class));
    }

    @Override public CommandElement[] getArguments() {
        return new CommandElement[] {
            GenericArguments.flags()
                .permissionFlag(permissions.getPermissionWithSuffix("damage"), "d", "-damageentities")
                .permissionFlag(permissions.getPermissionWithSuffix("break"), "b", "-breakblocks")
                .permissionFlag(permissions.getPermissionWithSuffix("fire"), "f", "-fire")
                .buildWith(
                    GenericArguments.optional(
                        GenericArguments.requiringPermission(
                            new SelectorWrapperArgument(GenericArguments.player(Text.of(playerKey)), permissions, SelectorWrapperArgument.ALL_SELECTORS),
                            permissions.getOthers())))
        };
    }

    @Override
    public CommandResult executeCommand(CommandSource src, CommandContext args) throws Exception {
        Collection<Player> playerList = args.getAll(playerKey);
        if (playerList.isEmpty()) {
            if (src instanceof Player) {
                playerList = Lists.newArrayList((Player)src);
            } else {
                throw new ReturnMessageException(plugin.getMessageProvider().getTextMessageWithFormat("command.playeronly"));
            }
        }

        // For each player, create a kitten, throw it out in the direction of the player, and make it explode after between 2 and 5 seconds
        playerList.forEach(x -> getACat(src, x, args.hasAny("d"), args.hasAny("b"), args.hasAny("f")));
        return CommandResult.success();
    }

    private void getACat(CommandSource source, Player spawnAt, boolean damageEntities, boolean breakBlocks, boolean causeFire) {
        // Fire it in the direction that the player is facing with a speed of 0.5 to 3.5, plus the player's current velocity.
        Vector3d headRotation = spawnAt.getHeadRotation();
        Quaterniond rot = Quaterniond.fromAxesAnglesDeg(headRotation.getX(), -headRotation.getY(), headRotation.getZ());
        Vector3d velocity = spawnAt.getVelocity().add(rot.rotate(Vector3d.UNIT_Z).mul(5 * random.nextDouble() + 1));
        World world = spawnAt.getWorld();
        Entity cat = world.createEntity(EntityTypes.OCELOT, spawnAt.getLocation()
            .getPosition().add(0, 1, 0).add(spawnAt.getTransform().getRotationAsQuaternion().getDirection()));
        cat.offer(Keys.OCELOT_TYPE, ocelotTypes.get(random.nextInt(ocelotTypes.size())));

        Sponge.getScheduler().createTaskBuilder().intervalTicks(5).delayTicks(5)
            .execute(new CatTimer(world.getUniqueId(), cat.getUniqueId(), spawnAt, random.nextInt(60) + 20, damageEntities, breakBlocks, causeFire))
            .submit(plugin);

        world.spawnEntity(cat, Cause.of(NamedCause.owner(SpawnCause.builder().type(SpawnTypes.PLUGIN).build()), NamedCause.source(source)));
        cat.offer(Keys.VELOCITY, velocity);
    }

    private class CatTimer implements Consumer<Task> {
{'fraction_non_alphanumeric': 0.11000800640512409, 'fraction_numerical': 0.0032025620496397116, 'mean_word_length': 4.129774127310061, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6277131', 'n_tokens_mistral': 3631, 'n_tokens_neox': 3428, 'n_words': 644}