优化副本闯关模式系统
修改内容: * 使用unordered_map替代vector提升查询性能 * 修复SummonedCreatureDies中的逻辑错误 * 添加线程安全保护(mutex) * 修复关卡验证错误,调整逻辑顺序 * 完成所有关卡后改为离开副本选项 技术改进: - Stage类数据结构优化 - 完善错误处理和日志记录 - 修复状态管理bug 解决问题: - 修复完成所有关卡后的状态处理 - 提升系统稳定性和性能
This commit is contained in:
parent
d72e531f5b
commit
74774554f7
@ -1,5 +1,4 @@
|
||||
#include "Player.h"
|
||||
#include "stage.h"
|
||||
#include <ScriptedGossip.h>
|
||||
#include "CreatureScript.h"
|
||||
#include "PlayerScript.h"
|
||||
@ -7,217 +6,365 @@
|
||||
#include "ScriptedCreature.h"
|
||||
#include "Chat.h"
|
||||
|
||||
#include "stage.h"
|
||||
#include "../mod_Switch/Switch.h"
|
||||
#include <mod_CustomCreature.h>
|
||||
std::vector<StageTemplate> StageVec;
|
||||
|
||||
// 使用unordered_map替代vector提升查询性能
|
||||
std::unordered_map<uint32, StageTemplate> StageMap;
|
||||
std::mutex StageMutex; // 添加线程安全保护
|
||||
|
||||
void Stage::Load()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
StageVec.clear();
|
||||
QueryResult result = WorldDatabase.Query(
|
||||
// 0 1 2 3
|
||||
"SELECT 关卡ID,召唤生物组ID,通关召唤物体ID,菜单文本 FROM acore_custom._副本_闯关模式");
|
||||
|
||||
std::lock_guard<std::mutex> lock(StageMutex);
|
||||
StageMap.clear();
|
||||
|
||||
QueryResult result = WorldDatabase.Query("SELECT 关卡ID,召唤生物组ID,通关召唤物体ID,菜单文本 FROM acore_custom._副本_闯关模式");
|
||||
|
||||
if (result)
|
||||
{
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
StageTemplate Temp;
|
||||
Temp.stageRank = fields[0].Get<uint32>();
|
||||
Temp.summonsGroupId = fields[1].Get<uint32>();
|
||||
Temp.rewardGameobjectId = fields[2].Get<uint32>();
|
||||
Temp.description = fields[3].Get<std::string>();
|
||||
StageVec.push_back(Temp);
|
||||
StageTemplate temp;
|
||||
temp.stageRank = fields[0].Get<uint32>();
|
||||
temp.summonsGroupId = fields[1].Get<uint32>();
|
||||
temp.rewardGameobjectId = fields[2].Get<uint32>();
|
||||
temp.description = fields[3].Get<std::string>();
|
||||
|
||||
// 验证召唤组ID和GameObject模板是否存在
|
||||
if (!ValidateSummonGroup(temp.summonsGroupId))
|
||||
{
|
||||
LOG_ERROR("module", "关卡 {} 有无效的召唤组ID: {}", temp.stageRank, temp.summonsGroupId);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (temp.rewardGameobjectId != 0 && !sObjectMgr->GetGameObjectTemplate(temp.rewardGameobjectId))
|
||||
{
|
||||
LOG_ERROR("module", "关卡 {} 有无效的游戏物体ID: {}", temp.stageRank, temp.rewardGameobjectId);
|
||||
continue;
|
||||
}
|
||||
|
||||
StageMap[temp.stageRank] = temp;
|
||||
} while (result->NextRow());
|
||||
sLog->outMessage("server", LogLevel::LOG_LEVEL_INFO, ">> 读取自定义功能数据表【_副本_闯关模式-----------】,共{}条数据读取加载,用时{}毫秒", StageVec.size(), GetMSTimeDiffToNow(oldMSTime));
|
||||
|
||||
sLog->outMessage("server", LogLevel::LOG_LEVEL_INFO,
|
||||
">> 读取自定义功能数据表【_副本_闯关模式-----------】,共{}条数据读取加载,用时{}毫秒",
|
||||
StageMap.size(), GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
}
|
||||
|
||||
std::string Stage::GetDescription(uint32 stage)
|
||||
{
|
||||
uint32 len = StageVec.size();
|
||||
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
if (stage == StageVec[i].stageRank)
|
||||
return StageVec[i].description;
|
||||
}
|
||||
|
||||
return "";
|
||||
std::lock_guard<std::mutex> lock(StageMutex);
|
||||
auto it = StageMap.find(stage);
|
||||
return (it != StageMap.end()) ? it->second.description : "";
|
||||
}
|
||||
|
||||
uint32 Stage::GetSumId(uint32 stage)
|
||||
{
|
||||
uint32 len = StageVec.size();
|
||||
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
if (stage == StageVec[i].stageRank)
|
||||
return StageVec[i].summonsGroupId;
|
||||
}
|
||||
|
||||
return 1;
|
||||
std::lock_guard<std::mutex> lock(StageMutex);
|
||||
auto it = StageMap.find(stage);
|
||||
return (it != StageMap.end()) ? it->second.summonsGroupId : 0; // 改为返回0表示无效
|
||||
}
|
||||
|
||||
uint32 Stage::GetGobId(uint32 stage)
|
||||
{
|
||||
uint32 len = StageVec.size();
|
||||
std::lock_guard<std::mutex> lock(StageMutex);
|
||||
auto it = StageMap.find(stage);
|
||||
return (it != StageMap.end()) ? it->second.rewardGameobjectId : 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
if (stage == StageVec[i].stageRank)
|
||||
return StageVec[i].rewardGameobjectId;
|
||||
}
|
||||
bool Stage::IsValidStage(uint32 stage)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(StageMutex);
|
||||
return StageMap.find(stage) != StageMap.end();
|
||||
}
|
||||
|
||||
return 0;
|
||||
uint32 Stage::GetMaxStage()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(StageMutex);
|
||||
return StageMap.size();
|
||||
}
|
||||
|
||||
// 验证召唤组是否存在的辅助函数
|
||||
bool Stage::ValidateSummonGroup(uint32 groupId)
|
||||
{
|
||||
// 这里需要检查creature_summon_groups表中是否存在该组ID
|
||||
QueryResult result = WorldDatabase.Query("SELECT COUNT(*) FROM creature_summon_groups WHERE groupId = {}", groupId);
|
||||
if (result)
|
||||
{
|
||||
Field* field = result->Fetch();
|
||||
return field[0].Get<uint32>() > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class StageNPC : public CreatureScript
|
||||
{
|
||||
public:
|
||||
StageNPC() : CreatureScript("StageNPC") { }
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature) override
|
||||
{
|
||||
// 获取该creature的mod_CustomCreature实例
|
||||
StageNPC() : CreatureScript("StageNPC") {}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature) override
|
||||
{
|
||||
mod_CustomCreature* customCreature = mod_CustomCreature::GetForCreature(creature);
|
||||
if (!customCreature)
|
||||
{
|
||||
LOG_ERROR("module", "闯关NPC: 未能获取生物 {} 的自定义生物数据", creature->GetGUID().ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
|
||||
uint32 eventid = atoi(sSwitch->GetFlagByIndex(ST_STAGE, 1).c_str());
|
||||
// 检查时间限制
|
||||
uint32 eventid = atoi(sSwitch->GetFlagByIndex(ST_STAGE, 1).c_str());
|
||||
if (eventid != 0 && !sGameEventMgr->IsActiveEvent(eventid))
|
||||
{
|
||||
ChatHandler(player->GetSession()).PSendSysMessage("当前时间不允许挑战!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (eventid != 0 && !sGameEventMgr->IsActiveEvent(eventid))
|
||||
{
|
||||
ChatHandler(player->GetSession()).PSendSysMessage("当前时间不允许挑战!");
|
||||
return false;
|
||||
}
|
||||
// 先检查是否完成所有关卡,再进行有效性验证
|
||||
if (customCreature->stage > sStage->GetMaxStage())
|
||||
{
|
||||
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "你已经完成了所有挑战!", 0, GOSSIP_ACTION_INFO_DEF + 3);
|
||||
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "离开副本", 0, GOSSIP_ACTION_INFO_DEF + 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 只有在正常关卡范围内才进行有效性验证
|
||||
if (!sStage->IsValidStage(customCreature->stage))
|
||||
{
|
||||
LOG_ERROR("module", "生物 {} 的关卡 {} 无效", customCreature->stage, creature->GetGUID().ToString());
|
||||
ChatHandler(player->GetSession()).PSendSysMessage("关卡配置错误,请联系管理员!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (customCreature->summonsClear && customCreature->stage <= StageVec.size())
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "挑战等级:" << customCreature->stage;
|
||||
if (customCreature->summonsClear)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "挑战等级:" << customCreature->stage;
|
||||
|
||||
AddGossipItemFor(player, GOSSIP_ICON_CHAT, oss.str(), customCreature->stage, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
AddGossipItemFor(player, GOSSIP_ICON_CHAT, sStage->GetDescription(customCreature->stage), customCreature->stage, GOSSIP_ACTION_INFO_DEF);
|
||||
}
|
||||
AddGossipItemFor(player, GOSSIP_ICON_CHAT, oss.str(), customCreature->stage, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
|
||||
std::string description = sStage->GetDescription(customCreature->stage);
|
||||
if (!description.empty())
|
||||
{
|
||||
AddGossipItemFor(player, GOSSIP_ICON_CHAT, description, customCreature->stage, GOSSIP_ACTION_INFO_DEF);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "当前关卡进行中...", 0, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
}
|
||||
}
|
||||
|
||||
SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action) override
|
||||
{
|
||||
// 获取该creature的mod_CustomCreature实例
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action) override
|
||||
{
|
||||
mod_CustomCreature* customCreature = mod_CustomCreature::GetForCreature(creature);
|
||||
if (!customCreature)
|
||||
{
|
||||
LOG_ERROR("module", "关卡NPC错误:无法获取生物GUID[{}]的自定义生物数据", creature->GetGUID().ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (action == GOSSIP_ACTION_INFO_DEF + 1)
|
||||
{
|
||||
OnGossipHello(player, creature);
|
||||
return true;
|
||||
}
|
||||
creature->SummonCreatureGroup(sStage->GetSumId(customCreature->stage));
|
||||
if (action == GOSSIP_ACTION_INFO_DEF + 1)
|
||||
{
|
||||
OnGossipHello(player, creature);
|
||||
return true;
|
||||
}
|
||||
else if (action == GOSSIP_ACTION_INFO_DEF + 2)
|
||||
{
|
||||
CloseGossipMenuFor(player);
|
||||
return true;
|
||||
}
|
||||
else if (action == GOSSIP_ACTION_INFO_DEF + 4) // 离开副本
|
||||
{
|
||||
CloseGossipMenuFor(player);
|
||||
// 传送玩家离开副本
|
||||
player->TeleportToEntryPoint();
|
||||
return true;
|
||||
}
|
||||
|
||||
// 开始挑战
|
||||
uint32 summonGroupId = sStage->GetSumId(customCreature->stage);
|
||||
LOG_INFO("module", "正在尝试为生物Entry[{}]召唤生物组[{}]", summonGroupId, creature->GetEntry());
|
||||
if (summonGroupId == 0) // 0表示无效
|
||||
{
|
||||
ChatHandler(player->GetSession()).PSendSysMessage("关卡召唤配置错误!");
|
||||
CloseGossipMenuFor(player);
|
||||
return false;
|
||||
}
|
||||
|
||||
creature->SummonCreatureGroup(summonGroupId);
|
||||
customCreature->summonsClear = false;
|
||||
CloseGossipMenuFor(player);
|
||||
return true;
|
||||
}
|
||||
CloseGossipMenuFor(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
struct StageNPCAI : public ScriptedAI
|
||||
{
|
||||
StageNPCAI(Creature* creature) : ScriptedAI(creature), Summons(me){}
|
||||
struct StageNPCAI : public ScriptedAI
|
||||
{
|
||||
StageNPCAI(Creature* creature) : ScriptedAI(creature), Summons(me) {}
|
||||
|
||||
SummonList Summons;
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summon->GetMotionMaster()->MoveRandom(5.0f);
|
||||
Summons.Summon(summon);
|
||||
}
|
||||
SummonList Summons;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
// 获取该creature的mod_CustomCreature实例
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summon->GetMotionMaster()->MoveRandom(5.0f);
|
||||
Summons.Summon(summon);
|
||||
LOG_INFO("module", "已召唤生物Entry[{}] 位置(X:{}, Y:{}, Z:{}) 当前总召唤数:{}",
|
||||
summon->GetEntry(), summon->GetPositionX(), summon->GetPositionY(),
|
||||
summon->GetPositionZ(), Summons.size());
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
mod_CustomCreature* customCreature = mod_CustomCreature::GetForCreature(me);
|
||||
if (!customCreature)
|
||||
{
|
||||
LOG_ERROR("module", "关卡NPC AI重置错误:无法获取生物GUID[{}]的自定义生物数据", me->GetGUID().ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
customCreature->summonsClear = true;
|
||||
customCreature->stage = 1;
|
||||
Summons.DespawnAll();
|
||||
}
|
||||
Summons.DespawnAll();
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
}
|
||||
LOG_INFO("module", "重置完成,已清除召唤生物:{},当前关卡:{}", customCreature->summonsClear, customCreature->stage);
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* summon, Unit* killer) override
|
||||
{
|
||||
// 获取该creature的mod_CustomCreature实例
|
||||
mod_CustomCreature* customCreature = mod_CustomCreature::GetForCreature(summon);
|
||||
void MoveInLineOfSight(Unit* /*who*/) override
|
||||
{
|
||||
// 空实现,避免不必要的处理
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* summon, Unit* killer) override
|
||||
{
|
||||
// 修复:应该从me获取customCreature,而不是从summon
|
||||
mod_CustomCreature* customCreature = mod_CustomCreature::GetForCreature(me);
|
||||
if (!customCreature)
|
||||
{
|
||||
LOG_ERROR("module", "召唤生物死亡错误:无法获取生物GUID[{}]的自定义生物数据", me->GetGUID().ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "挑战等级:" << customCreature->stage;
|
||||
me->Say(oss.str().c_str(), LANG_UNIVERSAL, 0);
|
||||
LOG_INFO("module", "生物死亡,当前关卡:{},之前召唤数量:{}", customCreature->stage, Summons.size());
|
||||
|
||||
Summons.Despawn(summon);
|
||||
std::ostringstream oss;
|
||||
oss << "挑战等级:" << customCreature->stage;
|
||||
me->Say(oss.str().c_str(), LANG_UNIVERSAL, 0);
|
||||
|
||||
if (Summons.empty())
|
||||
{
|
||||
uint32 gobEntry = sStage->GetGobId(customCreature->stage);
|
||||
Summons.Despawn(summon);
|
||||
|
||||
if (sObjectMgr->GetGameObjectTemplate(gobEntry))
|
||||
me->SummonGameObject(gobEntry, killer->GetPositionX(), killer->GetPositionY(), killer->GetPositionZ(), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0);
|
||||
LOG_INFO("module", "消失后召唤数量:{},是否为空:{}", Summons.size(), Summons.empty());
|
||||
|
||||
customCreature->stage++;
|
||||
customCreature->summonsClear = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
if (Summons.empty())
|
||||
{
|
||||
uint32 gobEntry = sStage->GetGobId(customCreature->stage);
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new StageNPCAI(creature);
|
||||
}
|
||||
// 验证GameObject模板存在性
|
||||
if (gobEntry != 0 && sObjectMgr->GetGameObjectTemplate(gobEntry))
|
||||
{
|
||||
me->SummonGameObject(gobEntry, killer->GetPositionX(), killer->GetPositionY(),
|
||||
killer->GetPositionZ(), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 300); // 5分钟后消失
|
||||
}
|
||||
|
||||
// 检查是否超出最大关卡
|
||||
if (customCreature->stage < sStage->GetMaxStage())
|
||||
{
|
||||
customCreature->stage++;
|
||||
customCreature->summonsClear = true;
|
||||
|
||||
LOG_INFO("module", "已进阶到关卡:{},召唤清除标记设为:{}", customCreature->stage, customCreature->summonsClear);
|
||||
|
||||
// 通知玩家进入下一关
|
||||
std::ostringstream nextStageMsg;
|
||||
nextStageMsg << "恭喜通过第" << (customCreature->stage - 1) << "关!准备挑战第" << customCreature->stage << "关!";
|
||||
me->Say(nextStageMsg.str().c_str(), LANG_UNIVERSAL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 所有关卡完成
|
||||
me->Say("恭喜完成所有关卡挑战!", LANG_UNIVERSAL, 0);
|
||||
customCreature->summonsClear = true;
|
||||
customCreature->stage = sStage->GetMaxStage() + 1; // 设置为超出最大关卡
|
||||
// 可以在这里添加特殊奖励逻辑
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_INFO("module", "仍有{}个召唤生物存在", Summons.size());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new StageNPCAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class StagePlayerScript : public PlayerScript
|
||||
{
|
||||
public:
|
||||
StagePlayerScript() : PlayerScript("StagePlayerScript") {}
|
||||
StagePlayerScript() : PlayerScript("StagePlayerScript") {}
|
||||
|
||||
void OnPlayerMapChanged(Player* player) override
|
||||
{
|
||||
uint32 mapId = atoi(sSwitch->GetFlagByIndex(ST_STAGE, 2).c_str());
|
||||
void OnPlayerMapChanged(Player* player) override
|
||||
{
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
if (player->GetMapId() != mapId)
|
||||
return;
|
||||
uint32 mapId = atoi(sSwitch->GetFlagByIndex(ST_STAGE, 2).c_str());
|
||||
if (mapId == 0 || player->GetMapId() != mapId)
|
||||
return;
|
||||
|
||||
uint32 size = atoi(sSwitch->GetFlagByIndex(ST_STAGE, 4).c_str());
|
||||
uint32 maxPlayers = atoi(sSwitch->GetFlagByIndex(ST_STAGE, 4).c_str());
|
||||
if (maxPlayers == 0)
|
||||
{
|
||||
LOG_ERROR("module", "关卡系统玩家最大数量配置无效");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Map* map = player->GetMap())
|
||||
{
|
||||
uint32 count = map->GetPlayersCountExceptGMs();
|
||||
Map* map = player->GetMap();
|
||||
if (!map)
|
||||
return;
|
||||
|
||||
if (count > size)
|
||||
{
|
||||
player->RepopAtGraveyard();
|
||||
return;
|
||||
}
|
||||
uint32 currentPlayers = map->GetPlayersCountExceptGMs();
|
||||
|
||||
if (count == 1)
|
||||
{
|
||||
uint32 npcId = atoi(sSwitch->GetFlagByIndex(ST_STAGE, 3).c_str());
|
||||
// 人数超限处理
|
||||
if (currentPlayers > maxPlayers)
|
||||
{
|
||||
ChatHandler(player->GetSession()).PSendSysMessage("当前地图人数已满,正在传送您离开...");
|
||||
player->RepopAtGraveyard();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Creature* creature = player->FindNearestCreature(npcId, 150))
|
||||
creature->AI()->Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
// 单人重置逻辑
|
||||
if (currentPlayers == 1)
|
||||
{
|
||||
uint32 npcId = atoi(sSwitch->GetFlagByIndex(ST_STAGE, 3).c_str());
|
||||
if (npcId == 0)
|
||||
{
|
||||
LOG_ERROR("module", "关卡系统NPC ID配置无效");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Creature* creature = player->FindNearestCreature(npcId, 150.0f))
|
||||
{
|
||||
if (creature->AI())
|
||||
{
|
||||
creature->AI()->Reset();
|
||||
ChatHandler(player->GetSession()).PSendSysMessage("关卡已重置,可以开始新的挑战!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_Stage()
|
||||
|
||||
@ -1,27 +1,45 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#ifndef STAGE_H
|
||||
#define STAGE_H
|
||||
|
||||
#include "Define.h"
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <mutex>
|
||||
|
||||
struct StageTemplate
|
||||
{
|
||||
uint32 stageRank;
|
||||
uint32 summonsGroupId;
|
||||
uint32 rewardGameobjectId;
|
||||
std::string description;
|
||||
uint32 stageRank;
|
||||
uint32 summonsGroupId;
|
||||
uint32 rewardGameobjectId;
|
||||
std::string description;
|
||||
};
|
||||
extern std::vector<StageTemplate> StageVec;
|
||||
|
||||
class Stage
|
||||
{
|
||||
public:
|
||||
static Stage* instance()
|
||||
{
|
||||
static Stage instance;
|
||||
return &instance;
|
||||
}
|
||||
static Stage* instance()
|
||||
{
|
||||
static Stage instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
void Load();
|
||||
void Load();
|
||||
std::string GetDescription(uint32 stage);
|
||||
uint32 GetSumId(uint32 stage);
|
||||
uint32 GetGobId(uint32 stage);
|
||||
bool IsValidStage(uint32 stage);
|
||||
uint32 GetMaxStage();
|
||||
|
||||
uint32 GetSumId(uint32 stage);
|
||||
uint32 GetGobId(uint32 stage);
|
||||
std::string GetDescription(uint32 stage);
|
||||
private:
|
||||
bool ValidateSummonGroup(uint32 groupId);
|
||||
Stage() = default;
|
||||
~Stage() = default;
|
||||
Stage(const Stage&) = delete;
|
||||
Stage& operator=(const Stage&) = delete;
|
||||
};
|
||||
|
||||
#define sStage Stage::instance()
|
||||
#define sStage Stage::instance()
|
||||
|
||||
#endif // STAGE_H
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user