DropManager.java 4.66 KB
Newer Older
Kengxxiao's avatar
Kengxxiao committed
1
2
3
4
package emu.grasscutter.game.drop;

import com.google.gson.reflect.TypeToken;
import emu.grasscutter.Grasscutter;
5
import emu.grasscutter.data.DataLoader;
Kengxxiao's avatar
Kengxxiao committed
6
import emu.grasscutter.data.GameData;
Melledy's avatar
Melledy committed
7
import emu.grasscutter.data.excels.ItemData;
Kengxxiao's avatar
Kengxxiao committed
8
9
import emu.grasscutter.game.entity.EntityItem;
import emu.grasscutter.game.entity.EntityMonster;
Kengxxiao's avatar
Kengxxiao committed
10
11
import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.inventory.ItemType;
Kengxxiao's avatar
Kengxxiao committed
12
import emu.grasscutter.game.player.Player;
Kengxxiao's avatar
Kengxxiao committed
13
14
import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.game.world.Scene;
Kengxxiao's avatar
Kengxxiao committed
15
16
17
18
19
20
import emu.grasscutter.server.game.GameServer;
import emu.grasscutter.utils.Position;
import emu.grasscutter.utils.Utils;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;

21
22
import java.io.InputStreamReader;
import java.io.Reader;
Kengxxiao's avatar
Kengxxiao committed
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import java.util.Collection;
import java.util.List;

public class DropManager {
    public GameServer getGameServer() {
        return gameServer;
    }

    private final GameServer gameServer;

    public Int2ObjectMap<List<DropData>> getDropData() {
        return dropData;
    }

    private final Int2ObjectMap<List<DropData>> dropData;

    public DropManager(GameServer gameServer) {
        this.gameServer = gameServer;
        this.dropData = new Int2ObjectOpenHashMap<>();
        this.load();
    }

    public synchronized void load() {
46
        try (Reader fileReader = new InputStreamReader(DataLoader.load("Drop.json"))) {
Kengxxiao's avatar
Kengxxiao committed
47
48
49
50
51
52
53
54
55
56
57
            getDropData().clear();
            List<DropInfo> banners = Grasscutter.getGsonFactory().fromJson(fileReader, TypeToken.getParameterized(Collection.class, DropInfo.class).getType());
            if(banners.size() > 0) {
                for (DropInfo di : banners) {
                    getDropData().put(di.getMonsterId(), di.getDropDataList());
                }
                Grasscutter.getLogger().info("Drop data successfully loaded.");
            } else {
                Grasscutter.getLogger().error("Unable to load drop data. Drop data size is 0.");
            }
        } catch (Exception e) {
KingRainbow44's avatar
KingRainbow44 committed
58
            Grasscutter.getLogger().error("Unable to load drop data.", e);
Kengxxiao's avatar
Kengxxiao committed
59
60
        }
    }
Kengxxiao's avatar
Kengxxiao committed
61
62
63
64
65
66
67
68
69
70
71
72
73
    private void addDropEntity(DropData dd, Scene dropScene, ItemData itemData, Position pos, int num, Player target) {
        if (!dd.isGive() && (itemData.getItemType() != ItemType.ITEM_VIRTUAL || itemData.getGadgetId() != 0)) {
            EntityItem entity = new EntityItem(dropScene, target, itemData, pos, num, dd.isShare());
            if (!dd.isShare())
                dropScene.addEntityToSingleClient(target, entity);
            else
                dropScene.addEntity(entity);
        } else {
            if (target != null) {
                target.getInventory().addItem(new GameItem(itemData, num), ActionReason.SubfieldDrop, true);
            } else {
                // target is null if items will be added are shared. no one could pick it up because of the combination(give + shared)
                // so it will be sent to all players' inventories directly.
74
                dropScene.getPlayers().forEach(x -> x.getInventory().addItem(new GameItem(itemData, num), ActionReason.SubfieldDrop, true));
Kengxxiao's avatar
Kengxxiao committed
75
76
77
            }
        }
    }
Kengxxiao's avatar
Kengxxiao committed
78
79
80
81
82
83

    private void processDrop(DropData dd, EntityMonster em, Player gp) {
        int target = Utils.randomRange(1, 10000);
        if (target >= dd.getMinWeight() && target < dd.getMaxWeight()) {
            ItemData itemData = GameData.getItemDataMap().get(dd.getItemId());
            int num = Utils.randomRange(dd.getMinCount(), dd.getMaxCount());
Kengxxiao's avatar
Kengxxiao committed
84

omg-xtao's avatar
omg-xtao committed
85
86
87
            if (itemData == null) {
                return;
            }
Kengxxiao's avatar
Kengxxiao committed
88
89
90
91
92
            if (itemData.isEquip()) {
                for (int i = 0; i < num; i++) {
                    float range = (5f + (.1f * num));
                    Position pos = em.getPosition().clone().addX((float) (Math.random() * range) - (range / 2)).addY(3f).addZ((float) (Math.random() * range) - (range / 2));
                    addDropEntity(dd, em.getScene(), itemData, pos, num, gp);
Kengxxiao's avatar
Kengxxiao committed
93
                }
Kengxxiao's avatar
Kengxxiao committed
94
95
96
            } else {
                Position pos = em.getPosition().clone().addY(3f);
                addDropEntity(dd, em.getScene(), itemData, pos, num, gp);
Kengxxiao's avatar
Kengxxiao committed
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
            }
        }
    }

    public void callDrop(EntityMonster em) {
        int id = em.getMonsterData().getId();
        if (getDropData().containsKey(id)) {
            for (DropData dd : getDropData().get(id)) {
                if (dd.isShare())
                    processDrop(dd, em, null);
                else {
                    for (Player gp : em.getScene().getPlayers()) {
                        processDrop(dd, em, gp);
                    }
                }
            }
        }
    }
}