mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-11-30 06:13:52 +00:00
Support Boss Chest
This commit is contained in:
parent
5429469852
commit
717c2d1dd7
@ -79,6 +79,7 @@ public class GameData {
|
|||||||
private static final Int2ObjectMap<TowerFloorData> towerFloorDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<TowerFloorData> towerFloorDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<TowerLevelData> towerLevelDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<TowerLevelData> towerLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<TowerScheduleData> towerScheduleDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<TowerScheduleData> towerScheduleDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
private static final Int2ObjectMap<InvestigationMonsterData> investigationMonsterDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
// Cache
|
// Cache
|
||||||
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
|
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
|
||||||
@ -352,4 +353,8 @@ public class GameData {
|
|||||||
public static Int2ObjectMap<GatherData> getGatherDataMap() {
|
public static Int2ObjectMap<GatherData> getGatherDataMap() {
|
||||||
return gatherDataMap;
|
return gatherDataMap;
|
||||||
}
|
}
|
||||||
|
public static Int2ObjectMap<InvestigationMonsterData> getInvestigationMonsterDataMap() {
|
||||||
|
return investigationMonsterDataMap;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package emu.grasscutter.data.def;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GameResource;
|
||||||
|
import emu.grasscutter.data.ResourceType;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@ResourceType(name = "InvestigationMonsterConfigData.json")
|
||||||
|
@Data
|
||||||
|
public class InvestigationMonsterData extends GameResource {
|
||||||
|
private int Id;
|
||||||
|
private int CityId;
|
||||||
|
private List<Integer> MonsterIdList;
|
||||||
|
private List<Integer> GroupIdList;
|
||||||
|
private int RewardPreviewId;
|
||||||
|
private String MapMarkCreateType;
|
||||||
|
private String MonsterCategory;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return this.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
super.onLoad();
|
||||||
|
}
|
||||||
|
}
|
@ -125,7 +125,9 @@ public class DungeonChallenge {
|
|||||||
|
|
||||||
if (this.isSuccess()) {
|
if (this.isSuccess()) {
|
||||||
// Call success script event
|
// Call success script event
|
||||||
this.getScene().getScriptManager().callEvent(EventType.EVENT_CHALLENGE_SUCCESS, null);
|
this.getScene().getScriptManager().callEvent(EventType.EVENT_CHALLENGE_SUCCESS,
|
||||||
|
// TODO record the time in PARAM2 and used in action
|
||||||
|
new ScriptArgs().setParam2(100));
|
||||||
|
|
||||||
// Settle
|
// Settle
|
||||||
settle();
|
settle();
|
||||||
@ -139,8 +141,7 @@ public class DungeonChallenge {
|
|||||||
|
|
||||||
if(!stage){
|
if(!stage){
|
||||||
getScene().getScriptManager().callEvent(EventType.EVENT_DUNGEON_SETTLE,
|
getScene().getScriptManager().callEvent(EventType.EVENT_DUNGEON_SETTLE,
|
||||||
// TODO record the time in PARAM2 and used in action
|
new ScriptArgs(this.isSuccess() ? 1 : 0));
|
||||||
new ScriptArgs(this.isSuccess() ? 1 : 0, 100));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
|||||||
import emu.grasscutter.net.proto.VectorOuterClass.Vector;
|
import emu.grasscutter.net.proto.VectorOuterClass.Vector;
|
||||||
import emu.grasscutter.net.proto.WorktopInfoOuterClass.WorktopInfo;
|
import emu.grasscutter.net.proto.WorktopInfoOuterClass.WorktopInfo;
|
||||||
import emu.grasscutter.scripts.constants.EventType;
|
import emu.grasscutter.scripts.constants.EventType;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGadget;
|
||||||
import emu.grasscutter.scripts.data.ScriptArgs;
|
import emu.grasscutter.scripts.data.ScriptArgs;
|
||||||
import emu.grasscutter.server.packet.send.PacketGadgetStateNotify;
|
import emu.grasscutter.server.packet.send.PacketGadgetStateNotify;
|
||||||
import emu.grasscutter.utils.Position;
|
import emu.grasscutter.utils.Position;
|
||||||
@ -51,6 +52,7 @@ public class EntityGadget extends EntityBaseGadget {
|
|||||||
private int state;
|
private int state;
|
||||||
private int pointType;
|
private int pointType;
|
||||||
private GadgetContent content;
|
private GadgetContent content;
|
||||||
|
private SceneGadget metaGadget;
|
||||||
|
|
||||||
public EntityGadget(Scene scene, int gadgetId, Position pos) {
|
public EntityGadget(Scene scene, int gadgetId, Position pos) {
|
||||||
super(scene);
|
super(scene);
|
||||||
@ -99,6 +101,7 @@ public class EntityGadget extends EntityBaseGadget {
|
|||||||
public void updateState(int state){
|
public void updateState(int state){
|
||||||
this.setState(state);
|
this.setState(state);
|
||||||
this.getScene().broadcastPacket(new PacketGadgetStateNotify(this, state));
|
this.getScene().broadcastPacket(new PacketGadgetStateNotify(this, state));
|
||||||
|
getScene().getScriptManager().callEvent(EventType.EVENT_GADGET_STATE_CHANGE, new ScriptArgs(state, this.getConfigId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPointType() {
|
public int getPointType() {
|
||||||
@ -117,7 +120,15 @@ public class EntityGadget extends EntityBaseGadget {
|
|||||||
public void setContent(GadgetContent content) {
|
public void setContent(GadgetContent content) {
|
||||||
this.content = this.content == null ? content : this.content;
|
this.content = this.content == null ? content : this.content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SceneGadget getMetaGadget() {
|
||||||
|
return metaGadget;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMetaGadget(SceneGadget metaGadget) {
|
||||||
|
this.metaGadget = metaGadget;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO refactor
|
// TODO refactor
|
||||||
public void buildContent() {
|
public void buildContent() {
|
||||||
if (getContent() != null || getGadgetData() == null || getGadgetData().getType() == null) {
|
if (getContent() != null || getGadgetData() == null || getGadgetData().getType() == null) {
|
||||||
|
@ -1,53 +1,63 @@
|
|||||||
package emu.grasscutter.game.entity.gadget;
|
package emu.grasscutter.game.entity.gadget;
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.game.entity.EntityGadget;
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.net.proto.BossChestInfoOuterClass.BossChestInfo;
|
||||||
|
import emu.grasscutter.net.proto.InterOpTypeOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.InteractTypeOuterClass;
|
||||||
import emu.grasscutter.net.proto.InteractTypeOuterClass.InteractType;
|
import emu.grasscutter.net.proto.InteractTypeOuterClass.InteractType;
|
||||||
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
||||||
import emu.grasscutter.scripts.constants.ScriptGadgetState;
|
import emu.grasscutter.scripts.constants.ScriptGadgetState;
|
||||||
import emu.grasscutter.server.packet.send.PacketGadgetInteractRsp;
|
import emu.grasscutter.server.packet.send.PacketGadgetInteractRsp;
|
||||||
|
|
||||||
|
import static emu.grasscutter.net.proto.InterOpTypeOuterClass.InterOpType.INTER_OP_START;
|
||||||
|
|
||||||
public class GadgetChest extends GadgetContent {
|
public class GadgetChest extends GadgetContent {
|
||||||
|
|
||||||
public GadgetChest(EntityGadget gadget) {
|
public GadgetChest(EntityGadget gadget) {
|
||||||
super(gadget);
|
super(gadget);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onInteract(Player player) {
|
public boolean onInteract(Player player, InterOpTypeOuterClass.InterOpType opType) {
|
||||||
var chestRewardMap = getGadget().getScene().getWorld().getServer().getWorldDataManager().getChestRewardMap();
|
var chestInteractHandlerMap = getGadget().getScene().getWorld().getServer().getWorldDataManager().getChestInteractHandlerMap();
|
||||||
var chestReward = chestRewardMap.get(getGadget().getGadgetData().getJsonName());
|
var handler = chestInteractHandlerMap.get(getGadget().getGadgetData().getJsonName());
|
||||||
if (chestReward == null) {
|
if(handler == null){
|
||||||
Grasscutter.getLogger().warn("Could not found the config of this type of Chests {}", getGadget().getGadgetData().getJsonName());
|
Grasscutter.getLogger().warn("Could not found the handler of this type of Chests {}", getGadget().getGadgetData().getJsonName());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(opType == INTER_OP_START && handler.isTwoStep()){
|
||||||
|
player.sendPacket(new PacketGadgetInteractRsp(getGadget(), InteractType.INTERACT_OPEN_CHEST, INTER_OP_START));
|
||||||
|
return false;
|
||||||
|
}else{
|
||||||
|
var success = handler.onInteract(this, player);
|
||||||
|
if (!success){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
getGadget().updateState(ScriptGadgetState.ChestOpened);
|
||||||
|
player.sendPacket(new PacketGadgetInteractRsp(this.getGadget(), InteractTypeOuterClass.InteractType.INTERACT_OPEN_CHEST));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
player.earnExp(chestReward.getAdvExp());
|
|
||||||
player.getInventory().addItem(201, chestReward.getResin());
|
|
||||||
|
|
||||||
var mora = chestReward.getMora() * (1 + (player.getWorldLevel() - 1) * 0.5);
|
|
||||||
player.getInventory().addItem(202, (int)mora);
|
|
||||||
|
|
||||||
for(int i=0;i<chestReward.getContent().size();i++){
|
|
||||||
getGadget().getScene().addItemEntity(chestReward.getContent().get(i).getItemId(), chestReward.getContent().get(i).getCount(), getGadget());
|
|
||||||
}
|
|
||||||
|
|
||||||
var random = new Random(System.currentTimeMillis());
|
|
||||||
for(int i=0;i<chestReward.getRandomCount();i++){
|
|
||||||
var index = random.nextInt(chestReward.getRandomContent().size());
|
|
||||||
var item = chestReward.getRandomContent().get(index);
|
|
||||||
getGadget().getScene().addItemEntity(item.getItemId(), item.getCount(), getGadget());
|
|
||||||
}
|
|
||||||
|
|
||||||
getGadget().updateState(ScriptGadgetState.ChestOpened);
|
|
||||||
player.sendPacket(new PacketGadgetInteractRsp(getGadget(), InteractType.INTERACT_OPEN_CHEST));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onBuildProto(SceneGadgetInfo.Builder gadgetInfo) {
|
public void onBuildProto(SceneGadgetInfo.Builder gadgetInfo) {
|
||||||
|
if(getGadget().getMetaGadget() == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bossChest = getGadget().getMetaGadget().boss_chest;
|
||||||
|
if(bossChest != null){
|
||||||
|
var players = getGadget().getScene().getPlayers().stream().map(Player::getUid).toList();
|
||||||
|
|
||||||
|
gadgetInfo.setBossChest(BossChestInfo.newBuilder()
|
||||||
|
.setMonsterConfigId(bossChest.monster_config_id)
|
||||||
|
.setResin(bossChest.resin)
|
||||||
|
.addAllQualifyUidList(players)
|
||||||
|
.addAllRemainUidList(players)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package emu.grasscutter.game.entity.gadget;
|
|||||||
|
|
||||||
import emu.grasscutter.game.entity.EntityGadget;
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.net.proto.InterOpTypeOuterClass;
|
||||||
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
||||||
|
|
||||||
public abstract class GadgetContent {
|
public abstract class GadgetContent {
|
||||||
@ -15,7 +16,7 @@ public abstract class GadgetContent {
|
|||||||
return gadget;
|
return gadget;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract boolean onInteract(Player player);
|
public abstract boolean onInteract(Player player, InterOpTypeOuterClass.InterOpType opType);
|
||||||
|
|
||||||
public abstract void onBuildProto(SceneGadgetInfo.Builder gadgetInfo);
|
public abstract void onBuildProto(SceneGadgetInfo.Builder gadgetInfo);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import emu.grasscutter.game.inventory.GameItem;
|
|||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.props.ActionReason;
|
import emu.grasscutter.game.props.ActionReason;
|
||||||
import emu.grasscutter.net.proto.GatherGadgetInfoOuterClass.GatherGadgetInfo;
|
import emu.grasscutter.net.proto.GatherGadgetInfoOuterClass.GatherGadgetInfo;
|
||||||
|
import emu.grasscutter.net.proto.InterOpTypeOuterClass;
|
||||||
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
||||||
|
|
||||||
public class GadgetGatherPoint extends GadgetContent {
|
public class GadgetGatherPoint extends GadgetContent {
|
||||||
@ -25,7 +26,7 @@ public class GadgetGatherPoint extends GadgetContent {
|
|||||||
return getGatherData().getItemId();
|
return getGatherData().getItemId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onInteract(Player player) {
|
public boolean onInteract(Player player, InterOpTypeOuterClass.InterOpType opType) {
|
||||||
GameItem item = new GameItem(gatherData.getItemId(), 1);
|
GameItem item = new GameItem(gatherData.getItemId(), 1);
|
||||||
|
|
||||||
player.getInventory().addItem(item, ActionReason.Gather);
|
player.getInventory().addItem(item, ActionReason.Gather);
|
||||||
|
@ -2,6 +2,7 @@ package emu.grasscutter.game.entity.gadget;
|
|||||||
|
|
||||||
import emu.grasscutter.game.entity.EntityGadget;
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.net.proto.InterOpTypeOuterClass;
|
||||||
import emu.grasscutter.net.proto.InteractTypeOuterClass.InteractType;
|
import emu.grasscutter.net.proto.InteractTypeOuterClass.InteractType;
|
||||||
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
||||||
import emu.grasscutter.server.packet.send.PacketGadgetInteractRsp;
|
import emu.grasscutter.server.packet.send.PacketGadgetInteractRsp;
|
||||||
@ -12,7 +13,7 @@ public class GadgetRewardStatue extends GadgetContent {
|
|||||||
super(gadget);
|
super(gadget);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onInteract(Player player) {
|
public boolean onInteract(Player player, InterOpTypeOuterClass.InterOpType opType) {
|
||||||
if (player.getScene().getChallenge() != null) {
|
if (player.getScene().getChallenge() != null) {
|
||||||
player.getScene().getChallenge().getStatueDrops(player);
|
player.getScene().getChallenge().getStatueDrops(player);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import java.util.Arrays;
|
|||||||
|
|
||||||
import emu.grasscutter.game.entity.EntityGadget;
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.net.proto.InterOpTypeOuterClass;
|
||||||
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
||||||
import emu.grasscutter.net.proto.WorktopInfoOuterClass.WorktopInfo;
|
import emu.grasscutter.net.proto.WorktopInfoOuterClass.WorktopInfo;
|
||||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||||
@ -34,7 +35,7 @@ public class GadgetWorktop extends GadgetContent {
|
|||||||
this.worktopOptions.remove(option);
|
this.worktopOptions.remove(option);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onInteract(Player player) {
|
public boolean onInteract(Player player, InterOpTypeOuterClass.InterOpType opType) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
package emu.grasscutter.game.entity.gadget.chest;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.common.ItemParamData;
|
||||||
|
import emu.grasscutter.game.entity.gadget.GadgetChest;
|
||||||
|
import emu.grasscutter.game.inventory.GameItem;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.game.props.ActionReason;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketGadgetAutoPickDropInfoNotify;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BossChestInteractHandler implements ChestInteractHandler{
|
||||||
|
@Override
|
||||||
|
public boolean isTwoStep() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onInteract(GadgetChest chest, Player player) {
|
||||||
|
var worldDataManager = chest.getGadget().getScene().getWorld().getServer().getWorldDataManager();
|
||||||
|
var monster = chest.getGadget().getMetaGadget().group.monsters.get(chest.getGadget().getMetaGadget().boss_chest.monster_config_id);
|
||||||
|
var reward = worldDataManager.getRewardByBossId(monster.monster_id);
|
||||||
|
|
||||||
|
List<GameItem> rewards = new ArrayList<>();
|
||||||
|
for (ItemParamData param : reward.getPreviewItems()) {
|
||||||
|
rewards.add(new GameItem(param.getId(), Math.max(param.getCount(), 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
player.getInventory().addItems(rewards, ActionReason.OpenWorldBossChest);
|
||||||
|
player.sendPacket(new PacketGadgetAutoPickDropInfoNotify(rewards));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package emu.grasscutter.game.entity.gadget.chest;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.entity.gadget.GadgetChest;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
|
||||||
|
public interface ChestInteractHandler {
|
||||||
|
|
||||||
|
boolean isTwoStep();
|
||||||
|
|
||||||
|
boolean onInteract(GadgetChest chest, Player player);
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package emu.grasscutter.game.entity.gadget.chest;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.entity.gadget.GadgetChest;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.game.world.ChestReward;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class NormalChestInteractHandler implements ChestInteractHandler {
|
||||||
|
private final ChestReward chestReward;
|
||||||
|
|
||||||
|
public NormalChestInteractHandler(ChestReward rewardData){
|
||||||
|
this.chestReward = rewardData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTwoStep() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onInteract(GadgetChest chest, Player player) {
|
||||||
|
player.earnExp(chestReward.getAdvExp());
|
||||||
|
player.getInventory().addItem(201, chestReward.getResin());
|
||||||
|
|
||||||
|
var mora = chestReward.getMora() * (1 + (player.getWorldLevel() - 1) * 0.5);
|
||||||
|
player.getInventory().addItem(202, (int)mora);
|
||||||
|
|
||||||
|
for(int i=0;i<chestReward.getContent().size();i++){
|
||||||
|
chest.getGadget().getScene().addItemEntity(chestReward.getContent().get(i).getItemId(), chestReward.getContent().get(i).getCount(), chest.getGadget());
|
||||||
|
}
|
||||||
|
|
||||||
|
var random = new Random(System.currentTimeMillis());
|
||||||
|
for(int i=0;i<chestReward.getRandomCount();i++){
|
||||||
|
var index = random.nextInt(chestReward.getRandomContent().size());
|
||||||
|
var item = chestReward.getRandomContent().get(index);
|
||||||
|
chest.getGadget().getScene().addItemEntity(item.getItemId(), item.getCount(), chest.getGadget());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -25,11 +25,8 @@ import emu.grasscutter.game.mail.MailHandler;
|
|||||||
import emu.grasscutter.game.managers.StaminaManager.StaminaManager;
|
import emu.grasscutter.game.managers.StaminaManager.StaminaManager;
|
||||||
import emu.grasscutter.game.managers.SotSManager;
|
import emu.grasscutter.game.managers.SotSManager;
|
||||||
import emu.grasscutter.game.props.ActionReason;
|
import emu.grasscutter.game.props.ActionReason;
|
||||||
import emu.grasscutter.game.props.EntityType;
|
|
||||||
import emu.grasscutter.game.props.PlayerProperty;
|
import emu.grasscutter.game.props.PlayerProperty;
|
||||||
import emu.grasscutter.game.props.SceneType;
|
import emu.grasscutter.game.props.SceneType;
|
||||||
import emu.grasscutter.game.quest.GameMainQuest;
|
|
||||||
import emu.grasscutter.game.quest.GameQuest;
|
|
||||||
import emu.grasscutter.game.quest.QuestManager;
|
import emu.grasscutter.game.quest.QuestManager;
|
||||||
import emu.grasscutter.game.shop.ShopLimit;
|
import emu.grasscutter.game.shop.ShopLimit;
|
||||||
import emu.grasscutter.game.managers.MapMarkManager.*;
|
import emu.grasscutter.game.managers.MapMarkManager.*;
|
||||||
@ -47,7 +44,6 @@ import emu.grasscutter.net.proto.OnlinePlayerInfoOuterClass.OnlinePlayerInfo;
|
|||||||
import emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo;
|
import emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo;
|
||||||
import emu.grasscutter.net.proto.ProfilePictureOuterClass.ProfilePicture;
|
import emu.grasscutter.net.proto.ProfilePictureOuterClass.ProfilePicture;
|
||||||
import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
|
import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
|
||||||
import emu.grasscutter.scripts.constants.ScriptGadgetState;
|
|
||||||
import emu.grasscutter.server.event.player.PlayerJoinEvent;
|
import emu.grasscutter.server.event.player.PlayerJoinEvent;
|
||||||
import emu.grasscutter.server.event.player.PlayerQuitEvent;
|
import emu.grasscutter.server.event.player.PlayerQuitEvent;
|
||||||
import emu.grasscutter.server.game.GameServer;
|
import emu.grasscutter.server.game.GameServer;
|
||||||
@ -890,7 +886,7 @@ public class Player {
|
|||||||
return this.getMailHandler().replaceMailByIndex(index, message);
|
return this.getMailHandler().replaceMailByIndex(index, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void interactWith(int gadgetEntityId) {
|
public void interactWith(int gadgetEntityId, InterOpTypeOuterClass.InterOpType opType) {
|
||||||
GameEntity entity = getScene().getEntityById(gadgetEntityId);
|
GameEntity entity = getScene().getEntityById(gadgetEntityId);
|
||||||
|
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
@ -923,7 +919,7 @@ public class Player {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean shouldDelete = gadget.getContent().onInteract(this);
|
boolean shouldDelete = gadget.getContent().onInteract(this, opType);
|
||||||
|
|
||||||
if (shouldDelete) {
|
if (shouldDelete) {
|
||||||
entity.getScene().removeEntity(entity);
|
entity.getScene().removeEntity(entity);
|
||||||
|
@ -3,42 +3,60 @@ package emu.grasscutter.game.world;
|
|||||||
import com.google.gson.reflect.TypeToken;
|
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.def.RewardPreviewData;
|
||||||
|
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.server.game.GameServer;
|
import emu.grasscutter.server.game.GameServer;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
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 static emu.grasscutter.Configuration.DATA;
|
|
||||||
|
|
||||||
public class WorldDataManager {
|
public class WorldDataManager {
|
||||||
private final GameServer gameServer;
|
private final GameServer gameServer;
|
||||||
private final Map<String, ChestReward> chestRewardMap;
|
private final Map<String, ChestInteractHandler> chestInteractHandlerMap; // chestType-Handler
|
||||||
|
|
||||||
public WorldDataManager(GameServer gameServer){
|
public WorldDataManager(GameServer gameServer){
|
||||||
this.gameServer = gameServer;
|
this.gameServer = gameServer;
|
||||||
this.chestRewardMap = new HashMap<>();
|
this.chestInteractHandlerMap = new HashMap<>();
|
||||||
load();
|
loadChestConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void load(){
|
public synchronized void loadChestConfig(){
|
||||||
|
// set the special chest first
|
||||||
|
chestInteractHandlerMap.put("SceneObj_Chest_Flora", new BossChestInteractHandler());
|
||||||
|
|
||||||
try(InputStream is = DataLoader.load("ChestReward.json"); InputStreamReader isr = new InputStreamReader(is)) {
|
try(InputStream is = DataLoader.load("ChestReward.json"); InputStreamReader isr = new InputStreamReader(is)) {
|
||||||
List<ChestReward> chestReward = Grasscutter.getGsonFactory().fromJson(
|
List<ChestReward> chestReward = Grasscutter.getGsonFactory().fromJson(
|
||||||
isr,
|
isr,
|
||||||
TypeToken.getParameterized(List.class, ChestReward.class).getType());
|
TypeToken.getParameterized(List.class, ChestReward.class).getType());
|
||||||
|
|
||||||
chestReward.forEach(reward ->
|
chestReward.forEach(reward ->
|
||||||
reward.getObjNames().forEach(name -> chestRewardMap.put(name, reward)));
|
reward.getObjNames().forEach(
|
||||||
|
name -> chestInteractHandlerMap.putIfAbsent(name, new NormalChestInteractHandler(reward))));
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Grasscutter.getLogger().error("Unable to load chest reward config.", e);
|
Grasscutter.getLogger().error("Unable to load chest reward config.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, ChestReward> getChestRewardMap() {
|
public Map<String, ChestInteractHandler> getChestInteractHandlerMap() {
|
||||||
return chestRewardMap;
|
return chestInteractHandlerMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RewardPreviewData getRewardByBossId(int monsterId){
|
||||||
|
var investigationMonsterData = GameData.getInvestigationMonsterDataMap().values().parallelStream()
|
||||||
|
.filter(imd -> imd.getMonsterIdList() != null && !imd.getMonsterIdList().isEmpty())
|
||||||
|
.filter(imd -> imd.getMonsterIdList().get(0) == monsterId)
|
||||||
|
.findFirst();
|
||||||
|
|
||||||
|
if(investigationMonsterData.isEmpty()){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return GameData.getRewardPreviewDataMap().get(investigationMonsterData.get().getRewardPreviewId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import emu.grasscutter.scripts.constants.EventType;
|
|||||||
import emu.grasscutter.scripts.data.*;
|
import emu.grasscutter.scripts.data.*;
|
||||||
import emu.grasscutter.scripts.service.ScriptMonsterSpawnService;
|
import emu.grasscutter.scripts.service.ScriptMonsterSpawnService;
|
||||||
import emu.grasscutter.scripts.service.ScriptMonsterTideService;
|
import emu.grasscutter.scripts.service.ScriptMonsterTideService;
|
||||||
|
import io.netty.util.concurrent.FastThreadLocalThread;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import org.luaj.vm2.LuaError;
|
import org.luaj.vm2.LuaError;
|
||||||
@ -21,6 +22,10 @@ import org.luaj.vm2.LuaValue;
|
|||||||
import org.luaj.vm2.lib.jse.CoerceJavaToLua;
|
import org.luaj.vm2.lib.jse.CoerceJavaToLua;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.LinkedBlockingDeque;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class SceneScriptManager {
|
public class SceneScriptManager {
|
||||||
private final Scene scene;
|
private final Scene scene;
|
||||||
@ -43,6 +48,12 @@ public class SceneScriptManager {
|
|||||||
* blockid - loaded groupSet
|
* blockid - loaded groupSet
|
||||||
*/
|
*/
|
||||||
private Int2ObjectMap<Set<SceneGroup>> loadedGroupSetPerBlock;
|
private Int2ObjectMap<Set<SceneGroup>> loadedGroupSetPerBlock;
|
||||||
|
public static final ExecutorService eventExecutor;
|
||||||
|
static {
|
||||||
|
eventExecutor = new ThreadPoolExecutor(4, 4,
|
||||||
|
60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(100),
|
||||||
|
FastThreadLocalThread::new, new ThreadPoolExecutor.AbortPolicy());
|
||||||
|
}
|
||||||
public SceneScriptManager(Scene scene) {
|
public SceneScriptManager(Scene scene) {
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this.triggers = new HashMap<>();
|
this.triggers = new HashMap<>();
|
||||||
@ -211,7 +222,7 @@ public class SceneScriptManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var toCreate = gadgets.stream()
|
var toCreate = gadgets.stream()
|
||||||
.map(g -> createGadget(g.groupId, group.block_id, g))
|
.map(g -> createGadget(g.group.id, group.block_id, g))
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.toList();
|
.toList();
|
||||||
this.addEntities(toCreate);
|
this.addEntities(toCreate);
|
||||||
@ -254,8 +265,17 @@ public class SceneScriptManager {
|
|||||||
getScene().addEntity(createMonster(group.id, group.block_id, group.monsters.get(configId)));
|
getScene().addEntity(createMonster(group.id, group.block_id, group.monsters.get(configId)));
|
||||||
}
|
}
|
||||||
// Events
|
// Events
|
||||||
|
public void callEvent(int eventType, ScriptArgs params){
|
||||||
public void callEvent(int eventType, ScriptArgs params) {
|
/**
|
||||||
|
* We use ThreadLocal to trans SceneScriptManager context to ScriptLib, to avoid eval script for every groups' trigger in every scene instances.
|
||||||
|
* But when callEvent is called in a ScriptLib func, it may cause NPE because the inner call cleans the ThreadLocal so that outer call could not get it.
|
||||||
|
* e.g. CallEvent -> set -> ScriptLib.xxx -> CallEvent -> set -> remove -> NPE -> (remove)
|
||||||
|
* So we use thread pool to clean the stack to avoid this new issue.
|
||||||
|
*/
|
||||||
|
eventExecutor.submit(() -> this.realCallEvent(eventType, params));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void realCallEvent(int eventType, ScriptArgs params) {
|
||||||
try{
|
try{
|
||||||
ScriptLoader.getScriptLib().setSceneScriptManager(this);
|
ScriptLoader.getScriptLib().setSceneScriptManager(this);
|
||||||
for (SceneTrigger trigger : this.getTriggersByEvent(eventType)) {
|
for (SceneTrigger trigger : this.getTriggersByEvent(eventType)) {
|
||||||
@ -282,7 +302,7 @@ public class SceneScriptManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public LuaValue callScriptFunc(String funcName, SceneGroup group, ScriptArgs params){
|
private LuaValue callScriptFunc(String funcName, SceneGroup group, ScriptArgs params){
|
||||||
LuaValue funcLua = null;
|
LuaValue funcLua = null;
|
||||||
if (funcName != null && !funcName.isEmpty()) {
|
if (funcName != null && !funcName.isEmpty()) {
|
||||||
funcLua = (LuaValue) group.getBindings().get(funcName);
|
funcLua = (LuaValue) group.getBindings().get(funcName);
|
||||||
@ -332,10 +352,8 @@ public class SceneScriptManager {
|
|||||||
entity.getRotation().set(g.rot);
|
entity.getRotation().set(g.rot);
|
||||||
entity.setState(g.state);
|
entity.setState(g.state);
|
||||||
entity.setPointType(g.point_type);
|
entity.setPointType(g.point_type);
|
||||||
|
entity.setMetaGadget(g);
|
||||||
entity.buildContent();
|
entity.buildContent();
|
||||||
|
|
||||||
// Lua event
|
|
||||||
this.callEvent(EventType.EVENT_GADGET_CREATE, new ScriptArgs(entity.getConfigId()));
|
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import emu.grasscutter.game.entity.gadget.GadgetWorktop;
|
|||||||
import emu.grasscutter.scripts.data.SceneGroup;
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
import emu.grasscutter.scripts.data.SceneRegion;
|
import emu.grasscutter.scripts.data.SceneRegion;
|
||||||
import emu.grasscutter.server.packet.send.PacketCanUseSkillNotify;
|
import emu.grasscutter.server.packet.send.PacketCanUseSkillNotify;
|
||||||
import emu.grasscutter.server.packet.send.PacketGadgetStateNotify;
|
|
||||||
import emu.grasscutter.server.packet.send.PacketWorktopOptionNotify;
|
import emu.grasscutter.server.packet.send.PacketWorktopOptionNotify;
|
||||||
import io.netty.util.concurrent.FastThreadLocal;
|
import io.netty.util.concurrent.FastThreadLocal;
|
||||||
import org.luaj.vm2.LuaTable;
|
import org.luaj.vm2.LuaTable;
|
||||||
@ -16,7 +15,6 @@ import org.luaj.vm2.LuaValue;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class ScriptLib {
|
public class ScriptLib {
|
||||||
@ -68,34 +66,24 @@ public class ScriptLib {
|
|||||||
if (entity.isEmpty()) {
|
if (entity.isEmpty()) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(entity.get() instanceof EntityGadget)) {
|
if (entity.get() instanceof EntityGadget entityGadget) {
|
||||||
return 1;
|
entityGadget.updateState(gadgetState);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityGadget gadget = (EntityGadget) entity.get();
|
return 1;
|
||||||
gadget.setState(gadgetState);
|
|
||||||
|
|
||||||
getSceneScriptManager().getScene().broadcastPacket(new PacketGadgetStateNotify(gadget, gadgetState));
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int SetGroupGadgetStateByConfigId(int groupId, int configId, int gadgetState) {
|
public int SetGroupGadgetStateByConfigId(int groupId, int configId, int gadgetState) {
|
||||||
logger.debug("[LUA] Call SetGroupGadgetStateByConfigId with {},{},{}",
|
logger.debug("[LUA] Call SetGroupGadgetStateByConfigId with {},{},{}",
|
||||||
groupId,configId,gadgetState);
|
groupId,configId,gadgetState);
|
||||||
List<GameEntity> list = getSceneScriptManager().getScene().getEntities().values().stream()
|
|
||||||
.filter(e -> e.getGroupId() == groupId).toList();
|
getSceneScriptManager().getScene().getEntities().values().stream()
|
||||||
|
.filter(e -> e.getGroupId() == groupId)
|
||||||
for (GameEntity entity : list) {
|
.filter(e -> e instanceof EntityGadget)
|
||||||
if (!(entity instanceof EntityGadget)) {
|
.map(e -> (EntityGadget)e)
|
||||||
continue;
|
.forEach(e -> e.updateState(gadgetState));
|
||||||
}
|
|
||||||
|
|
||||||
EntityGadget gadget = (EntityGadget) entity;
|
|
||||||
gadget.setState(gadgetState);
|
|
||||||
|
|
||||||
getSceneScriptManager().getScene().broadcastPacket(new PacketGadgetStateNotify(gadget, gadgetState));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -450,8 +438,9 @@ public class ScriptLib {
|
|||||||
|
|
||||||
if (entity instanceof EntityGadget entityGadget) {
|
if (entity instanceof EntityGadget entityGadget) {
|
||||||
entityGadget.updateState(state);
|
entityGadget.updateState(state);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
package emu.grasscutter.scripts.data;
|
||||||
|
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
public class SceneBossChest {
|
||||||
|
public int life_time;
|
||||||
|
public int monster_config_id;
|
||||||
|
public int resin;
|
||||||
|
public int take_num;
|
||||||
|
}
|
@ -9,4 +9,5 @@ public class SceneGadget extends SceneObject{
|
|||||||
public int gadget_id;
|
public int gadget_id;
|
||||||
public int state;
|
public int state;
|
||||||
public int point_type;
|
public int point_type;
|
||||||
|
public SceneBossChest boss_chest;
|
||||||
}
|
}
|
||||||
|
@ -98,11 +98,11 @@ public class SceneGroup {
|
|||||||
// Set
|
// Set
|
||||||
monsters = ScriptLoader.getSerializer().toList(SceneMonster.class, bindings.get("monsters")).stream()
|
monsters = ScriptLoader.getSerializer().toList(SceneMonster.class, bindings.get("monsters")).stream()
|
||||||
.collect(Collectors.toMap(x -> x.config_id, y -> y));
|
.collect(Collectors.toMap(x -> x.config_id, y -> y));
|
||||||
monsters.values().forEach(m -> m.groupId = id);
|
monsters.values().forEach(m -> m.group = this);
|
||||||
|
|
||||||
gadgets = ScriptLoader.getSerializer().toList(SceneGadget.class, bindings.get("gadgets")).stream()
|
gadgets = ScriptLoader.getSerializer().toList(SceneGadget.class, bindings.get("gadgets")).stream()
|
||||||
.collect(Collectors.toMap(x -> x.config_id, y -> y));
|
.collect(Collectors.toMap(x -> x.config_id, y -> y));
|
||||||
gadgets.values().forEach(m -> m.groupId = id);
|
gadgets.values().forEach(m -> m.group = this);
|
||||||
|
|
||||||
triggers = ScriptLoader.getSerializer().toList(SceneTrigger.class, bindings.get("triggers")).stream()
|
triggers = ScriptLoader.getSerializer().toList(SceneTrigger.class, bindings.get("triggers")).stream()
|
||||||
.collect(Collectors.toMap(x -> x.name, y -> y));
|
.collect(Collectors.toMap(x -> x.name, y -> y));
|
||||||
|
@ -16,5 +16,5 @@ public class SceneObject {
|
|||||||
/**
|
/**
|
||||||
* not set by lua
|
* not set by lua
|
||||||
*/
|
*/
|
||||||
public transient int groupId;
|
public transient SceneGroup group;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ public class HandlerGadgetInteractReq extends PacketHandler {
|
|||||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||||
GadgetInteractReq req = GadgetInteractReq.parseFrom(payload);
|
GadgetInteractReq req = GadgetInteractReq.parseFrom(payload);
|
||||||
|
|
||||||
session.getPlayer().interactWith(req.getGadgetEntityId());
|
session.getPlayer().interactWith(req.getGadgetEntityId(), req.getOpType());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
package emu.grasscutter.server.packet.recv;
|
||||||
|
|
||||||
|
import emu.grasscutter.net.packet.Opcodes;
|
||||||
|
import emu.grasscutter.net.packet.PacketHandler;
|
||||||
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
|
import emu.grasscutter.net.proto.GetInvestigationMonsterReqOuterClass;
|
||||||
|
import emu.grasscutter.server.game.GameSession;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketGetInvestigationMonsterRsp;
|
||||||
|
|
||||||
|
@Opcodes(PacketOpcodes.GetInvestigationMonsterReq)
|
||||||
|
public class HandlerGetInvestigationMonsterReq extends PacketHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||||
|
var req = GetInvestigationMonsterReqOuterClass.GetInvestigationMonsterReq.parseFrom(payload);
|
||||||
|
|
||||||
|
session.send(new PacketGetInvestigationMonsterRsp(req.getCityIdListList()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,20 +4,27 @@ import emu.grasscutter.game.entity.EntityBaseGadget;
|
|||||||
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.GadgetInteractRspOuterClass.GadgetInteractRsp;
|
import emu.grasscutter.net.proto.GadgetInteractRspOuterClass.GadgetInteractRsp;
|
||||||
|
import emu.grasscutter.net.proto.InterOpTypeOuterClass;
|
||||||
import emu.grasscutter.net.proto.InteractTypeOuterClass.InteractType;
|
import emu.grasscutter.net.proto.InteractTypeOuterClass.InteractType;
|
||||||
import emu.grasscutter.net.proto.RetcodeOuterClass;
|
import emu.grasscutter.net.proto.RetcodeOuterClass;
|
||||||
|
|
||||||
public class PacketGadgetInteractRsp extends BasePacket {
|
public class PacketGadgetInteractRsp extends BasePacket {
|
||||||
public PacketGadgetInteractRsp(EntityBaseGadget gadget, InteractType interact) {
|
public PacketGadgetInteractRsp(EntityBaseGadget gadget, InteractType interact) {
|
||||||
|
this(gadget, interact, null);
|
||||||
|
}
|
||||||
|
public PacketGadgetInteractRsp(EntityBaseGadget gadget, InteractType interact, InterOpTypeOuterClass.InterOpType opType) {
|
||||||
super(PacketOpcodes.GadgetInteractRsp);
|
super(PacketOpcodes.GadgetInteractRsp);
|
||||||
|
|
||||||
GadgetInteractRsp proto = GadgetInteractRsp.newBuilder()
|
var proto = GadgetInteractRsp.newBuilder()
|
||||||
.setGadgetEntityId(gadget.getId())
|
.setGadgetEntityId(gadget.getId())
|
||||||
.setInteractType(interact)
|
.setInteractType(interact)
|
||||||
.setGadgetId(gadget.getGadgetId())
|
.setGadgetId(gadget.getGadgetId());
|
||||||
.build();
|
|
||||||
|
if(opType != null){
|
||||||
|
proto.setOpType(opType);
|
||||||
|
}
|
||||||
|
|
||||||
this.setData(proto);
|
this.setData(proto.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public PacketGadgetInteractRsp() {
|
public PacketGadgetInteractRsp() {
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
package emu.grasscutter.server.packet.send;
|
||||||
|
|
||||||
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
|
import emu.grasscutter.net.proto.GetActivityInfoRspOuterClass;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PacketGetInvestigationMonsterRsp extends BasePacket {
|
||||||
|
|
||||||
|
public PacketGetInvestigationMonsterRsp(List<Integer> cityIdListList) {
|
||||||
|
super(PacketOpcodes.GetInvestigationMonsterRsp);
|
||||||
|
|
||||||
|
var resp = GetActivityInfoRspOuterClass.GetActivityInfoRsp.newBuilder();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
this.setData(resp.build());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user