DropSystem.java 4.23 KB
Newer Older
Kengxxiao's avatar
Kengxxiao committed
1
2
3
package emu.grasscutter.game.drop;

import emu.grasscutter.Grasscutter;
4
import emu.grasscutter.data.DataLoader;
Kengxxiao's avatar
Kengxxiao committed
5
import emu.grasscutter.data.GameData;
Melledy's avatar
Melledy committed
6
import emu.grasscutter.data.excels.ItemData;
Kengxxiao's avatar
Kengxxiao committed
7
8
import emu.grasscutter.game.entity.EntityItem;
import emu.grasscutter.game.entity.EntityMonster;
Kengxxiao's avatar
Kengxxiao committed
9
10
import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.inventory.ItemType;
Kengxxiao's avatar
Kengxxiao committed
11
import emu.grasscutter.game.player.Player;
Kengxxiao's avatar
Kengxxiao committed
12
13
import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.game.world.Scene;
14
import emu.grasscutter.server.game.BaseGameSystem;
Kengxxiao's avatar
Kengxxiao committed
15
16
17
18
19
20
21
22
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;

import java.util.List;

23
public class DropSystem extends BaseGameSystem {
Kengxxiao's avatar
Kengxxiao committed
24
25
    private final Int2ObjectMap<List<DropData>> dropData;

26
27
    public DropSystem(GameServer server) {
        super(server);
Kengxxiao's avatar
Kengxxiao committed
28
29
30
        this.dropData = new Int2ObjectOpenHashMap<>();
        this.load();
    }
github-actions's avatar
github-actions committed
31

32
33
34
    public Int2ObjectMap<List<DropData>> getDropData() {
        return dropData;
    }
Kengxxiao's avatar
Kengxxiao committed
35
36

    public synchronized void load() {
37
38
39
        getDropData().clear();
        try {
            List<DropInfo> banners = DataLoader.loadList("Drop.json", DropInfo.class);
github-actions's avatar
github-actions committed
40
            if (banners.size() > 0) {
Kengxxiao's avatar
Kengxxiao committed
41
42
43
                for (DropInfo di : banners) {
                    getDropData().put(di.getMonsterId(), di.getDropDataList());
                }
44
                Grasscutter.getLogger().debug("Drop data successfully loaded.");
Kengxxiao's avatar
Kengxxiao committed
45
46
47
48
            } else {
                Grasscutter.getLogger().error("Unable to load drop data. Drop data size is 0.");
            }
        } catch (Exception e) {
KingRainbow44's avatar
KingRainbow44 committed
49
            Grasscutter.getLogger().error("Unable to load drop data.", e);
Kengxxiao's avatar
Kengxxiao committed
50
51
        }
    }
Kengxxiao's avatar
Kengxxiao committed
52
53
54
55
56
57
58
59
60
61
62
63
64
    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.
65
                dropScene.getPlayers().forEach(x -> x.getInventory().addItem(new GameItem(itemData, num), ActionReason.SubfieldDrop, true));
Kengxxiao's avatar
Kengxxiao committed
66
67
68
            }
        }
    }
Kengxxiao's avatar
Kengxxiao committed
69
70
71
72
73
74

    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
75

omg-xtao's avatar
omg-xtao committed
76
77
78
            if (itemData == null) {
                return;
            }
Kengxxiao's avatar
Kengxxiao committed
79
80
            if (itemData.isEquip()) {
                for (int i = 0; i < num; i++) {
AnimeGitB's avatar
AnimeGitB committed
81
82
                    float range = (2.5f + (.05f * num));
                    Position pos = em.getPosition().nearby2d(range).addY(3f);
Kengxxiao's avatar
Kengxxiao committed
83
                    addDropEntity(dd, em.getScene(), itemData, pos, num, gp);
Kengxxiao's avatar
Kengxxiao committed
84
                }
Kengxxiao's avatar
Kengxxiao committed
85
86
87
            } else {
                Position pos = em.getPosition().clone().addY(3f);
                addDropEntity(dd, em.getScene(), itemData, pos, num, gp);
Kengxxiao's avatar
Kengxxiao committed
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
            }
        }
    }

    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);
                    }
                }
            }
        }
    }
}