Implement buying from shops

This commit is contained in:
Melledy
2023-10-16 03:57:04 -07:00
parent 3306629d29
commit b016f358bc
12 changed files with 1333 additions and 17 deletions

View File

@@ -13,6 +13,7 @@ public class GameConstants {
public static final String DEFAULT_NAME = "Trailblazer";
public static final int TRAILBLAZER_AVATAR_ID = 8001;
public static final int MAX_TRAILBLAZER_LEVEL = 70;
public static final int MATERIAL_COIN_ID = 2; // Material id for credits. DO NOT CHANGE
public static final int MAX_STAMINA = 240;
public static final int MAX_AVATARS_IN_TEAM = 4;
public static final int DEFAULT_TEAMS = 6;

View File

@@ -18,6 +18,11 @@ public class ItemParam {
public ItemParam() {
// Gson
}
public ItemParam(int id, int count) {
this.id = id;
this.count = count;
}
public ItemParam(ItemParamType type, int id, int count) {
this.type = type;

View File

@@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import emu.lunarcore.GameConstants;
import emu.lunarcore.data.GameResource;
import emu.lunarcore.data.ResourceType;
import emu.lunarcore.data.ResourceType.LoadPriority;
@@ -46,7 +47,7 @@ public class AvatarPromotionExcel extends GameResource {
Iterator<ItemParam> it = this.PromotionCostList.iterator();
while (it.hasNext()) {
ItemParam param = it.next();
if (param.getId() == 2) {
if (param.getId() == GameConstants.MATERIAL_COIN_ID) {
this.PromotionCostCoin = param.getCount();
it.remove();
}

View File

@@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import emu.lunarcore.GameConstants;
import emu.lunarcore.data.GameData;
import emu.lunarcore.data.GameResource;
import emu.lunarcore.data.ResourceType;
@@ -44,7 +45,7 @@ public class AvatarSkillTreeExcel extends GameResource {
Iterator<ItemParam> it = this.MaterialList.iterator();
while (it.hasNext()) {
ItemParam param = it.next();
if (param.getId() == 2) {
if (param.getId() == GameConstants.MATERIAL_COIN_ID) {
this.MaterialCostCoin = param.getCount();
it.remove();
}

View File

@@ -1,10 +1,16 @@
package emu.lunarcore.data.excel;
import java.util.ArrayList;
import java.util.List;
import emu.lunarcore.GameConstants;
import emu.lunarcore.data.GameData;
import emu.lunarcore.data.GameResource;
import emu.lunarcore.data.ResourceType;
import emu.lunarcore.data.ResourceType.LoadPriority;
import emu.lunarcore.data.common.ItemParam;
import emu.lunarcore.proto.GoodsOuterClass.Goods;
import lombok.AccessLevel;
import lombok.Getter;
@Getter
@@ -14,9 +20,15 @@ public class ShopGoodsExcel extends GameResource {
private int ItemID;
private int ItemCount;
private int ShopID;
@Getter(AccessLevel.NONE)
private int[] CurrencyList;
@Getter(AccessLevel.NONE)
private int[] CurrencyCostList;
private transient List<ItemParam> costList;
private transient int coinCost;
@Override
public int getId() {
return GoodsID;
@@ -24,10 +36,28 @@ public class ShopGoodsExcel extends GameResource {
@Override
public void onLoad() {
// Add to shop excel
ShopExcel shop = GameData.getShopExcelMap().get(this.ShopID);
if (shop == null) return;
shop.getGoods().put(this.GoodsID, this);
// Cache currency cost
this.costList = new ArrayList<>(CurrencyList.length);
for (int i = 0; i < CurrencyList.length; i++) {
if (CurrencyList[i] == GameConstants.MATERIAL_COIN_ID) {
this.coinCost = CurrencyCostList[i];
continue;
}
ItemParam param = new ItemParam(CurrencyList[i], CurrencyCostList[i]);
this.costList.add(param);
}
// Done - Clear references to save memory
this.CurrencyList = null;
this.CurrencyCostList = null;
}
public Goods toProto() {

View File

@@ -261,6 +261,11 @@ public class GameItem {
public Item toProto() {
return Item.newInstance()
.setItemId(this.getItemId())
.setNum(this.getCount());
.setNum(this.getCount())
.setLevel(this.getLevel())
.setMainAffixId(this.getMainAffix())
.setRank(this.getRank())
.setPromotion(this.getPromotion())
.setUniqueId(this.getInternalUid());
}
}

View File

@@ -111,15 +111,16 @@ public class Inventory extends BasePlayerManager {
return false;
}
public void addItems(Collection<GameItem> items) {
// Sanity
if (items.size() == 0) {
return;
}
// Init results and add items to inventory
public List<GameItem> addItems(Collection<GameItem> items) {
// Init results
List<GameItem> results = new ArrayList<GameItem>(items.size());
// Sanity
if (items.size() == 0) {
return results;
}
// Add to inventory
for (GameItem item : items) {
GameItem result = putItem(item);
if (result != null) {
@@ -131,6 +132,8 @@ public class Inventory extends BasePlayerManager {
if (results.size() > 0) {
getPlayer().sendPacket(new PacketPlayerSyncScNotify(results));
}
return results;
}
private synchronized GameItem putItem(GameItem item) {
@@ -235,8 +238,12 @@ public class Inventory extends BasePlayerManager {
break;
}
}
public void removeItemsByParams(Collection<ItemParam> items) {
removeItemsByParams(items, 1);
}
public void removeItemsByParams(Collection<ItemParam> items, int multiplier) {
// Sanity
if (items.size() == 0) {
return;
@@ -249,7 +256,7 @@ public class Inventory extends BasePlayerManager {
GameItem item = this.getItemByParam(param);
if (item == null) continue;
GameItem result = this.deleteItem(item, param.getCount());
GameItem result = this.deleteItem(item, param.getCount() * multiplier);
if (result != null) {
results.add(result);
}

View File

@@ -6,10 +6,7 @@ import java.util.List;
import emu.lunarcore.data.GameData;
import emu.lunarcore.data.common.ItemParam;
import emu.lunarcore.data.excel.AvatarPromotionExcel;
import emu.lunarcore.data.excel.AvatarRankExcel;
import emu.lunarcore.data.excel.AvatarSkillTreeExcel;
import emu.lunarcore.data.excel.EquipmentPromotionExcel;
import emu.lunarcore.data.excel.*;
import emu.lunarcore.game.avatar.GameAvatar;
import emu.lunarcore.game.inventory.GameItem;
import emu.lunarcore.game.player.Player;
@@ -542,4 +539,50 @@ public class InventoryService extends BaseGameService {
// Send packet
player.sendPacket(new PacketSellItemScRsp(returnItems));
}
public List<GameItem> buyShopGoods(Player player, int shopId, int goodsId, int goodsNum) {
// Get shop and goods excels
ShopExcel shop = GameData.getShopExcelMap().get(shopId);
if (shop == null) return null;
ShopGoodsExcel goods = shop.getGoods().get(goodsId);
if (goods == null) return null;
// Verify items
for (ItemParam param : goods.getCostList()) {
GameItem item = player.getInventory().getItemByParam(param);
if (item == null || item.getCount() < param.getCount() * goodsNum) {
return null;
}
}
// Verify credits
if (player.getScoin() < goods.getCoinCost() * goodsNum) {
return null;
}
// Pay items
player.getInventory().removeItemsByParams(goods.getCostList(), goodsNum);
player.addSCoin(goods.getCoinCost() * goodsNum);
// Buy items
List<GameItem> items = new ArrayList<>();
ItemExcel itemExcel = GameData.getItemExcelMap().get(goods.getItemID());
if (!itemExcel.isEquippable()) {
GameItem item = new GameItem(itemExcel, goods.getItemCount());
items.add(item);
} else {
int num = goods.getItemCount() * goodsNum;
for (int i = 0; i < num; i++) {
GameItem item = new GameItem(itemExcel, 1);
items.add(item);
}
}
// Add to inventory
player.getInventory().addItems(items);
return items;
}
}

View File

@@ -1,16 +1,21 @@
package emu.lunarcore.server.packet.recv;
import emu.lunarcore.proto.BuyGoodsCsReqOuterClass.BuyGoodsCsReq;
import emu.lunarcore.server.game.GameSession;
import emu.lunarcore.server.packet.CmdId;
import emu.lunarcore.server.packet.Opcodes;
import emu.lunarcore.server.packet.PacketHandler;
import emu.lunarcore.server.packet.send.PacketBuyGoodsScRsp;
@Opcodes(CmdId.BuyGoodsCsReq)
public class HandlerBuyGoodsCsReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] data) throws Exception {
session.send(CmdId.BuyGoodsScRsp);
var req = BuyGoodsCsReq.parseFrom(data);
var items = session.getServer().getInventoryService().buyShopGoods(session.getPlayer(), req.getShopId(), req.getGoodsId(), req.getGoodsNum());
session.send(new PacketBuyGoodsScRsp(req, items));
}
}

View File

@@ -0,0 +1,33 @@
package emu.lunarcore.server.packet.send;
import java.util.List;
import emu.lunarcore.game.inventory.GameItem;
import emu.lunarcore.proto.BuyGoodsCsReqOuterClass.BuyGoodsCsReq;
import emu.lunarcore.proto.BuyGoodsScRspOuterClass.BuyGoodsScRsp;
import emu.lunarcore.proto.ItemListOuterClass.ItemList;
import emu.lunarcore.server.packet.BasePacket;
import emu.lunarcore.server.packet.CmdId;
public class PacketBuyGoodsScRsp extends BasePacket {
public PacketBuyGoodsScRsp(BuyGoodsCsReq req, List<GameItem> items) {
super(CmdId.BuyGoodsScRsp);
var data = BuyGoodsScRsp.newInstance();
if (items != null) {
ItemList returnItems = ItemList.newInstance();
items.stream().map(GameItem::toProto).forEach(returnItems::addItemList);
data.setShopId(req.getShopId());
data.setGoodsId(req.getGoodsId());
data.setGoodsBuyTimes(req.getGoodsNum());
data.setReturnItemList(returnItems);
} else {
data.setRetcode(1);
}
this.setData(data);
}
}