mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-01-28 03:13:12 +08:00
Add Support of Item Combine (#513)
* Add Support of Item Combine * Add Support of Item Combine Co-authored-by: Melledy <52122272+Melledy@users.noreply.github.com>
This commit is contained in:
parent
6943360f4a
commit
823040be56
@ -66,8 +66,9 @@ public class GameData {
|
|||||||
private static final Int2ObjectMap<DailyDungeonData> dailyDungeonDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<DailyDungeonData> dailyDungeonDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<DungeonData> dungeonDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<DungeonData> dungeonDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<ShopGoodsData> shopGoodsDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<ShopGoodsData> shopGoodsDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
private static final Int2ObjectMap<CombineData> combineDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<RewardPreviewData> rewardPreviewDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<RewardPreviewData> rewardPreviewDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
// Cache
|
// Cache
|
||||||
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
|
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
|
||||||
private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
|
private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
|
||||||
@ -301,9 +302,6 @@ public class GameData {
|
|||||||
return shopGoods;
|
return shopGoods;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the rewardpreviewdatamap
|
|
||||||
*/
|
|
||||||
public static Int2ObjectMap<RewardPreviewData> getRewardPreviewDataMap() {
|
public static Int2ObjectMap<RewardPreviewData> getRewardPreviewDataMap() {
|
||||||
return rewardPreviewDataMap;
|
return rewardPreviewDataMap;
|
||||||
}
|
}
|
||||||
@ -311,4 +309,8 @@ public class GameData {
|
|||||||
public static IntList getScenePointIdList() {
|
public static IntList getScenePointIdList() {
|
||||||
return scenePointIdList;
|
return scenePointIdList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Int2ObjectMap<CombineData> getCombineDataMap() {
|
||||||
|
return combineDataMap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,173 @@
|
|||||||
package emu.grasscutter.data.def;
|
package emu.grasscutter.data.def;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GameResource;
|
||||||
import emu.grasscutter.data.ResourceType;
|
import emu.grasscutter.data.ResourceType;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ResourceType(name = "CombineExcelConfigData.json")
|
@ResourceType(name = "CombineExcelConfigData.json")
|
||||||
public class CombineData {
|
public class CombineData extends GameResource {
|
||||||
|
|
||||||
|
private int CombineId;
|
||||||
|
|
||||||
|
private int PlayerLevel;
|
||||||
|
|
||||||
|
private boolean IsDefaultShow;
|
||||||
|
|
||||||
|
private int CombineType;
|
||||||
|
|
||||||
|
private int SubCombineType;
|
||||||
|
|
||||||
|
private int ResultItemId;
|
||||||
|
|
||||||
|
private int ResultItemCount;
|
||||||
|
|
||||||
|
private int ScoinCost;
|
||||||
|
|
||||||
|
private List<CombineItemPair> RandomItems;
|
||||||
|
|
||||||
|
private List<CombineItemPair> MaterialItems;
|
||||||
|
|
||||||
|
private long EffectDescTextMapHash;
|
||||||
|
|
||||||
|
private String RecipeType;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return this.CombineId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
super.onLoad();
|
||||||
|
// clean data
|
||||||
|
RandomItems = RandomItems.stream().filter(item -> item.Id > 0).collect(Collectors.toList());
|
||||||
|
MaterialItems = MaterialItems.stream().filter(item -> item.Id > 0).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CombineItemPair {
|
||||||
|
|
||||||
|
private int Id;
|
||||||
|
|
||||||
|
private int Count;
|
||||||
|
|
||||||
|
public CombineItemPair(int id, int count) {
|
||||||
|
Id = id;
|
||||||
|
Count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
Id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCount() {
|
||||||
|
return Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCount(int count) {
|
||||||
|
Count = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCombineId() {
|
||||||
|
return CombineId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCombineId(int combineId) {
|
||||||
|
CombineId = combineId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPlayerLevel() {
|
||||||
|
return PlayerLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlayerLevel(int playerLevel) {
|
||||||
|
PlayerLevel = playerLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDefaultShow() {
|
||||||
|
return IsDefaultShow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultShow(boolean defaultShow) {
|
||||||
|
IsDefaultShow = defaultShow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCombineType() {
|
||||||
|
return CombineType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCombineType(int combineType) {
|
||||||
|
CombineType = combineType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSubCombineType() {
|
||||||
|
return SubCombineType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubCombineType(int subCombineType) {
|
||||||
|
SubCombineType = subCombineType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getResultItemId() {
|
||||||
|
return ResultItemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResultItemId(int resultItemId) {
|
||||||
|
ResultItemId = resultItemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getResultItemCount() {
|
||||||
|
return ResultItemCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResultItemCount(int resultItemCount) {
|
||||||
|
ResultItemCount = resultItemCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getScoinCost() {
|
||||||
|
return ScoinCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScoinCost(int scoinCost) {
|
||||||
|
ScoinCost = scoinCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CombineItemPair> getRandomItems() {
|
||||||
|
return RandomItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRandomItems(List<CombineItemPair> randomItems) {
|
||||||
|
RandomItems = randomItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CombineItemPair> getMaterialItems() {
|
||||||
|
return MaterialItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaterialItems(List<CombineItemPair> materialItems) {
|
||||||
|
MaterialItems = materialItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getEffectDescTextMapHash() {
|
||||||
|
return EffectDescTextMapHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEffectDescTextMapHash(long effectDescTextMapHash) {
|
||||||
|
EffectDescTextMapHash = effectDescTextMapHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecipeType() {
|
||||||
|
return RecipeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecipeType(String recipeType) {
|
||||||
|
RecipeType = recipeType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,83 @@
|
|||||||
|
package emu.grasscutter.game.combine;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GameData;
|
||||||
|
import emu.grasscutter.data.def.CombineData;
|
||||||
|
import emu.grasscutter.game.inventory.ItemType;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.net.proto.RetcodeOuterClass;
|
||||||
|
import emu.grasscutter.server.game.GameServer;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketCombineRsp;
|
||||||
|
import it.unimi.dsi.fastutil.Pair;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CombineManger {
|
||||||
|
private final GameServer gameServer;
|
||||||
|
|
||||||
|
public GameServer getGameServer() {
|
||||||
|
return gameServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CombineManger(GameServer gameServer) {
|
||||||
|
this.gameServer = gameServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CombineResult combineItem(Player player, int cid, int count){
|
||||||
|
// check config exist
|
||||||
|
if(!GameData.getCombineDataMap().containsKey(cid)){
|
||||||
|
player.getWorld().getHost().sendPacket(new PacketCombineRsp());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
CombineData combineData = GameData.getCombineDataMap().get(cid);
|
||||||
|
|
||||||
|
if(combineData.getPlayerLevel() > player.getLevel()){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// check enough
|
||||||
|
var enough = combineData.getMaterialItems().stream()
|
||||||
|
.filter(item -> player.getInventory()
|
||||||
|
.getInventoryTab(ItemType.ITEM_MATERIAL)
|
||||||
|
.getItemById(item.getId())
|
||||||
|
.getCount() < item.getCount() * count
|
||||||
|
)
|
||||||
|
.findAny()
|
||||||
|
.isEmpty();
|
||||||
|
|
||||||
|
// if not enough
|
||||||
|
if(!enough){
|
||||||
|
player.getWorld().getHost().sendPacket(
|
||||||
|
new PacketCombineRsp(RetcodeOuterClass.Retcode.RET_ITEM_COMBINE_COUNT_NOT_ENOUGH_VALUE)
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (player.getMora() >= combineData.getScoinCost()) {
|
||||||
|
player.setMora(player.getMora() - combineData.getScoinCost() * count);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// try to remove materials
|
||||||
|
combineData.getMaterialItems().stream()
|
||||||
|
.map(item -> Pair.of(player.getInventory()
|
||||||
|
.getInventoryTab(ItemType.ITEM_MATERIAL)
|
||||||
|
.getItemById(item.getId())
|
||||||
|
,item.getCount() * count)
|
||||||
|
)
|
||||||
|
.forEach(item -> player.getInventory().removeItem(item.first(), item.second()));
|
||||||
|
|
||||||
|
// make the result
|
||||||
|
player.getInventory().addItem(combineData.getResultItemId(),
|
||||||
|
combineData.getResultItemCount() * count);
|
||||||
|
|
||||||
|
CombineResult result = new CombineResult();
|
||||||
|
result.setMaterial(List.of());
|
||||||
|
result.setResult(List.of(new CombineData.CombineItemPair(combineData.getResultItemId(),
|
||||||
|
combineData.getResultItemCount() * count)));
|
||||||
|
// TODO lucky characters
|
||||||
|
result.setExtra(List.of());
|
||||||
|
result.setBack(List.of());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package emu.grasscutter.game.combine;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.def.CombineData;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CombineResult {
|
||||||
|
private List<CombineData.CombineItemPair> material;
|
||||||
|
private List<CombineData.CombineItemPair> result;
|
||||||
|
private List<CombineData.CombineItemPair> extra;
|
||||||
|
private List<CombineData.CombineItemPair> back;
|
||||||
|
|
||||||
|
public List<CombineData.CombineItemPair> getMaterial() {
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaterial(List<CombineData.CombineItemPair> material) {
|
||||||
|
this.material = material;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CombineData.CombineItemPair> getResult() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResult(List<CombineData.CombineItemPair> result) {
|
||||||
|
this.result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CombineData.CombineItemPair> getExtra() {
|
||||||
|
return extra;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExtra(List<CombineData.CombineItemPair> extra) {
|
||||||
|
this.extra = extra;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CombineData.CombineItemPair> getBack() {
|
||||||
|
return back;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBack(List<CombineData.CombineItemPair> back) {
|
||||||
|
this.back = back;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -5,6 +5,7 @@ import emu.grasscutter.Grasscutter;
|
|||||||
import emu.grasscutter.command.CommandMap;
|
import emu.grasscutter.command.CommandMap;
|
||||||
import emu.grasscutter.database.DatabaseHelper;
|
import emu.grasscutter.database.DatabaseHelper;
|
||||||
import emu.grasscutter.game.Account;
|
import emu.grasscutter.game.Account;
|
||||||
|
import emu.grasscutter.game.combine.CombineManger;
|
||||||
import emu.grasscutter.game.drop.DropManager;
|
import emu.grasscutter.game.drop.DropManager;
|
||||||
import emu.grasscutter.game.dungeons.DungeonManager;
|
import emu.grasscutter.game.dungeons.DungeonManager;
|
||||||
import emu.grasscutter.game.gacha.GachaManager;
|
import emu.grasscutter.game.gacha.GachaManager;
|
||||||
@ -44,7 +45,9 @@ public final class GameServer extends KcpServer {
|
|||||||
private final CommandMap commandMap;
|
private final CommandMap commandMap;
|
||||||
private final TaskMap taskMap;
|
private final TaskMap taskMap;
|
||||||
private final DropManager dropManager;
|
private final DropManager dropManager;
|
||||||
|
|
||||||
|
private final CombineManger combineManger;
|
||||||
|
|
||||||
public GameServer(InetSocketAddress address) {
|
public GameServer(InetSocketAddress address) {
|
||||||
super(address);
|
super(address);
|
||||||
|
|
||||||
@ -63,7 +66,8 @@ public final class GameServer extends KcpServer {
|
|||||||
this.commandMap = new CommandMap(true);
|
this.commandMap = new CommandMap(true);
|
||||||
this.taskMap = new TaskMap(true);
|
this.taskMap = new TaskMap(true);
|
||||||
this.dropManager = new DropManager(this);
|
this.dropManager = new DropManager(this);
|
||||||
|
this.combineManger = new CombineManger(this);
|
||||||
|
|
||||||
// Schedule game loop.
|
// Schedule game loop.
|
||||||
Timer gameLoop = new Timer();
|
Timer gameLoop = new Timer();
|
||||||
gameLoop.scheduleAtFixedRate(new TimerTask() {
|
gameLoop.scheduleAtFixedRate(new TimerTask() {
|
||||||
@ -125,6 +129,9 @@ public final class GameServer extends KcpServer {
|
|||||||
return this.commandMap;
|
return this.commandMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CombineManger getCombineManger(){
|
||||||
|
return this.combineManger;
|
||||||
|
}
|
||||||
public TaskMap getTaskMap() {
|
public TaskMap getTaskMap() {
|
||||||
return this.taskMap;
|
return this.taskMap;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,16 @@
|
|||||||
package emu.grasscutter.server.packet.recv;
|
package emu.grasscutter.server.packet.recv;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.def.CombineData;
|
||||||
import emu.grasscutter.net.packet.Opcodes;
|
import emu.grasscutter.net.packet.Opcodes;
|
||||||
import emu.grasscutter.net.packet.PacketHandler;
|
import emu.grasscutter.net.packet.PacketHandler;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.CombineReqOuterClass;
|
import emu.grasscutter.net.proto.CombineReqOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.ItemParamOuterClass;
|
||||||
import emu.grasscutter.server.game.GameSession;
|
import emu.grasscutter.server.game.GameSession;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketCombineRsp;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Opcodes(PacketOpcodes.CombineReq)
|
@Opcodes(PacketOpcodes.CombineReq)
|
||||||
public class HandlerCombineReq extends PacketHandler {
|
public class HandlerCombineReq extends PacketHandler {
|
||||||
@ -14,7 +20,28 @@ public class HandlerCombineReq extends PacketHandler {
|
|||||||
|
|
||||||
CombineReqOuterClass.CombineReq req = CombineReqOuterClass.CombineReq.parseFrom(payload);
|
CombineReqOuterClass.CombineReq req = CombineReqOuterClass.CombineReq.parseFrom(payload);
|
||||||
|
|
||||||
|
var result = session.getServer().getCombineManger()
|
||||||
|
.combineItem(session.getPlayer(), req.getCombineId(), req.getCombineCount());
|
||||||
|
|
||||||
|
if(result == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
session.send(new PacketCombineRsp(req,
|
||||||
|
toItemParamList(result.getMaterial()),
|
||||||
|
toItemParamList(result.getResult()),
|
||||||
|
toItemParamList(result.getExtra()),
|
||||||
|
toItemParamList(result.getBack()),
|
||||||
|
toItemParamList(result.getBack())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<ItemParamOuterClass.ItemParam> toItemParamList(List<CombineData.CombineItemPair> list){
|
||||||
|
return list.stream()
|
||||||
|
.map(item -> ItemParamOuterClass.ItemParam.newBuilder()
|
||||||
|
.setItemId(item.getId())
|
||||||
|
.setCount(item.getCount())
|
||||||
|
.build())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user