mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-01-25 03:53:00 +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
06983e9e84
commit
48d1e026ef
@ -66,8 +66,9 @@ public class GameData {
|
||||
private static final Int2ObjectMap<DailyDungeonData> dailyDungeonDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<DungeonData> dungeonDataMap = 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<>();
|
||||
|
||||
|
||||
// Cache
|
||||
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
|
||||
private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
|
||||
@ -301,9 +302,6 @@ public class GameData {
|
||||
return shopGoods;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the rewardpreviewdatamap
|
||||
*/
|
||||
public static Int2ObjectMap<RewardPreviewData> getRewardPreviewDataMap() {
|
||||
return rewardPreviewDataMap;
|
||||
}
|
||||
@ -311,4 +309,8 @@ public class GameData {
|
||||
public static IntList getScenePointIdList() {
|
||||
return scenePointIdList;
|
||||
}
|
||||
|
||||
public static Int2ObjectMap<CombineData> getCombineDataMap() {
|
||||
return combineDataMap;
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,173 @@
|
||||
package emu.grasscutter.data.def;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@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.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.Account;
|
||||
import emu.grasscutter.game.combine.CombineManger;
|
||||
import emu.grasscutter.game.drop.DropManager;
|
||||
import emu.grasscutter.game.dungeons.DungeonManager;
|
||||
import emu.grasscutter.game.gacha.GachaManager;
|
||||
@ -44,7 +45,9 @@ public final class GameServer extends KcpServer {
|
||||
private final CommandMap commandMap;
|
||||
private final TaskMap taskMap;
|
||||
private final DropManager dropManager;
|
||||
|
||||
|
||||
private final CombineManger combineManger;
|
||||
|
||||
public GameServer(InetSocketAddress address) {
|
||||
super(address);
|
||||
|
||||
@ -63,7 +66,8 @@ public final class GameServer extends KcpServer {
|
||||
this.commandMap = new CommandMap(true);
|
||||
this.taskMap = new TaskMap(true);
|
||||
this.dropManager = new DropManager(this);
|
||||
|
||||
this.combineManger = new CombineManger(this);
|
||||
|
||||
// Schedule game loop.
|
||||
Timer gameLoop = new Timer();
|
||||
gameLoop.scheduleAtFixedRate(new TimerTask() {
|
||||
@ -125,6 +129,9 @@ public final class GameServer extends KcpServer {
|
||||
return this.commandMap;
|
||||
}
|
||||
|
||||
public CombineManger getCombineManger(){
|
||||
return this.combineManger;
|
||||
}
|
||||
public TaskMap getTaskMap() {
|
||||
return this.taskMap;
|
||||
}
|
||||
|
@ -1,10 +1,16 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.data.def.CombineData;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.CombineReqOuterClass;
|
||||
import emu.grasscutter.net.proto.ItemParamOuterClass;
|
||||
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)
|
||||
public class HandlerCombineReq extends PacketHandler {
|
||||
@ -14,7 +20,28 @@ public class HandlerCombineReq extends PacketHandler {
|
||||
|
||||
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