Basic Inventory Management, /give
Command, Gacha Cost (#29)
* Basic inventory management, materials. * Add await to player save. * Adding equipment and relics. * Added method for paying items, add payment to gacha. * Remove database log. * Simplyfy give command
This commit is contained in:
parent
e24ff7d25d
commit
719b3200be
104
src/commands/item.ts
Normal file
104
src/commands/item.ts
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import { Equipment } from "../data/proto/StarRail";
|
||||||
|
import Player from "../db/Player";
|
||||||
|
import ItemExcel from "../util/excel/ItemExcel";
|
||||||
|
import Logger from "../util/Logger";
|
||||||
|
import Interface, { Command } from "./Interface";
|
||||||
|
const c = new Logger("/item", "blue");
|
||||||
|
|
||||||
|
export default async function handle(command: Command) {
|
||||||
|
if (!Interface.target) {
|
||||||
|
c.log("No target specified");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const player = Interface.target.player;
|
||||||
|
const actionType = command.args[0];
|
||||||
|
const itemId = Number(command.args[1]);
|
||||||
|
|
||||||
|
let count: number = 1;
|
||||||
|
let level: number = 1;
|
||||||
|
let rank: number = 1;
|
||||||
|
let promotion: number = 1;
|
||||||
|
|
||||||
|
for (let i = 2; i < command.args.length; i++) {
|
||||||
|
const arg = command.args[i];
|
||||||
|
const number = Number(command.args[i].substring(1));
|
||||||
|
|
||||||
|
if (arg.startsWith("x")) {
|
||||||
|
count = number;
|
||||||
|
}
|
||||||
|
else if (arg.startsWith("l")) {
|
||||||
|
level = number;
|
||||||
|
}
|
||||||
|
else if (arg.startsWith("r")) {
|
||||||
|
rank = number;
|
||||||
|
}
|
||||||
|
else if (arg.startsWith("p")) {
|
||||||
|
promotion = number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (actionType) {
|
||||||
|
case "give": {
|
||||||
|
await handleGive(player, itemId, count, level, rank, promotion);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "giveall": {
|
||||||
|
await handleGiveAll(player);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
c.log(`Usage: /item <give|giveall> <itemId> [x<count>|l<level>|r<rank>|p<promotion>]*`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleGive(player: Player, itemId: number, count:number, level: number, rank: number, promotion: number) {
|
||||||
|
if (!itemId) {
|
||||||
|
return c.log("No avatarId specified");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this item exists.
|
||||||
|
const itemData = ItemExcel.fromId(itemId);
|
||||||
|
if (!itemData) {
|
||||||
|
return c.log(`Item ID ${itemId} does not exist.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const inventory = await player.getInventory();
|
||||||
|
switch (itemData.ItemType) {
|
||||||
|
case "Material":
|
||||||
|
await inventory.addMaterial(itemId, count);
|
||||||
|
break;
|
||||||
|
case "Equipment":
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
await inventory.addEquipment({
|
||||||
|
tid: itemId,
|
||||||
|
uniqueId: 0,
|
||||||
|
level: level,
|
||||||
|
rank: rank,
|
||||||
|
exp: 1,
|
||||||
|
isProtected: false,
|
||||||
|
promotion: promotion,
|
||||||
|
baseAvatarId: 0
|
||||||
|
} as Equipment);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return c.log(`Unsupported item type: ${itemData.ItemType}.`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
c.log(`Added ${count} of item ${itemId} to player ${player.uid}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleGiveAll(player: Player) {
|
||||||
|
const inventory = await player.getInventory();
|
||||||
|
|
||||||
|
for (const entry of ItemExcel.all()) {
|
||||||
|
const count = entry.ItemType == "Material" ? 100 : 1;
|
||||||
|
await inventory.addItem(entry.ID, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
c.log(`All materials added to ${player.uid}`);
|
||||||
|
}
|
369
src/db/Inventory.ts
Normal file
369
src/db/Inventory.ts
Normal file
@ -0,0 +1,369 @@
|
|||||||
|
import { Equipment, Item, Material, PlayerSyncScNotify, Relic } from "../data/proto/StarRail";
|
||||||
|
import Logger from "../util/Logger";
|
||||||
|
import Database from "./Database";
|
||||||
|
import Player from "./Player";
|
||||||
|
import ItemExcel from "../util/excel/ItemExcel";
|
||||||
|
import { Timestamp } from "mongodb";
|
||||||
|
|
||||||
|
const c = new Logger("Inventory");
|
||||||
|
|
||||||
|
export interface PayItemData {
|
||||||
|
id: number,
|
||||||
|
count: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface InventoryI {
|
||||||
|
_id: number,
|
||||||
|
nextItemUid: number,
|
||||||
|
materials: { [key: number]: number },
|
||||||
|
relics: Relic[],
|
||||||
|
equipments: Equipment[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class Inventory {
|
||||||
|
public readonly player : Player;
|
||||||
|
public readonly db: InventoryI;
|
||||||
|
|
||||||
|
private constructor(player: Player, db: InventoryI) {
|
||||||
|
this.player = player;
|
||||||
|
this.db = db;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async loadOrCreate(player: Player) : Promise<Inventory> {
|
||||||
|
// Try to load the player's inventory from the database.
|
||||||
|
const db = Database.getInstance();
|
||||||
|
const inventory = await db.get("inventory", { _id: player.uid }) as unknown as InventoryI; // How to get rid of this ugly fuck?!
|
||||||
|
|
||||||
|
// If successfull, we are done.
|
||||||
|
if (inventory) {
|
||||||
|
return new Inventory(player, inventory);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, we create a default inventory.
|
||||||
|
const data : InventoryI = {
|
||||||
|
_id: player.uid,
|
||||||
|
nextItemUid: 1,
|
||||||
|
materials: {},
|
||||||
|
relics: [],
|
||||||
|
equipments: []
|
||||||
|
};
|
||||||
|
await db.set("inventory", data);
|
||||||
|
return new Inventory(player, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async save() {
|
||||||
|
const db = Database.getInstance();
|
||||||
|
await db.update("inventory", { _id: this.db._id }, this.db);
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************************
|
||||||
|
Get inventory info.
|
||||||
|
********************************************************************************/
|
||||||
|
/**
|
||||||
|
* Get list of all `Material`s as proto.
|
||||||
|
* @returns List of materials.
|
||||||
|
*/
|
||||||
|
public getMaterialList() : Material[] {
|
||||||
|
const res: Material[] = [];
|
||||||
|
|
||||||
|
Object.keys(this.db.materials).forEach(key => {
|
||||||
|
res.push({ tid: Number(key), num: this.db.materials[Number(key)] } as Material);
|
||||||
|
});
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get list of all `Equipment`s as proto.
|
||||||
|
* @returns List of equipments.
|
||||||
|
*/
|
||||||
|
public getEquipmentList() : Equipment[] {
|
||||||
|
return this.db.equipments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get list of all `Relic`s as proto.
|
||||||
|
* @returns List of relics.
|
||||||
|
*/
|
||||||
|
public getRelicsList() : Relic[] {
|
||||||
|
return this.db.relics;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the count of the given item (material or virtual) in the player's inventory.
|
||||||
|
* @param id The item id.
|
||||||
|
* @returns The count in the player's inventory.
|
||||||
|
*/
|
||||||
|
public async getItemCount(id: number) : Promise<number> {
|
||||||
|
// Get item data.
|
||||||
|
const itemData = ItemExcel.fromId(id);
|
||||||
|
if (!itemData) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (itemData.ItemType) {
|
||||||
|
case "Virtual": return 0; // ToDo: Handle virtual items.
|
||||||
|
case "Material": return this.db.materials[id] ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************************
|
||||||
|
Add items to the inventory.
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the given amount of the given item to the player's inventory.
|
||||||
|
* @param id The item id. For equipment and relics, this is the base id.
|
||||||
|
* @param count The amount of items to add.
|
||||||
|
*/
|
||||||
|
public async addItem(id: number, count: number) {
|
||||||
|
// Get info for the particular item we are trying to add.
|
||||||
|
const itemData = ItemExcel.fromId(id);
|
||||||
|
if (!itemData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle adding depending on item type.
|
||||||
|
const t = itemData.ItemType;
|
||||||
|
if (t == "Virtual") {
|
||||||
|
await this.addVirtualItem(id, count);
|
||||||
|
}
|
||||||
|
else if (t == "Material") {
|
||||||
|
await this.addMaterial(id, count);
|
||||||
|
}
|
||||||
|
else if (t == "Equipment") {
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
await this.addEquipment(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (t == "Relic") {
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
await this.addRelic(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the given amount of the virtual item with the given id to the player's inventory.
|
||||||
|
* @param id The item id.
|
||||||
|
* @param count The amount.
|
||||||
|
*/
|
||||||
|
public async addVirtualItem(id: number, count: number) {
|
||||||
|
// ToDo: Figure out which virtual item ID is what.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the given amount of the material with the given id to the player's inventory.
|
||||||
|
* @param id The material id.
|
||||||
|
* @param count The amount.
|
||||||
|
*/
|
||||||
|
public async addMaterial(id: number, count: number) {
|
||||||
|
// Get info for the particular item we are trying to add.
|
||||||
|
const itemData = ItemExcel.fromId(id);
|
||||||
|
if (!itemData || itemData.ItemType != "Material") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const t = itemData.ItemType;
|
||||||
|
if (t != "Material") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current item count for this ID and calculate new count.
|
||||||
|
const currentCount = this.db.materials[id] ?? 0;
|
||||||
|
const newCount = Math.min(currentCount + count, itemData.PileLimit);
|
||||||
|
|
||||||
|
// Update.
|
||||||
|
this.db.materials[id] = newCount;
|
||||||
|
await this.save();
|
||||||
|
|
||||||
|
// Send update.
|
||||||
|
this.sendMaterialUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the given equipment to the player's inventory.
|
||||||
|
* @param equipment Either an `Equipment`, or the base id.
|
||||||
|
*/
|
||||||
|
public async addEquipment(equipment: number | Equipment) {
|
||||||
|
// If the parameter is a number, add a new equipment with this item ID as base.
|
||||||
|
if (typeof(equipment) == "number") {
|
||||||
|
const equip : Equipment = {
|
||||||
|
tid: equipment,
|
||||||
|
uniqueId: this.db.nextItemUid++,
|
||||||
|
level: 1,
|
||||||
|
rank: 1,
|
||||||
|
exp: 1,
|
||||||
|
isProtected: false,
|
||||||
|
promotion: 1,
|
||||||
|
baseAvatarId: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
this.db.equipments.push(equip);
|
||||||
|
await this.save();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, add the equipment object directly, but reset it's UID.
|
||||||
|
equipment.uniqueId = this.db.nextItemUid++;
|
||||||
|
this.db.equipments.push(equipment);
|
||||||
|
await this.save();
|
||||||
|
|
||||||
|
// Send update.
|
||||||
|
this.sendEquipmentUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the given relic to the player's inventory.
|
||||||
|
* @param relic Either a `Relic`, or the base id.
|
||||||
|
*/
|
||||||
|
public async addRelic(relic: number | Relic) {
|
||||||
|
// Don't add relics for now until we figure out affix IDs, since the game kinda breaks with
|
||||||
|
// incorrect ones.
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If the parameter is a number, add a new equipment with this item ID as base.
|
||||||
|
/*if (typeof(relic) == "number") {
|
||||||
|
const rel : Relic = {
|
||||||
|
tid: relic,
|
||||||
|
uniqueId: this.db.nextItemUid++,
|
||||||
|
level: 1,
|
||||||
|
exp: 1,
|
||||||
|
isProtected: false,
|
||||||
|
baseAvatarId: 0,
|
||||||
|
mainAffixId: 1,
|
||||||
|
subAffixList: []
|
||||||
|
};
|
||||||
|
|
||||||
|
this.db.relics.push(rel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, add the equipment object directly, but reset it's UID.
|
||||||
|
relic.uniqueId = this.db.nextItemUid++;
|
||||||
|
this.db.relics.push(relic);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************************
|
||||||
|
Remove items from the inventory directly.
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the the given number of the given item (virtual or material) with the given ID.
|
||||||
|
* @param id The item ID.
|
||||||
|
* @param count The number to remove.
|
||||||
|
*/
|
||||||
|
public async removeItem(id: number, count: number) {
|
||||||
|
const itemData = ItemExcel.fromId(id);
|
||||||
|
if (!itemData) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (itemData.ItemType) {
|
||||||
|
case "Virtual": await this.removeVirtualItem(id, count); break;
|
||||||
|
case "Material": await this.removeMaterial(id, count); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the given amount of the given virtual item from the player's inventory.
|
||||||
|
* @param id The item id.
|
||||||
|
* @param count The amount.
|
||||||
|
*/
|
||||||
|
public async removeVirtualItem(id: number, count: number) {
|
||||||
|
await this.addVirtualItem(id, -count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the given amount of the given material from the player's inventory.
|
||||||
|
* @param id The item id.
|
||||||
|
* @param count The amount.
|
||||||
|
*/
|
||||||
|
public async removeMaterial(id: number, count: number) {
|
||||||
|
await this.addMaterial(id, -count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the given equipment player's inventory.
|
||||||
|
* @param equipment Either an `Equipment`, or the equipment's unique id.
|
||||||
|
*/
|
||||||
|
public async removeEquipment(equipment: number | Equipment) {
|
||||||
|
// Find index to delete.
|
||||||
|
const toDelete: number = (typeof(equipment) == "number") ? equipment : equipment.uniqueId;
|
||||||
|
const index = this.db.equipments.findIndex(i => i.uniqueId == toDelete);
|
||||||
|
|
||||||
|
// Delete and save.
|
||||||
|
this.db.equipments.splice(index, 1);
|
||||||
|
this.save();
|
||||||
|
|
||||||
|
// Send update.
|
||||||
|
this.sendEquipmentUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the given relic player's inventory.
|
||||||
|
* @param relic Either a `Relic`, or the relic's unique id.
|
||||||
|
*/
|
||||||
|
public async removeRelic(relic: number | Relic) {
|
||||||
|
// Find index to delete.
|
||||||
|
const toDelete: number = (typeof(relic) == "number") ? relic : relic.uniqueId;
|
||||||
|
const index = this.db.relics.findIndex(i => i.uniqueId == toDelete);
|
||||||
|
|
||||||
|
// Delete and save.
|
||||||
|
this.db.relics.splice(index, 1);
|
||||||
|
this.save();
|
||||||
|
|
||||||
|
// Send update.
|
||||||
|
this.sendRelicUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************************
|
||||||
|
Pay items.
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pay items (virtual items and materials).
|
||||||
|
* @param items The items to be paid.
|
||||||
|
* @returns True if paying succeeded, false otherwise.
|
||||||
|
*/
|
||||||
|
public async payItems(items: PayItemData[]) : Promise<boolean> {
|
||||||
|
// Check if the player has a sufficient amount of all necessary items.
|
||||||
|
for (const item of items) {
|
||||||
|
const currentCount = await this.getItemCount(item.id);
|
||||||
|
if (currentCount < item.count) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have enough of everything - pay.
|
||||||
|
for (const item of items) {
|
||||||
|
await this.removeItem(item.id, item.count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send update.
|
||||||
|
this.sendMaterialUpdate();
|
||||||
|
|
||||||
|
// Done.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************************
|
||||||
|
Player updating.
|
||||||
|
********************************************************************************/
|
||||||
|
private sendMaterialUpdate() {
|
||||||
|
this.player.session.send(PlayerSyncScNotify, PlayerSyncScNotify.fromPartial({
|
||||||
|
materialList: this.getMaterialList()
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
private sendEquipmentUpdate() {
|
||||||
|
this.player.session.send(PlayerSyncScNotify, PlayerSyncScNotify.fromPartial({
|
||||||
|
equipmentList: this.getEquipmentList()
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
private sendRelicUpdate() {
|
||||||
|
this.player.session.send(PlayerSyncScNotify, PlayerSyncScNotify.fromPartial({
|
||||||
|
relicList: this.getRelicsList()
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ import Account from "./Account";
|
|||||||
import Avatar from "./Avatar";
|
import Avatar from "./Avatar";
|
||||||
import Database from "./Database";
|
import Database from "./Database";
|
||||||
import { Scene } from "../game/Scene";
|
import { Scene } from "../game/Scene";
|
||||||
|
import Inventory from "./Inventory";
|
||||||
const c = new Logger("Player");
|
const c = new Logger("Player");
|
||||||
|
|
||||||
export interface LineupI {
|
export interface LineupI {
|
||||||
@ -49,6 +50,7 @@ interface PlayerI {
|
|||||||
export default class Player {
|
export default class Player {
|
||||||
public readonly uid: number
|
public readonly uid: number
|
||||||
public readonly scene: Scene;
|
public readonly scene: Scene;
|
||||||
|
private inventory!: Inventory;
|
||||||
|
|
||||||
private constructor(readonly session: Session, public db: PlayerI) {
|
private constructor(readonly session: Session, public db: PlayerI) {
|
||||||
this.uid = db._id;
|
this.uid = db._id;
|
||||||
@ -105,6 +107,15 @@ export default class Player {
|
|||||||
this.db.lineup.curIndex = curIndex;
|
this.db.lineup.curIndex = curIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getInventory() : Promise<Inventory> {
|
||||||
|
// If this players inventory has not been loaded yet, do so now.
|
||||||
|
if (!this.inventory) {
|
||||||
|
this.inventory = await Inventory.loadOrCreate(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.inventory;
|
||||||
|
}
|
||||||
|
|
||||||
public static async create(session: Session, uid: number | string): Promise<Player | undefined> {
|
public static async create(session: Session, uid: number | string): Promise<Player | undefined> {
|
||||||
if (typeof uid == "string") uid = Number(uid);
|
if (typeof uid == "string") uid = Number(uid);
|
||||||
const acc = await Account.fromUID(uid);
|
const acc = await Account.fromUID(uid);
|
||||||
|
@ -80,10 +80,15 @@ export default class Session {
|
|||||||
|
|
||||||
public async sync() {
|
public async sync() {
|
||||||
const avatars = await Avatar.fromUID(this.player.db._id);
|
const avatars = await Avatar.fromUID(this.player.db._id);
|
||||||
|
const inventory = await this.player.getInventory();
|
||||||
|
|
||||||
this.send(PlayerSyncScNotify, PlayerSyncScNotify.fromPartial({
|
this.send(PlayerSyncScNotify, PlayerSyncScNotify.fromPartial({
|
||||||
avatarSync: {
|
avatarSync: {
|
||||||
avatarList: avatars.map(x => x.data),
|
avatarList: avatars.map(x => x.data)
|
||||||
},
|
},
|
||||||
|
materialList: inventory.getMaterialList(),
|
||||||
|
equipmentList: inventory.getEquipmentList(),
|
||||||
|
relicList: inventory.getRelicsList(),
|
||||||
basicInfo: this.player.db.basicInfo
|
basicInfo: this.player.db.basicInfo
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { DoGachaCsReq, DoGachaScRsp, GachaItem, Item, ItemList } from "../../data/proto/StarRail";
|
import { DoGachaCsReq, DoGachaScRsp, GachaItem, Item, ItemList } from "../../data/proto/StarRail";
|
||||||
|
import { PayItemData } from "../../db/Inventory";
|
||||||
import Banners from "../../util/Banner";
|
import Banners from "../../util/Banner";
|
||||||
import Packet from "../kcp/Packet";
|
import Packet from "../kcp/Packet";
|
||||||
import Session from "../kcp/Session";
|
import Session from "../kcp/Session";
|
||||||
@ -8,6 +9,17 @@ export default async function handle(session: Session, packet: Packet) {
|
|||||||
const body = packet.body as DoGachaCsReq;
|
const body = packet.body as DoGachaCsReq;
|
||||||
const banner = Banners.config.find(banner => banner.gachaId === body.gachaId)!;
|
const banner = Banners.config.find(banner => banner.gachaId === body.gachaId)!;
|
||||||
const combined = banner.rateUpItems4.concat(banner.rateUpItems5)
|
const combined = banner.rateUpItems4.concat(banner.rateUpItems5)
|
||||||
|
|
||||||
|
// Pay currency.
|
||||||
|
const inventory = await session.player.getInventory();
|
||||||
|
const success = await inventory.payItems([{ id: banner.costItemId, count: body.gachaNum } as PayItemData]);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
session.send(DoGachaScRsp, {
|
||||||
|
retcode: 1
|
||||||
|
} as DoGachaScRsp);
|
||||||
|
}
|
||||||
|
|
||||||
//bad gachaing but whatever....
|
//bad gachaing but whatever....
|
||||||
//TODO: pity system, proper logic
|
//TODO: pity system, proper logic
|
||||||
for(let i = 0; i < body.gachaNum; i++){
|
for(let i = 0; i < body.gachaNum; i++){
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
import { GetBagScRsp } from "../../data/proto/StarRail";
|
import { Equipment, GetBagScRsp, Material, Relic } from "../../data/proto/StarRail";
|
||||||
import Packet from "../kcp/Packet";
|
import Packet from "../kcp/Packet";
|
||||||
import Session from "../kcp/Session";
|
import Session from "../kcp/Session";
|
||||||
|
|
||||||
export default async function handle(session: Session, packet: Packet) {
|
export default async function handle(session: Session, packet: Packet) {
|
||||||
|
const inventory = await session.player.getInventory();
|
||||||
|
|
||||||
session.send(GetBagScRsp, {
|
session.send(GetBagScRsp, {
|
||||||
equipmentList: [],
|
equipmentList: inventory.getEquipmentList(),
|
||||||
materialList: [],
|
materialList: inventory.getMaterialList(),
|
||||||
relicList: [],
|
relicList: inventory.getRelicsList(),
|
||||||
retcode: 0,
|
retcode: 0,
|
||||||
rogueItemList: [],
|
rogueItemList: [],
|
||||||
waitDelResourceList: []
|
waitDelResourceList: []
|
||||||
|
@ -33,7 +33,7 @@ export default class Banners {
|
|||||||
rateUpItems5: [
|
rateUpItems5: [
|
||||||
1102
|
1102
|
||||||
],
|
],
|
||||||
costItemId: -1 //unused for now
|
costItemId: 101 // Star Rail Pass
|
||||||
} as Banner
|
} as Banner
|
||||||
];
|
];
|
||||||
|
|
||||||
|
20
src/util/excel/ItemExcel.ts
Normal file
20
src/util/excel/ItemExcel.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import _ItemExcelTable from "../../data/excel/ItemExcelTable.json";
|
||||||
|
type ItemExcelTableEntry = typeof _ItemExcelTable[keyof typeof _ItemExcelTable]
|
||||||
|
const ItemExcelTable = _ItemExcelTable as { [key: string]: ItemExcelTableEntry };
|
||||||
|
|
||||||
|
export default class ItemExcel {
|
||||||
|
private constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static all() : ItemExcelTableEntry[] {
|
||||||
|
return Object.values(ItemExcelTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static fromId(id: number) : ItemExcelTableEntry {
|
||||||
|
return ItemExcelTable[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static fromIds(ids: number[]): ItemExcelTableEntry[] {
|
||||||
|
return ids.map(id => ItemExcel.fromId(id));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user