SpawnCommand.java 4.74 KB
Newer Older
KingRainbow44's avatar
KingRainbow44 committed
1
2
3
4
package emu.grasscutter.command.commands;

import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
5
import emu.grasscutter.data.GameData;
Melledy's avatar
Melledy committed
6
7
8
import emu.grasscutter.data.excels.GadgetData;
import emu.grasscutter.data.excels.ItemData;
import emu.grasscutter.data.excels.MonsterData;
9
import emu.grasscutter.game.entity.*;
Melledy's avatar
Melledy committed
10
import emu.grasscutter.game.player.Player;
11
import emu.grasscutter.game.props.FightProperty;
KingRainbow44's avatar
KingRainbow44 committed
12
import emu.grasscutter.utils.Position;
AnimeGitB's avatar
AnimeGitB committed
13
import emu.grasscutter.game.world.Scene;
KingRainbow44's avatar
KingRainbow44 committed
14
15
16

import java.util.List;

17
import static emu.grasscutter.config.Configuration.*;
18
19
import static emu.grasscutter.utils.Language.translate;

20
21
22
23
24
25
@Command(
    label = "spawn",
    usage = {"spawn <entityId> [amount] [level(monster only)] [<x> <y> <z>(monster only)]"},
    aliases = {"drop"},
    permission = "server.spawn",
    permissionTargeted = "server.spawn.others")
KingRainbow44's avatar
KingRainbow44 committed
26
27
28
public final class SpawnCommand implements CommandHandler {

    @Override
AnimeGitB's avatar
AnimeGitB committed
29
    public void execute(Player sender, Player targetPlayer, List<String> args) {
AnimeGitB's avatar
AnimeGitB committed
30
31
32
        int id = 0;  // This is just to shut up the linter, it's not a real default
        int amount = 1;
        int level = 1;
github-actions's avatar
github-actions committed
33
        float x = 0, y = 0, z = 0;
AnimeGitB's avatar
AnimeGitB committed
34
        switch (args.size()) {
35
36
37
38
39
40
41
42
            case 6:
                try {
                    x = Float.parseFloat(args.get(3));
                    y = Float.parseFloat(args.get(4));
                    z = Float.parseFloat(args.get(5));
                } catch (NumberFormatException ignored) {
                    CommandHandler.sendMessage(sender, translate(sender, "commands.execution.argument_error"));
                }  // Fallthrough
AnimeGitB's avatar
AnimeGitB committed
43
44
45
46
            case 3:
                try {
                    level = Integer.parseInt(args.get(2));
                } catch (NumberFormatException ignored) {
Secretboy's avatar
Secretboy committed
47
                    CommandHandler.sendMessage(sender, translate(sender, "commands.execution.argument_error"));
AnimeGitB's avatar
AnimeGitB committed
48
49
50
51
52
                }  // Fallthrough
            case 2:
                try {
                    amount = Integer.parseInt(args.get(1));
                } catch (NumberFormatException ignored) {
Secretboy's avatar
Secretboy committed
53
                    CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.amount"));
AnimeGitB's avatar
AnimeGitB committed
54
55
56
57
58
                }  // Fallthrough
            case 1:
                try {
                    id = Integer.parseInt(args.get(0));
                } catch (NumberFormatException ignored) {
Secretboy's avatar
Secretboy committed
59
                    CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.entityId"));
AnimeGitB's avatar
AnimeGitB committed
60
61
62
                }
                break;
            default:
63
                sendUsageMessage(sender);
AnimeGitB's avatar
AnimeGitB committed
64
                return;
KingRainbow44's avatar
KingRainbow44 committed
65
        }
github-actions's avatar
github-actions committed
66

AnimeGitB's avatar
AnimeGitB committed
67
68
69
70
        MonsterData monsterData = GameData.getMonsterDataMap().get(id);
        GadgetData gadgetData = GameData.getGadgetDataMap().get(id);
        ItemData itemData = GameData.getItemDataMap().get(id);
        if (monsterData == null && gadgetData == null && itemData == null) {
Secretboy's avatar
Secretboy committed
71
            CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.entityId"));
AnimeGitB's avatar
AnimeGitB committed
72
73
            return;
        }
github-actions's avatar
github-actions committed
74

AnimeGitB's avatar
AnimeGitB committed
75
        Scene scene = targetPlayer.getScene();
github-actions's avatar
github-actions committed
76

77
        if (scene.getEntities().size() + amount > GAME_OPTIONS.sceneEntityLimit) {
github-actions's avatar
github-actions committed
78
79
80
81
82
            amount = Math.max(Math.min(GAME_OPTIONS.sceneEntityLimit - scene.getEntities().size(), amount), 0);
            CommandHandler.sendMessage(sender, translate(sender, "commands.spawn.limit_reached", amount));
            if (amount <= 0) {
                return;
            }
83
        }
KingRainbow44's avatar
KingRainbow44 committed
84

AnimeGitB's avatar
AnimeGitB committed
85
        double maxRadius = Math.sqrt(amount * 0.2 / Math.PI);
AnimeGitB's avatar
AnimeGitB committed
86
87
88
        Position center = (x != 0 && y != 0 && z != 0)
                            ? (new Position(x, y, z))
                            : (targetPlayer.getPosition());
AnimeGitB's avatar
AnimeGitB committed
89
        for (int i = 0; i < amount; i++) {
AnimeGitB's avatar
AnimeGitB committed
90
            Position pos = GetRandomPositionInCircle(center, maxRadius).addY(3);
AnimeGitB's avatar
AnimeGitB committed
91
92
93
            GameEntity entity = null;
            if (itemData != null) {
                entity = new EntityItem(scene, null, itemData, pos, 1, true);
KingRainbow44's avatar
KingRainbow44 committed
94
            }
AnimeGitB's avatar
AnimeGitB committed
95
            if (gadgetData != null) {
Benj's avatar
Benj committed
96
                pos.addY(-3);
AnimeGitB's avatar
AnimeGitB committed
97
                entity = new EntityVehicle(scene, targetPlayer, id, 0, pos, targetPlayer.getRotation());
KingRainbow44's avatar
KingRainbow44 committed
98
            }
AnimeGitB's avatar
AnimeGitB committed
99
100
101
102
103
            if (monsterData != null) {
                entity = new EntityMonster(scene, monsterData, pos, level);
            }

            scene.addEntity(entity);
KingRainbow44's avatar
KingRainbow44 committed
104
        }
AnimeGitB's avatar
AnimeGitB committed
105
        CommandHandler.sendMessage(sender, translate(sender, "commands.spawn.success", amount, id));
KingRainbow44's avatar
KingRainbow44 committed
106
    }
107

github-actions's avatar
github-actions committed
108
    private Position GetRandomPositionInCircle(Position origin, double radius) {
109
110
111
112
113
114
        Position target = origin.clone();
        double angle = Math.random() * 360;
        double r = Math.sqrt(Math.random() * radius * radius);
        target.addX((float) (r * Math.cos(angle))).addZ((float) (r * Math.sin(angle)));
        return target;
    }
KingRainbow44's avatar
KingRainbow44 committed
115
}