MonsterInvestigation (boss icon in map)

This commit is contained in:
Akka
2022-06-18 19:07:39 +08:00
committed by Melledy
parent 80c61466e3
commit 706dc5e4c7
7 changed files with 159 additions and 13 deletions

View File

@@ -4,10 +4,16 @@ import com.google.gson.reflect.TypeToken;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.DataLoader;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.InvestigationMonsterData;
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.ChestInteractHandler;
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 java.io.InputStream;
@@ -15,14 +21,19 @@ import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
public class WorldDataManager {
private final GameServer gameServer;
private final Map<String, ChestInteractHandler> chestInteractHandlerMap; // chestType-Handler
private final Map<String, SceneGroup> sceneInvestigationGroupMap; // <sceneId_groupId, Group>
public WorldDataManager(GameServer gameServer){
this.gameServer = gameServer;
this.chestInteractHandlerMap = new HashMap<>();
this.sceneInvestigationGroupMap = new ConcurrentHashMap<>();
loadChestConfig();
}
@@ -59,4 +70,80 @@ public class WorldDataManager {
}
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();
}
}