Skip to content
Snippets Groups Projects
Commit 706dc5e4 authored by Akka's avatar Akka Committed by Melledy
Browse files

MonsterInvestigation (boss icon in map)

parent 80c61466
Branches
Tags
No related merge requests found
...@@ -93,6 +93,7 @@ public class GameData { ...@@ -93,6 +93,7 @@ public class GameData {
private static final Int2ObjectMap<HomeWorldLevelData> homeWorldLevelDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<HomeWorldLevelData> homeWorldLevelDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<FurnitureMakeConfigData> furnitureMakeConfigDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<FurnitureMakeConfigData> furnitureMakeConfigDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<InvestigationMonsterData> investigationMonsterDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<InvestigationMonsterData> investigationMonsterDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<CityData> cityDataMap = new Int2ObjectOpenHashMap<>();
// Cache // Cache
private static Map<Integer, List<Integer>> fetters = new HashMap<>(); private static Map<Integer, List<Integer>> fetters = new HashMap<>();
...@@ -411,4 +412,8 @@ public class GameData { ...@@ -411,4 +412,8 @@ public class GameData {
public static Int2ObjectMap<InvestigationMonsterData> getInvestigationMonsterDataMap() { public static Int2ObjectMap<InvestigationMonsterData> getInvestigationMonsterDataMap() {
return investigationMonsterDataMap; return investigationMonsterDataMap;
} }
public static Int2ObjectMap<CityData> getCityDataMap() {
return cityDataMap;
}
} }
package emu.grasscutter.data.excels;
import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.FieldDefaults;
import java.util.List;
@ResourceType(name = "CityConfigData.json", loadPriority = ResourceType.LoadPriority.HIGH)
@Getter
@Setter
@FieldDefaults(level = AccessLevel.PRIVATE)
public class CityData extends GameResource {
int cityId;
int sceneId;
List<Integer> areaIdVec;
@Override
public int getId() {
return this.cityId;
}
@Override
public void onLoad() {
super.onLoad();
}
}
package emu.grasscutter.data.excels; package emu.grasscutter.data.excels;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import lombok.AccessLevel;
import lombok.Data; import lombok.Data;
import lombok.Getter;
import lombok.experimental.FieldDefaults;
import java.util.List; import java.util.List;
@ResourceType(name = "InvestigationMonsterConfigData.json") @ResourceType(name = "InvestigationMonsterConfigData.json", loadPriority = ResourceType.LoadPriority.LOW)
@Data @Getter
@FieldDefaults(level = AccessLevel.PRIVATE)
public class InvestigationMonsterData extends GameResource { public class InvestigationMonsterData extends GameResource {
private int id; int id;
private int cityId; int cityId;
private List<Integer> monsterIdList; List<Integer> monsterIdList;
private List<Integer> groupIdList; List<Integer> groupIdList;
private int rewardPreviewId; int rewardPreviewId;
private String mapMarkCreateType; String mapMarkCreateType;
private String monsterCategory; String monsterCategory;
CityData cityData;
@Override @Override
public int getId() { public int getId() {
return this.id; return this.id;
...@@ -24,6 +30,6 @@ public class InvestigationMonsterData extends GameResource { ...@@ -24,6 +30,6 @@ public class InvestigationMonsterData extends GameResource {
@Override @Override
public void onLoad() { public void onLoad() {
super.onLoad(); this.cityData = GameData.getCityDataMap().get(cityId);
} }
} }
...@@ -4,10 +4,16 @@ import com.google.gson.reflect.TypeToken; ...@@ -4,10 +4,16 @@ import com.google.gson.reflect.TypeToken;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.DataLoader; import emu.grasscutter.data.DataLoader;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.InvestigationMonsterData;
import emu.grasscutter.data.excels.RewardPreviewData; import emu.grasscutter.data.excels.RewardPreviewData;
import emu.grasscutter.data.excels.WorldLevelData;
import emu.grasscutter.game.entity.gadget.chest.BossChestInteractHandler; import emu.grasscutter.game.entity.gadget.chest.BossChestInteractHandler;
import emu.grasscutter.game.entity.gadget.chest.ChestInteractHandler; import emu.grasscutter.game.entity.gadget.chest.ChestInteractHandler;
import emu.grasscutter.game.entity.gadget.chest.NormalChestInteractHandler; import emu.grasscutter.game.entity.gadget.chest.NormalChestInteractHandler;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.proto.InvestigationMonsterOuterClass;
import emu.grasscutter.scripts.data.SceneGroup;
import emu.grasscutter.scripts.data.SceneMonster;
import emu.grasscutter.server.game.GameServer; import emu.grasscutter.server.game.GameServer;
import java.io.InputStream; import java.io.InputStream;
...@@ -15,14 +21,19 @@ import java.io.InputStreamReader; ...@@ -15,14 +21,19 @@ import java.io.InputStreamReader;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
public class WorldDataManager { public class WorldDataManager {
private final GameServer gameServer; private final GameServer gameServer;
private final Map<String, ChestInteractHandler> chestInteractHandlerMap; // chestType-Handler private final Map<String, ChestInteractHandler> chestInteractHandlerMap; // chestType-Handler
private final Map<String, SceneGroup> sceneInvestigationGroupMap; // <sceneId_groupId, Group>
public WorldDataManager(GameServer gameServer){ public WorldDataManager(GameServer gameServer){
this.gameServer = gameServer; this.gameServer = gameServer;
this.chestInteractHandlerMap = new HashMap<>(); this.chestInteractHandlerMap = new HashMap<>();
this.sceneInvestigationGroupMap = new ConcurrentHashMap<>();
loadChestConfig(); loadChestConfig();
} }
...@@ -59,4 +70,80 @@ public class WorldDataManager { ...@@ -59,4 +70,80 @@ public class WorldDataManager {
} }
return GameData.getRewardPreviewDataMap().get(investigationMonsterData.get().getRewardPreviewId()); return GameData.getRewardPreviewDataMap().get(investigationMonsterData.get().getRewardPreviewId());
} }
private SceneGroup getInvestigationGroup(int sceneId, int groupId){
var key = sceneId + "_" + groupId;
if(!sceneInvestigationGroupMap.containsKey(key)){
var group = SceneGroup.of(groupId).load(sceneId);
sceneInvestigationGroupMap.putIfAbsent(key, group);
return group;
}
return sceneInvestigationGroupMap.get(key);
}
public int getMonsterLevel(SceneMonster monster, World world){
// Calculate level
int level = monster.level;
WorldLevelData worldLevelData = GameData.getWorldLevelDataMap().get(world.getWorldLevel());
if (worldLevelData != null) {
level = worldLevelData.getMonsterLevel();
}
return level;
}
private InvestigationMonsterOuterClass.InvestigationMonster getInvestigationMonster(Player player, InvestigationMonsterData imd) {
var groupId = imd.getGroupIdList().get(0);
var monsterId = imd.getMonsterIdList().get(0);
var sceneId = imd.getCityData().getSceneId();
var group = getInvestigationGroup(sceneId, groupId);
if(group == null || group.monsters == null){
return null;
}
var monster = group.monsters.values().stream()
.filter(x -> x.monster_id == monsterId)
.findFirst();
if(monster.isEmpty()){
return null;
}
var builder = InvestigationMonsterOuterClass.InvestigationMonster.newBuilder();
builder.setId(imd.getId())
.setCityId(imd.getCityId())
.setSceneId(imd.getCityData().getSceneId())
.setGroupId(groupId)
.setMonsterId(monsterId)
.setLevel(getMonsterLevel(monster.get(), player.getWorld()))
.setIsAlive(true)
.setNextRefreshTime(Integer.MAX_VALUE)
.setRefreshInterval(Integer.MAX_VALUE)
.setPos(monster.get().pos.toProto());
if("Boss".equals(imd.getMonsterCategory())){
var bossChest = group.searchBossChestInGroup();
if(bossChest.isPresent()){
builder.setResin(bossChest.get().resin);
builder.setBossChestNum(bossChest.get().take_num);
}
}
return builder.build();
}
public List<InvestigationMonsterOuterClass.InvestigationMonster> getInvestigationMonstersByCityId(Player player, int cityId){
var cityData = GameData.getCityDataMap().get(cityId);
if(cityData == null){
Grasscutter.getLogger().warn("City not exist {}", cityId);
return List.of();
}
return GameData.getInvestigationMonsterDataMap().values()
.parallelStream()
.filter(imd -> imd.getCityId() == cityId)
.map(imd -> this.getInvestigationMonster(player, imd))
.filter(Objects::nonNull)
.toList();
}
} }
...@@ -16,6 +16,7 @@ import org.luaj.vm2.LuaValue; ...@@ -16,6 +16,7 @@ import org.luaj.vm2.LuaValue;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static emu.grasscutter.Configuration.SCRIPT; import static emu.grasscutter.Configuration.SCRIPT;
...@@ -165,4 +166,12 @@ public class SceneGroup { ...@@ -165,4 +166,12 @@ public class SceneGroup {
Grasscutter.getLogger().info("group {} in scene {} is loaded successfully.", id, sceneId); Grasscutter.getLogger().info("group {} in scene {} is loaded successfully.", id, sceneId);
return this; return this;
} }
public Optional<SceneBossChest> searchBossChestInGroup() {
return gadgets.values().stream()
.filter(g -> g.boss_chest != null && g.boss_chest.monster_config_id > 0)
.map(g -> g.boss_chest)
.findFirst();
}
} }
...@@ -14,7 +14,11 @@ public class HandlerGetInvestigationMonsterReq extends PacketHandler { ...@@ -14,7 +14,11 @@ public class HandlerGetInvestigationMonsterReq extends PacketHandler {
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
var req = GetInvestigationMonsterReqOuterClass.GetInvestigationMonsterReq.parseFrom(payload); var req = GetInvestigationMonsterReqOuterClass.GetInvestigationMonsterReq.parseFrom(payload);
session.send(new PacketGetInvestigationMonsterRsp(req.getCityIdListList())); session.send(new PacketGetInvestigationMonsterRsp(
session.getPlayer(),
session.getServer().getWorldDataManager(),
req.getCityIdListList()));
} }
} }
package emu.grasscutter.server.packet.send; package emu.grasscutter.server.packet.send;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.world.WorldDataManager;
import emu.grasscutter.net.packet.BasePacket; import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.GetActivityInfoRspOuterClass; import emu.grasscutter.net.proto.GetActivityInfoRspOuterClass;
import emu.grasscutter.net.proto.GetInvestigationMonsterRspOuterClass;
import java.util.List; import java.util.List;
public class PacketGetInvestigationMonsterRsp extends BasePacket { public class PacketGetInvestigationMonsterRsp extends BasePacket {
public PacketGetInvestigationMonsterRsp(List<Integer> cityIdListList) { public PacketGetInvestigationMonsterRsp(Player player, WorldDataManager worldDataManager, List<Integer> cityIdListList) {
super(PacketOpcodes.GetInvestigationMonsterRsp); super(PacketOpcodes.GetInvestigationMonsterRsp);
var resp = GetActivityInfoRspOuterClass.GetActivityInfoRsp.newBuilder(); var resp = GetInvestigationMonsterRspOuterClass.GetInvestigationMonsterRsp.newBuilder();
cityIdListList.forEach(id -> resp.addAllMonsterList(worldDataManager.getInvestigationMonstersByCityId(player, id)));
this.setData(resp.build()); this.setData(resp.build());
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment