Commit 48d1e026 authored by Akka's avatar Akka Committed by GitHub
Browse files

Add Support of Item Combine (#513)



* Add Support of Item Combine

* Add Support of Item Combine
Co-authored-by: default avatarMelledy <52122272+Melledy@users.noreply.github.com>
parent 06983e9e
...@@ -66,8 +66,9 @@ public class GameData { ...@@ -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 { ...@@ -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 { ...@@ -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;
}
} }
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;
}
} }
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;
}
}
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; ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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;
} }
......
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 { ...@@ -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());
}
} }
Markdown is supported
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