DropManager.java 4.65 KB
Newer Older
Kengxxiao's avatar
Kengxxiao committed
1
2
3
4
5
6
7
8
package emu.grasscutter.game.drop;

import com.google.gson.reflect.TypeToken;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.def.ItemData;
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;
Kengxxiao's avatar
Kengxxiao committed
14
15
16
17
18
19
20
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
56
57
58
59
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.io.FileReader;
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() {
        try (FileReader fileReader = new FileReader(Grasscutter.getConfig().DATA_FOLDER + "Drop.json")) {
            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) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
Kengxxiao's avatar
Kengxxiao committed
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    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.
                dropScene.getPlayers().forEach(x -> {
                    x.getInventory().addItem(new GameItem(itemData, num), ActionReason.SubfieldDrop, true);
                });
            }
        }
    }
Kengxxiao's avatar
Kengxxiao committed
79
80
81
82
83
84

    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
85

omg-xtao's avatar
omg-xtao committed
86
87
88
            if (itemData == null) {
                return;
            }
Kengxxiao's avatar
Kengxxiao committed
89
90
91
92
93
            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
94
                }
Kengxxiao's avatar
Kengxxiao committed
95
96
97
            } else {
                Position pos = em.getPosition().clone().addY(3f);
                addDropEntity(dd, em.getScene(), itemData, pos, num, gp);
Kengxxiao's avatar
Kengxxiao committed
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
            }
        }
    }

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