金币经验掉落
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { oops } from "db://oops-framework/core/Oops";
|
||||
import { WxCloudApi ,UserGameData} from "../wx_clound_client_api/WxCloudApi";
|
||||
import { smc } from "./SingletonModuleComp";
|
||||
import { GameData } from "../wx_clound_client_api/WxCloudApi";
|
||||
|
||||
/**
|
||||
* 游戏数据同步管理器
|
||||
@@ -296,7 +297,7 @@ export class GameDataSyncManager {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 增加天赋点
|
||||
* @param talId 天赋ID
|
||||
@@ -351,33 +352,6 @@ export class GameDataSyncManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置天赋点数量
|
||||
* @param talId 天赋ID
|
||||
* @param count 数量
|
||||
* @returns 是否成功
|
||||
*/
|
||||
async setTalent(talId: number, count: number): Promise<boolean> {
|
||||
try {
|
||||
console.log(`[GameDataSyncManager]: 设置天赋点数量 ID:${talId}, 数量:${count}`);
|
||||
|
||||
const result = await WxCloudApi.setInventoryItem('tals', talId, count);
|
||||
|
||||
if (result.result.code === 200) {
|
||||
// 远程修改成功,同步本地数据
|
||||
smc.tals[talId] = count;
|
||||
console.log(`[GameDataSyncManager]: 天赋点数量设置成功,本地数据已同步`);
|
||||
return true;
|
||||
} else {
|
||||
console.warn(`[GameDataSyncManager]: 天赋点数量设置失败: ${result.result.msg}`);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`[GameDataSyncManager]: 设置天赋点数量异常:`, error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加装备
|
||||
* @param equipId 装备ID
|
||||
@@ -432,34 +406,37 @@ export class GameDataSyncManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置装备数量
|
||||
* @param equipId 装备ID
|
||||
* @param count 数量
|
||||
* @returns 是否成功
|
||||
*/
|
||||
async setEquipment(equipId: number, count: number): Promise<boolean> {
|
||||
|
||||
async addGameProperty(property: string, value: any): Promise<boolean> {
|
||||
try {
|
||||
console.log(`[GameDataSyncManager]: 设置装备数量 ID:${equipId}, 数量:${count}`);
|
||||
|
||||
const result = await WxCloudApi.setInventoryItem('equips', equipId, count);
|
||||
|
||||
console.log(`[GameDataSyncManager]: 增加游戏数据 ${property} = ${value}`);
|
||||
const result = await WxCloudApi.addGameDataField(property, value);
|
||||
if (result.result.code === 200) {
|
||||
// 远程修改成功,同步本地数据
|
||||
smc.equips[equipId] = count;
|
||||
console.log(`[GameDataSyncManager]: 装备数量设置成功,本地数据已同步`);
|
||||
console.log(`[GameDataSyncManager]: 游戏数据增加成功`);
|
||||
return true;
|
||||
} else {
|
||||
console.warn(`[GameDataSyncManager]: 装备数量设置失败: ${result.result.msg}`);
|
||||
console.warn(`[GameDataSyncManager]: 游戏数据增加失败: ${result.result.msg}`);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`[GameDataSyncManager]: 设置装备数量异常:`, error);
|
||||
console.error(`[GameDataSyncManager]: 增加游戏数据异常:`, error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async spendGameProperty(property: string, value: any): Promise<boolean> {
|
||||
try {
|
||||
console.log(`[GameDataSyncManager]: 消耗游戏数据 ${property} = ${value}`);
|
||||
const result = await WxCloudApi.spendGameDataField(property, value);
|
||||
if (result.result.code === 200) {
|
||||
console.log(`[GameDataSyncManager]: 游戏数据消耗成功`);
|
||||
return true;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`[GameDataSyncManager]: 消耗游戏数据异常:`, error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从云端加载所有游戏数据并同步到本地
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Initialize } from "../initialize/Initialize";
|
||||
import { GameMap } from "../map/GameMap";
|
||||
import { HeroUI, VmInfo } from "./config/Mission";
|
||||
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
||||
import { WxCloudApi } from "../wx_clound_client_api/WxCloudApi";
|
||||
import { GameData, WxCloudApi } from "../wx_clound_client_api/WxCloudApi";
|
||||
import { gameDataSyncManager } from "./GameDataSyncManager";
|
||||
import { GameSet } from "./config/BoxSet";
|
||||
import { Test } from "./Test";
|
||||
@@ -166,17 +166,63 @@ export class SingletonModuleComp extends ecs.Comp {
|
||||
* @param autoSave 是否自动保存 (默认true)
|
||||
* @returns 操作结果
|
||||
*/
|
||||
async addGameProperty(property: string, value: any, autoSave: boolean = true): Promise<any> {
|
||||
const currentValue = this.data[property] || 0;
|
||||
const newValue = currentValue + value;
|
||||
|
||||
this.data[property] = newValue;
|
||||
this.vmdata.data[property] = newValue;
|
||||
|
||||
console.log(`[SMC]: 增加游戏数据 ${property} = ${value}, 当前值: ${newValue}`);
|
||||
return newValue;
|
||||
addExp(exp:number,autoSave:boolean=true){
|
||||
this.data.exp+=exp
|
||||
this.vmdata.data.exp+=exp
|
||||
if(this.isWxClient()){
|
||||
this.gameDataSyncManager.addGameProperty("exp",exp)
|
||||
}
|
||||
}
|
||||
|
||||
addGold(gold:number,autoSave:boolean=true){
|
||||
this.data.gold+=gold
|
||||
this.vmdata.data.gold+=gold
|
||||
if(this.isWxClient()){
|
||||
this.gameDataSyncManager.addGameProperty("gold",gold)
|
||||
}
|
||||
}
|
||||
addDiamond(diamond:number,autoSave:boolean=true){
|
||||
this.data.diamond+=diamond
|
||||
this.vmdata.data.diamond+=diamond
|
||||
if(this.isWxClient()){
|
||||
this.gameDataSyncManager.addGameProperty("diamond",diamond)
|
||||
}
|
||||
}
|
||||
addMission(mission:number,autoSave:boolean=true){
|
||||
this.data.mission+=mission
|
||||
this.vmdata.data.mission+=mission
|
||||
if(this.isWxClient()){
|
||||
this.gameDataSyncManager.addGameProperty("mission",mission)
|
||||
}
|
||||
}
|
||||
spendMission(mission:number,autoSave:boolean=true){
|
||||
this.data.mission-=mission
|
||||
this.vmdata.data.mission-=mission
|
||||
if(this.isWxClient()){
|
||||
this.gameDataSyncManager.spendGameProperty("mission",mission)
|
||||
}
|
||||
}
|
||||
spendExp(exp:number,autoSave:boolean=true){
|
||||
this.data.exp-=exp
|
||||
this.vmdata.data.exp-=exp
|
||||
if(this.isWxClient()){
|
||||
this.gameDataSyncManager.spendGameProperty("exp",exp)
|
||||
}
|
||||
}
|
||||
spendGold(gold:number,autoSave:boolean=true){
|
||||
this.data.gold-=gold
|
||||
this.vmdata.data.gold-=gold
|
||||
if(this.isWxClient()){
|
||||
this.gameDataSyncManager.spendGameProperty("gold",gold)
|
||||
}
|
||||
}
|
||||
spendDiamond(diamond:number,autoSave:boolean=true){
|
||||
this.data.diamond-=diamond
|
||||
this.vmdata.data.diamond-=diamond
|
||||
if(this.isWxClient()){
|
||||
this.gameDataSyncManager.spendGameProperty("diamond",diamond)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 消耗游戏数据属性(统一接口)
|
||||
* - 支持单个字段:spendGameProperty('gold', 10)
|
||||
@@ -228,6 +274,7 @@ export class SingletonModuleComp extends ecs.Comp {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
addItem(item_uuid:number,count:number,autoSave:boolean=true){
|
||||
if(this.isWxClient()){
|
||||
this.gameDataSyncManager.addItem(item_uuid,count);
|
||||
|
||||
@@ -116,6 +116,93 @@ export const MonsterDropTable: { [monsterId: number]: [number, number, number, n
|
||||
]
|
||||
};
|
||||
|
||||
// 基础资源掉落配置表 - 以普通怪为基础值
|
||||
export const BaseResourceDropConfig = {
|
||||
// 经验值配置
|
||||
exp: {
|
||||
baseValue: 100, // 普通怪基础经验值
|
||||
stageMultiplier: 1.15, // 关卡倍数 (降低增长)
|
||||
randomRange: 0.2, // 随机范围 (±20%)
|
||||
baseProbability: 1.0 // 基础掉落概率 (100%)
|
||||
},
|
||||
// 金币配置
|
||||
gold: {
|
||||
baseValue: 50, // 普通怪基础金币值
|
||||
stageMultiplier: 1.12, // 关卡倍数 (降低增长)
|
||||
randomRange: 0.25, // 随机范围 (±25%)
|
||||
baseProbability: 0.7 // 基础掉落概率 (70%)
|
||||
},
|
||||
// 钻石配置
|
||||
diamond: {
|
||||
baseValue: 2, // 基础钻石值
|
||||
stageMultiplier: 1.05, // 关卡倍数 (大幅降低增长)
|
||||
randomRange: 0.2, // 随机范围 (±20%)
|
||||
baseProbability: 0.0 // 基础掉落概率 (0%,需要品质加成)
|
||||
}
|
||||
};
|
||||
|
||||
// 怪物品质加成配置表 - 使用加法权重
|
||||
export const QualityBonusConfig = {
|
||||
[QualitySet.GREEN]: {
|
||||
// 绿色品质:基础值 + 加成
|
||||
expBonus: 0, // 经验值加成
|
||||
goldBonus: 0, // 金币加成
|
||||
diamondBonus: 0, // 钻石加成
|
||||
expProbabilityBonus: 0, // 经验掉落概率加成
|
||||
goldProbabilityBonus: 0, // 金币掉落概率加成
|
||||
diamondProbabilityBonus: 0 // 钻石掉落概率加成
|
||||
},
|
||||
[QualitySet.BLUE]: {
|
||||
// 蓝色品质:基础值 + 加成
|
||||
expBonus: 50, // 经验值 +50
|
||||
goldBonus: 25, // 金币 +25
|
||||
diamondBonus: 0, // 钻石加成 0
|
||||
expProbabilityBonus: 0, // 经验掉落概率加成
|
||||
goldProbabilityBonus: 0.1, // 金币掉落概率 +10%
|
||||
diamondProbabilityBonus: 0.2 // 钻石掉落概率 +20%
|
||||
},
|
||||
[QualitySet.PURPLE]: {
|
||||
// 紫色品质:基础值 + 加成
|
||||
expBonus: 100, // 经验值 +100
|
||||
goldBonus: 50, // 金币 +50
|
||||
diamondBonus: 1, // 钻石 +1
|
||||
expProbabilityBonus: 0, // 经验掉落概率加成
|
||||
goldProbabilityBonus: 0.2, // 金币掉落概率 +20%
|
||||
diamondProbabilityBonus: 0.1 // 钻石掉落概率 +10%(精英10%)
|
||||
},
|
||||
[QualitySet.ORANGE]: {
|
||||
// 橙色品质:基础值 + 加成
|
||||
expBonus: 200, // 经验值 +200
|
||||
goldBonus: 100, // 金币 +100
|
||||
diamondBonus: 3, // 钻石 +3
|
||||
expProbabilityBonus: 0, // 经验掉落概率加成
|
||||
goldProbabilityBonus: 0.3, // 金币掉落概率 +30%
|
||||
diamondProbabilityBonus: 1.0 // 钻石掉落概率 +100%(BOSS必掉)
|
||||
}
|
||||
};
|
||||
|
||||
// 关卡和buff加成配置表 - 使用加法权重
|
||||
export const StageBuffBonusConfig = {
|
||||
// 关卡加成配置
|
||||
stage: {
|
||||
expBonusPerStage: 5, // 每关经验值加成
|
||||
goldBonusPerStage: 2, // 每关金币加成
|
||||
diamondBonusPerStage: 0.1, // 每关钻石加成
|
||||
expProbabilityBonusPerStage: 0, // 每关经验掉落概率加成
|
||||
goldProbabilityBonusPerStage: 0, // 每关金币掉落概率加成
|
||||
diamondProbabilityBonusPerStage: 0 // 每关钻石掉落概率加成
|
||||
},
|
||||
// buff数量加成配置
|
||||
buff: {
|
||||
expBonusPerBuff: 10, // 每个buff经验值加成
|
||||
goldBonusPerBuff: 5, // 每个buff金币加成
|
||||
diamondBonusPerBuff: 0.5, // 每个buff钻石加成
|
||||
expProbabilityBonusPerBuff: 0, // 每个buff经验掉落概率加成
|
||||
goldProbabilityBonusPerBuff: 0.01, // 每个buff金币掉落概率加成
|
||||
diamondProbabilityBonusPerBuff: 0.005 // 每个buff钻石掉落概率加成
|
||||
}
|
||||
};
|
||||
|
||||
// 怪物掉落管理器
|
||||
export class MonsterDropManager {
|
||||
|
||||
@@ -213,5 +300,68 @@ export class MonsterDropManager {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算怪物基础资源掉落(经验、金币、钻石)
|
||||
* @param monsterQuality 怪物品质
|
||||
* @param stageNumber 关卡数
|
||||
* @param buffCount buff数量
|
||||
* @returns 基础资源掉落结果
|
||||
*/
|
||||
static calculateBaseResourceDrops(monsterQuality: QualitySet, stageNumber: number, buffCount: number = 0): {exp: number, gold?: number, diamond?: number} {
|
||||
const result: {exp: number, gold?: number, diamond?: number} = {exp: 0};
|
||||
|
||||
// 获取品质加成
|
||||
const qualityBonus = QualityBonusConfig[monsterQuality];
|
||||
|
||||
// 计算经验值(必出)
|
||||
const expConfig = BaseResourceDropConfig.exp;
|
||||
const expValue = (expConfig.baseValue +
|
||||
qualityBonus.expBonus +
|
||||
StageBuffBonusConfig.stage.expBonusPerStage * stageNumber +
|
||||
StageBuffBonusConfig.buff.expBonusPerBuff * buffCount) *
|
||||
Math.pow(expConfig.stageMultiplier, stageNumber - 1);
|
||||
|
||||
// 添加随机范围
|
||||
const expRandomFactor = 1 + (Math.random() - 0.5) * 2 * expConfig.randomRange;
|
||||
result.exp = Math.floor(expValue * expRandomFactor);
|
||||
|
||||
// 金币与钻石独立判定,可同时掉落:
|
||||
// 使用加法权重系统:基础值 + 品质加成 + 关卡加成 + buff加成 + 关卡增长
|
||||
|
||||
// 金币判定
|
||||
const goldProbability = BaseResourceDropConfig.gold.baseProbability +
|
||||
qualityBonus.goldProbabilityBonus +
|
||||
StageBuffBonusConfig.stage.goldProbabilityBonusPerStage * stageNumber +
|
||||
StageBuffBonusConfig.buff.goldProbabilityBonusPerBuff * buffCount;
|
||||
if (Math.random() < goldProbability) {
|
||||
const goldConfig = BaseResourceDropConfig.gold;
|
||||
const goldValue = (goldConfig.baseValue +
|
||||
qualityBonus.goldBonus +
|
||||
StageBuffBonusConfig.stage.goldBonusPerStage * stageNumber +
|
||||
StageBuffBonusConfig.buff.goldBonusPerBuff * buffCount) *
|
||||
Math.pow(goldConfig.stageMultiplier, stageNumber - 1);
|
||||
const goldRandomFactor = 1 + (Math.random() - 0.5) * 2 * goldConfig.randomRange;
|
||||
result.gold = Math.floor(goldValue * goldRandomFactor);
|
||||
}
|
||||
|
||||
// 钻石判定
|
||||
const diamondProbability = BaseResourceDropConfig.diamond.baseProbability +
|
||||
qualityBonus.diamondProbabilityBonus +
|
||||
StageBuffBonusConfig.stage.diamondProbabilityBonusPerStage * stageNumber +
|
||||
StageBuffBonusConfig.buff.diamondProbabilityBonusPerBuff * buffCount;
|
||||
if (Math.random() < diamondProbability) {
|
||||
const diamondConfig = BaseResourceDropConfig.diamond;
|
||||
const diamondValue = (diamondConfig.baseValue +
|
||||
qualityBonus.diamondBonus +
|
||||
StageBuffBonusConfig.stage.diamondBonusPerStage * stageNumber +
|
||||
StageBuffBonusConfig.buff.diamondBonusPerBuff * buffCount) *
|
||||
Math.pow(diamondConfig.stageMultiplier, stageNumber - 1);
|
||||
const diamondRandomFactor = 1 + (Math.random() - 0.5) * 2 * diamondConfig.randomRange;
|
||||
result.diamond = Math.floor(diamondValue * diamondRandomFactor);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import { FightSet, getExpDrops, getStoneDrops, TooltipTypes } from "../common/co
|
||||
import { RandomManager } from "db://oops-framework/core/common/random/RandomManager";
|
||||
import { EnhancementType } from "../common/config/LevelUp";
|
||||
import { MonsterDropManager } from "../common/config/Items";
|
||||
import { HeroInfo } from "../common/config/heroSet";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
|
||||
@@ -255,10 +256,7 @@ export class HeroViewComp extends CCComp {
|
||||
this.is_count_dead=true
|
||||
if(this.fac==FacSet.MON){
|
||||
this.scheduleOnce(()=>{
|
||||
let drop_item=this.do_drop()
|
||||
if(drop_item.length>0){
|
||||
oops.message.dispatchEvent(GameEvent.MonDead,{mon_uuid:this.hero_uuid,drops:drop_item})
|
||||
}
|
||||
this.do_drop()
|
||||
},0.1)
|
||||
}
|
||||
if(this.fac==FacSet.HERO){
|
||||
@@ -276,8 +274,24 @@ export class HeroViewComp extends CCComp {
|
||||
}
|
||||
do_drop(){
|
||||
let drop_item=MonsterDropManager.calculateMonsterDrops(this.hero_uuid,smc.data.mission,1)
|
||||
console.log("[HeroViewComp]:do_drop",this.hero_uuid,drop_item)
|
||||
return drop_item
|
||||
let {exp,gold,diamond}=MonsterDropManager.calculateBaseResourceDrops(HeroInfo[this.hero_uuid].quality,smc.data.mission,this.BUFFS.length)
|
||||
oops.message.dispatchEvent(GameEvent.MonDead,{mon_uuid:this.hero_uuid,drops:drop_item,game_data:{exp:exp, gold:gold, diamond:diamond}})
|
||||
if(drop_item.length>0){
|
||||
for(let i=0;i<drop_item.length;i++){
|
||||
let d_item=drop_item[i]
|
||||
smc.addItem(d_item.item_uuid,d_item.count)
|
||||
}
|
||||
}
|
||||
if(exp>0){
|
||||
smc.addExp(exp)
|
||||
}
|
||||
if(gold>0){
|
||||
smc.addGold(gold)
|
||||
}
|
||||
if(diamond>0){
|
||||
smc.addDiamond(diamond)
|
||||
}
|
||||
console.log("[HeroViewComp]:do_drop",this.hero_uuid,drop_item,exp,gold,diamond)
|
||||
}
|
||||
add_debuff(type:number,deV:number,deC:number,deR:number){
|
||||
let n_deR=deR-this.Attrs[BuffAttr.DEBUFF_DOWN]
|
||||
|
||||
@@ -65,8 +65,8 @@ export class HInfoComp extends Component {
|
||||
smc.spendGameProperty({exp:experience,gold:gold},false)
|
||||
let result=smc.levelUpHero(this.h_uuid,experience,gold)
|
||||
if(!result){
|
||||
smc.addGameProperty("exp",experience,false)
|
||||
smc.addGameProperty("gold",gold,false)
|
||||
smc.addExp(experience,false)
|
||||
smc.addGold(gold,false)
|
||||
oops.gui.toast("网络出错了,升级失败,请重试")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -71,7 +71,6 @@ export class MissionComp extends CCComp {
|
||||
if(d_item.item_uuid==hitem.item_uuid){
|
||||
hitem.addItemCount(d_item.count)
|
||||
drop_item.splice(j,1)
|
||||
smc.addItem(d_item.item_uuid,d_item.count)
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -89,7 +88,6 @@ export class MissionComp extends CCComp {
|
||||
const node = instantiate(prefab) as unknown as Node;
|
||||
node.parent=parent
|
||||
node.getComponent(ItemComp)!.update_data(d_item.item_uuid,d_item.count)
|
||||
smc.addItem(d_item.item_uuid,d_item.count)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,7 +105,7 @@ export class MissionComp extends CCComp {
|
||||
oops.message.dispatchEvent(GameEvent.NewWave)
|
||||
return
|
||||
}
|
||||
smc.addGameProperty("mission",1)
|
||||
smc.addMission(1)
|
||||
oops.message.dispatchEvent(GameEvent.FightEnd,{victory:true})
|
||||
oops.gui.open(UIID.Victory,{victory:true,rewards:this.rewards})
|
||||
}
|
||||
|
||||
@@ -36,14 +36,6 @@ export type GameData = {
|
||||
diamond: number,
|
||||
meat: number,
|
||||
exp: number,
|
||||
ghstone: number, // 绿色英雄石
|
||||
bhstone: number, // 蓝色英雄石
|
||||
phlestone: number, // 紫色英雄石
|
||||
rhstone: number, // 红色英雄石
|
||||
herocard: number, // 英雄卡
|
||||
ckey: number, // 铜钥匙
|
||||
skey: number, // 银钥匙
|
||||
gkey: number // 金钥匙
|
||||
}
|
||||
|
||||
// 出战英雄类型
|
||||
@@ -209,7 +201,7 @@ export class WxCloudApi{
|
||||
* @param amount 增加的数量
|
||||
* @return Promise<CloudCallFunctionResult<CloudReturnType<{field: string, old_value: number, new_value: number, change: number}>>>
|
||||
*/
|
||||
public static async addGameDataField(field: keyof GameData, amount: number): Promise<CloudCallFunctionResult<CloudReturnType<{
|
||||
public static async addGameDataField(field:string, amount: number): Promise<CloudCallFunctionResult<CloudReturnType<{
|
||||
field: string,
|
||||
old_value: number,
|
||||
new_value: number,
|
||||
@@ -232,7 +224,7 @@ export class WxCloudApi{
|
||||
* @param amount 消耗的数量
|
||||
* @return Promise<CloudCallFunctionResult<CloudReturnType<{field: string, old_value: number, new_value: number, change: number}>>>
|
||||
*/
|
||||
public static async spendGameDataField(field: keyof GameData, amount: number): Promise<CloudCallFunctionResult<CloudReturnType<{
|
||||
public static async spendGameDataField(field:string, amount: number): Promise<CloudCallFunctionResult<CloudReturnType<{
|
||||
field: string,
|
||||
old_value: number,
|
||||
new_value: number,
|
||||
|
||||
Reference in New Issue
Block a user