ClearCommand.java 5.77 KB
Newer Older
1
2
3
4
package emu.grasscutter.command.commands;

import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
5
import emu.grasscutter.game.inventory.GameItem;
6
7
import emu.grasscutter.game.inventory.Inventory;
import emu.grasscutter.game.inventory.ItemType;
Melledy's avatar
Melledy committed
8
import emu.grasscutter.game.player.Player;
9
10

import java.util.List;
11
12
13
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
14

15
16
17
18
19
@Command(
    label = "clear",
    usage = {"(all|wp|art|mat) [lv<max level>] [r<max refinement>] [<max rarity>*]"},
    permission = "player.clearinv",
    permissionTargeted = "player.clearinv.others")
20
public final class ClearCommand implements CommandHandler {
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
    private static Pattern lvlRegex = Pattern.compile("l(?:vl?)?(\\d+)");  // Java doesn't have raw string literals :(
    private static Pattern refineRegex = Pattern.compile("r(\\d+)");
    private static Pattern rankRegex = Pattern.compile("(\\d+)\\*");

    private static int matchIntOrNeg(Pattern pattern, String arg) {
        Matcher match = pattern.matcher(arg);
        if (match.find()) {
            return Integer.parseInt(match.group(1));  // This should be exception-safe as only \d+ can be passed to it (i.e. non-empty string of pure digits)
        }
        return -1;
    }

    private static class ClearItemParameters {
        public int lvl = 1;
        public int refinement = 1;
        public int rank = 4;
    };

    private Stream<GameItem> getOther(ItemType type, Inventory playerInventory, ClearItemParameters param) {
        return playerInventory.getItems().values().stream()
                .filter(item -> item.getItemType() == type)
                .filter(item -> item.getItemData().getRankLevel() <= param.rank)
                .filter(item -> !item.isLocked() && !item.isEquipped());
    }

    private Stream<GameItem> getWeapons(Inventory playerInventory, ClearItemParameters param) {
        return getOther(ItemType.ITEM_WEAPON, playerInventory, param)
                .filter(item -> item.getLevel() <= param.lvl)
                .filter(item -> item.getRefinement() < param.refinement);
    }

    private Stream<GameItem> getRelics(Inventory playerInventory, ClearItemParameters param) {
        return getOther(ItemType.ITEM_RELIQUARY, playerInventory, param)
                .filter(item -> item.getLevel() <= param.lvl + 1);
    }
56
57

    @Override
AnimeGitB's avatar
AnimeGitB committed
58
    public void execute(Player sender, Player targetPlayer, List<String> args) {
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
        Inventory playerInventory = targetPlayer.getInventory();
        ClearItemParameters param = new ClearItemParameters();

        // Extract any tagged arguments (e.g. "lv90", "x100", "r5")
        for (int i = args.size() - 1; i >= 0; i--) {  // Reverse iteration as we are deleting elements
            String arg = args.get(i).toLowerCase();
            boolean deleteArg = false;
            int argNum;
            // Note that a single argument can actually match all of these, e.g. "lv90r5*"
            if ((argNum = matchIntOrNeg(lvlRegex, arg)) != -1) {
                param.lvl = argNum;
                deleteArg = true;
            }
            if ((argNum = matchIntOrNeg(refineRegex, arg)) != -1) {
                param.refinement = argNum;
                deleteArg = true;
            }
            if ((argNum = matchIntOrNeg(rankRegex, arg)) != -1) {
                param.rank = argNum;
                deleteArg = true;
            }
            if (deleteArg) {
                args.remove(i);
            }
        }

AnimeGitB's avatar
AnimeGitB committed
85
        if (args.size() < 1) {
86
            sendUsageMessage(sender);
87
88
            return;
        }
89
90

        String playerString = targetPlayer.getNickname();  // Should probably be UID instead but whatever
AnimeGitB's avatar
AnimeGitB committed
91
92
        switch (args.get(0)) {
            case "wp" -> {
93
94
                playerInventory.removeItems(getWeapons(playerInventory, param).toList());
                CommandHandler.sendTranslatedMessage(sender, "commands.clear.weapons", playerString);
AnimeGitB's avatar
AnimeGitB committed
95
96
            }
            case "art" -> {
97
98
                playerInventory.removeItems(getRelics(playerInventory, param).toList());
                CommandHandler.sendTranslatedMessage(sender, "commands.clear.artifacts", playerString);
AnimeGitB's avatar
AnimeGitB committed
99
100
            }
            case "mat" -> {
101
102
                playerInventory.removeItems(getOther(ItemType.ITEM_MATERIAL, playerInventory, param).toList());
                CommandHandler.sendTranslatedMessage(sender, "commands.clear.materials", playerString);
AnimeGitB's avatar
AnimeGitB committed
103
104
            }
            case "all" -> {
105
106
107
108
109
110
111
112
113
114
115
116
117
                playerInventory.removeItems(getRelics(playerInventory, param).toList());
                CommandHandler.sendTranslatedMessage(sender, "commands.clear.artifacts", playerString);
                playerInventory.removeItems(getWeapons(playerInventory, param).toList());
                CommandHandler.sendTranslatedMessage(sender, "commands.clear.weapons", playerString);
                playerInventory.removeItems(getOther(ItemType.ITEM_MATERIAL, playerInventory, param).toList());
                CommandHandler.sendTranslatedMessage(sender, "commands.clear.materials", playerString);
                playerInventory.removeItems(getOther(ItemType.ITEM_FURNITURE, playerInventory, param).toList());
                CommandHandler.sendTranslatedMessage(sender, "commands.clear.furniture", playerString);
                playerInventory.removeItems(getOther(ItemType.ITEM_DISPLAY, playerInventory, param).toList());
                CommandHandler.sendTranslatedMessage(sender, "commands.clear.displays", playerString);
                playerInventory.removeItems(getOther(ItemType.ITEM_VIRTUAL, playerInventory, param).toList());
                CommandHandler.sendTranslatedMessage(sender, "commands.clear.virtuals", playerString);
                CommandHandler.sendTranslatedMessage(sender, "commands.clear.everything", playerString);
AnimeGitB's avatar
AnimeGitB committed
118
            }
119
120
121
        }
    }
}