CombineManger.java 5.79 KB
Newer Older
Akka's avatar
Akka committed
1
2
package emu.grasscutter.game.combine;

3
4
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.DataLoader;
Akka's avatar
Akka committed
5
import emu.grasscutter.data.GameData;
Melledy's avatar
Melledy committed
6
7
import emu.grasscutter.data.common.ItemParamData;
import emu.grasscutter.data.excels.CombineData;
ImmuState's avatar
ImmuState committed
8
import emu.grasscutter.game.inventory.GameItem;
Akka's avatar
Akka committed
9
import emu.grasscutter.game.player.Player;
ImmuState's avatar
ImmuState committed
10
import emu.grasscutter.game.props.ActionReason;
11
import emu.grasscutter.game.props.ItemUseOp;
Akka's avatar
Akka committed
12
import emu.grasscutter.net.proto.RetcodeOuterClass;
13
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
14
import emu.grasscutter.server.game.BaseGameSystem;
Akka's avatar
Akka committed
15
import emu.grasscutter.server.game.GameServer;
ImmuState's avatar
ImmuState committed
16
import emu.grasscutter.server.packet.send.PacketCombineFormulaDataNotify;
Akka's avatar
Akka committed
17
import emu.grasscutter.server.packet.send.PacketCombineRsp;
18
19
20
21
import emu.grasscutter.server.packet.send.PacketReliquaryDecomposeRsp;
import emu.grasscutter.utils.Utils;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
Akka's avatar
Akka committed
22

ImmuState's avatar
ImmuState committed
23
import java.util.ArrayList;
Akka's avatar
Akka committed
24
25
import java.util.List;

26
public class CombineManger extends BaseGameSystem {
github-actions's avatar
github-actions committed
27
    private final static Int2ObjectMap<List<Integer>> reliquaryDecomposeData = new Int2ObjectOpenHashMap<>();
Akka's avatar
Akka committed
28

29
30
    public CombineManger(GameServer server) {
        super(server);
Akka's avatar
Akka committed
31
32
    }

33
    public static void initialize() {
github-actions's avatar
github-actions committed
34
        // Read the data we need for strongbox.
35
36
        try {
            DataLoader.loadList("ReliquaryDecompose.json", ReliquaryDecomposeEntry.class).forEach(entry -> {
github-actions's avatar
github-actions committed
37
                reliquaryDecomposeData.put(entry.getConfigId(), entry.getItems());
38
            });
github-actions's avatar
github-actions committed
39
40
41
42
43
44
            Grasscutter.getLogger().debug("Loaded {} reliquary decompose entries.", reliquaryDecomposeData.size());
        }
        catch (Exception ex) {
            Grasscutter.getLogger().error("Unable to load reliquary decompose data.", ex);
        }
    }
45

ImmuState's avatar
ImmuState committed
46
    public boolean unlockCombineDiagram(Player player, GameItem diagramItem) {
github-actions's avatar
github-actions committed
47
        // Make sure this is actually a diagram.
48
        if (diagramItem.getItemData().getItemUse().get(0).getUseOp() != ItemUseOp.ITEM_USE_UNLOCK_COMBINE) {
github-actions's avatar
github-actions committed
49
50
            return false;
        }
ImmuState's avatar
ImmuState committed
51

github-actions's avatar
github-actions committed
52
        // Determine the combine item we should unlock.
53
        int combineId = Integer.parseInt(diagramItem.getItemData().getItemUse().get(0).getUseParam()[0]);
ImmuState's avatar
ImmuState committed
54

github-actions's avatar
github-actions committed
55
56
57
58
        // Remove the diagram from the player's inventory.
        // We need to do this here, before sending CombineFormulaDataNotify, or the the combine UI won't correctly
        // update when unlocking the diagram.
        player.getInventory().removeItem(diagramItem, 1);
ImmuState's avatar
ImmuState committed
59

github-actions's avatar
github-actions committed
60
61
62
        // Tell the client that this diagram is now unlocked and add the unlocked item to the player.
        player.getUnlockedCombines().add(combineId);
        player.sendPacket(new PacketCombineFormulaDataNotify(combineId));
ImmuState's avatar
ImmuState committed
63

github-actions's avatar
github-actions committed
64
65
        return true;
    }
ImmuState's avatar
ImmuState committed
66

github-actions's avatar
github-actions committed
67
    public CombineResult combineItem(Player player, int cid, int count) {
Akka's avatar
Akka committed
68
        // check config exist
github-actions's avatar
github-actions committed
69
        if (!GameData.getCombineDataMap().containsKey(cid)) {
Akka's avatar
Akka committed
70
71
72
73
74
75
            player.getWorld().getHost().sendPacket(new PacketCombineRsp());
            return null;
        }

        CombineData combineData = GameData.getCombineDataMap().get(cid);

github-actions's avatar
github-actions committed
76
        if (combineData.getPlayerLevel() > player.getLevel()) {
Akka's avatar
Akka committed
77
78
            return null;
        }
ImmuState's avatar
ImmuState committed
79
80
81
82
83

        // consume items
        List<ItemParamData> material = new ArrayList<>(combineData.getMaterialItems());
        material.add(new ItemParamData(202, combineData.getScoinCost()));

AnimeGitB's avatar
AnimeGitB committed
84
        boolean success = player.getInventory().payItems(material, count, ActionReason.Combine);
ImmuState's avatar
ImmuState committed
85
86
87
88

        // abort if not enough material
        if (!success) {
            player.sendPacket(new PacketCombineRsp(RetcodeOuterClass.Retcode.RET_ITEM_COMBINE_COUNT_NOT_ENOUGH_VALUE));
Akka's avatar
Akka committed
89
90
91
92
93
94
95
96
        }

        // make the result
        player.getInventory().addItem(combineData.getResultItemId(),
                combineData.getResultItemCount() * count);

        CombineResult result = new CombineResult();
        result.setMaterial(List.of());
Melledy's avatar
Melledy committed
97
        result.setResult(List.of(new ItemParamData(combineData.getResultItemId(),
Akka's avatar
Akka committed
98
99
100
101
102
103
104
105
                combineData.getResultItemCount() * count)));
        // TODO lucky characters
        result.setExtra(List.of());
        result.setBack(List.of());

        return result;
    }

106
107
108
109
110
111
112
    public synchronized void decomposeReliquaries(Player player, int configId, int count, List<Long> input) {
        // Check if the configId is legal.
        List<Integer> possibleDrops = reliquaryDecomposeData.get(configId);
        if (possibleDrops == null) {
            player.sendPacket(new PacketReliquaryDecomposeRsp(Retcode.RET_RELIQUARY_DECOMPOSE_PARAM_ERROR));
            return;
        }
github-actions's avatar
github-actions committed
113

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
        // Check if the number of input items matches the output count.
        if (input.size() != count * 3) {
            player.sendPacket(new PacketReliquaryDecomposeRsp(Retcode.RET_RELIQUARY_DECOMPOSE_PARAM_ERROR));
            return;
        }

        // Check if all the input reliquaries actually are in the player's inventory.
        for (long guid : input) {
            if (player.getInventory().getItemByGuid(guid) == null) {
                player.sendPacket(new PacketReliquaryDecomposeRsp(Retcode.RET_RELIQUARY_DECOMPOSE_PARAM_ERROR));
                return;
            }
        }

        // Delete the input reliquaries.
        for (long guid : input) {
            player.getInventory().removeItem(guid);
        }

        // Generate outoput reliquaries.
        List<Long> resultItems = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            int itemId = Utils.drawRandomListElement(possibleDrops);
github-actions's avatar
github-actions committed
137
            GameItem newReliquary = new GameItem(itemId, 1);
138
139
140
141
142
143
144
145

            player.getInventory().addItem(newReliquary);
            resultItems.add(newReliquary.getGuid());
        }

        // Send packet.
        player.sendPacket(new PacketReliquaryDecomposeRsp(resultItems));
    }
Akka's avatar
Akka committed
146
}