Commit 3cd073dd authored by fallenstardust's avatar fallenstardust

注释部分函数

parent 7c60c104
......@@ -1231,39 +1231,86 @@ void DuelClient::HandleSTOCPacketLan(unsigned char* data, int len) {
}
}
// Analyze STOC_GAME_MSG packet
/**
* @brief 分析并处理来自服务器的游戏消息包
*
* 该函数负责解析从服务器接收到的STOC_GAME_MSG类型数据包,根据消息类型执行相应的游戏逻辑处理。
* 主要功能包括:
* 1. 读取消息类型并保存到游戏信息中
* 2. 保存最后一次成功处理的消息用于错误恢复
* 3. 隐藏当前显示的菜单界面
* 4. 处理非重播模式下的界面清理工作
* 5. 处理观战者视角切换
* 6. 根据不同的消息类型分发到对应的处理逻辑
*
* @param msg 指向消息数据包的指针
* @param len 消息数据包的长度
* @return bool 处理成功返回true,失败返回false
*
* @note 该函数是游戏核心逻辑处理函数,负责处理所有游戏过程中服务器发送的消息
* @note 对于MSG_RETRY消息会进行特殊处理,尝试恢复上一次成功的操作
* @note 在处理过程中会根据需要锁定和解锁图形界面互斥锁以保证线程安全
*/
bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
// 定义一个指针,用于遍历消息数据
unsigned char* pbuf = msg;
// 定义一个宽字符缓冲区,用于存储文本信息
wchar_t textBuffer[256];
// 从消息数据中读取当前消息类型,并存储到游戏信息结构中
mainGame->dInfo.curMsg = BufferIO::Read<uint8_t>(pbuf);
// 如果当前消息不是重试消息,则将当前消息保存为最后成功处理的消息
if(mainGame->dInfo.curMsg != MSG_RETRY) {
// 复制消息数据到last_successful_msg缓冲区
std::memcpy(last_successful_msg, msg, len);
// 记录消息长度
last_successful_msg_length = len;
}
// 隐藏当前显示的游戏菜单
mainGame->dField.HideMenu();
// 如果不是回放模式,且当前消息不是等待或卡片选择消息
if(!mainGame->dInfo.isReplay && mainGame->dInfo.curMsg != MSG_WAITING && mainGame->dInfo.curMsg != MSG_CARD_SELECTED) {
// 重置等待帧计数器
mainGame->waitFrame = -1;
// 隐藏提示信息显示
mainGame->stHintMsg->setVisible(false);
// 如果卡片选择窗口当前可见
if(mainGame->wCardSelect->isVisible()) {
// 锁定图形界面互斥锁
mainGame->gMutex.lock();
// 隐藏卡片选择窗口
mainGame->HideElement(mainGame->wCardSelect);
// 解锁图形界面互斥锁
mainGame->gMutex.unlock();
// 等待11帧确保界面操作完成
mainGame->WaitFrameSignal(11);
}
// 如果选项窗口当前可见
if(mainGame->wOptions->isVisible()) {
// 锁定图形界面互斥锁
mainGame->gMutex.lock();
// 隐藏选项窗口
mainGame->HideElement(mainGame->wOptions);
// 解锁图形界面互斥锁
mainGame->gMutex.unlock();
// 等待11帧确保界面操作完成
mainGame->WaitFrameSignal(11);
}
}
// 如果当前计时玩家是玩家1,则将计时玩家设置为2(无)
if(mainGame->dInfo.time_player == 1)
mainGame->dInfo.time_player = 2;
// 如果正在进行视角交换
if(is_swapping) {
// 锁定图形界面互斥锁
mainGame->gMutex.lock();
// 执行回放视角交换操作
mainGame->dField.ReplaySwap();
// 解锁图形界面互斥锁
mainGame->gMutex.unlock();
// 重置视角交换标志
is_swapping = false;
}
// 根据消息类型分发到相应的处理函数
switch(mainGame->dInfo.curMsg) {
case MSG_RETRY: {
if(last_successful_msg_length) {
......@@ -3168,23 +3215,39 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
return true;
}
case MSG_SUMMONING: {
// 从消息缓冲区读取召唤的卡片密码
unsigned int code = BufferIO::Read<int32_t>(pbuf);
// 读取控制者位置(被注释掉,未使用)
/*int cc = */mainGame->LocalPlayer(BufferIO::Read<uint8_t>(pbuf));
// 读取召唤位置(被注释掉,未使用)
/*int cl = */BufferIO::Read<uint8_t>(pbuf);
// 读取召唤区域序列(被注释掉,未使用)
/*int cs = */BufferIO::Read<uint8_t>(pbuf);
// 读取召唤位置(被注释掉,未使用)
/*int cp = */BufferIO::Read<uint8_t>(pbuf);
// 如果不是回放模式或者不是跳过回放,则执行以下操作
if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping) {
// 尝试播放在sound/chants/{code}.mp3 该卡片id相同文件名所在的音效,如果失败则播放普通召唤音效
if(!mainGame->soundManager->PlayChant(code))
mainGame->soundManager->PlaySoundEffect(SoundManager::SFX::SUMMON);
// 构造召唤事件字符串,显示"召唤了xxx",会打印在消息记录窗口中
myswprintf(event_string, dataManager.GetSysString(1603), dataManager.GetName(code));
// 设置要显示的卡片密码
mainGame->showcardcode = code;
// 设置卡片显示差异参数为0
mainGame->showcarddif = 0;
// 设置卡片显示位置参数为0
mainGame->showcardp = 0;
// 设置显示卡片类型为7(召唤动画)
mainGame->showcard = 7;
// 等待30帧显示召唤动画
mainGame->WaitFrameSignal(30);
// 重置显示卡片类型
mainGame->showcard = 0;
// 再等待11帧
mainGame->WaitFrameSignal(11);
}
// 返回true表示处理成功
return true;
}
case MSG_SUMMONED: {
......
This diff is collapsed.
......@@ -1903,16 +1903,30 @@ void Game::SaveConfig() {
// android::saveIntSetting(appMain, "control_mode", gameConf.control_mode);
}
/**
* @brief 显示指定卡牌的信息。
*
* 此函数用于在游戏界面中显示一张卡牌的详细信息,包括图像、名称、类型、种族、属性、攻击力/守备力等,
* 并根据卡牌是否有效(存在于数据表中)以及其具体类型(怪兽卡、魔法卡、陷阱卡等)进行不同的处理。
* 同时会设置文本区域以展示卡牌描述,并调整控件位置与缩放。
*
* @param code 卡牌编号,用作查找卡牌数据的关键字。
*/
void Game::ShowCardInfo(int code) {
// 定义格式化缓冲区和获取卡牌数据表引用
wchar_t formatBuffer[256];
auto& _datas = dataManager.GetDataTable();
auto cit = _datas.find(code);
bool is_valid = (cit != _datas.end());
// 设置卡片图片并启用自动缩放
imgCard->setImage(imageManager.GetTexture(code));
imgCard->setScaleImage(true);
// 根据卡牌是否存在决定如何显示名称:若存在且是替代卡则使用别名
if (is_valid) {
auto& cd = cit->second;
if (is_alternative(cd.code,cd.alias))
if (is_alternative(cd.code, cd.alias))
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(cd.alias), cd.alias);
else
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(code), code);
......@@ -1920,20 +1934,26 @@ void Game::ShowCardInfo(int code) {
else {
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(code), code);
}
// 设置名称标签文本及提示工具文本(当文字超出宽度时)
stName->setText(formatBuffer);
if((int)guiFont->getDimension(formatBuffer).Width > stName->getRelativePosition().getWidth() - gameConf.textfontsize)
if ((int)guiFont->getDimension(formatBuffer).Width > stName->getRelativePosition().getWidth() - gameConf.textfontsize)
stName->setToolTipText(formatBuffer);
else
stName->setToolTipText(nullptr);
// 字段名显示逻辑
int offset = 0;
if (is_valid && !gameConf.hide_setname) {
auto& cd = cit->second;
auto target = cit;
// 若当前卡有同名卡并且该同名卡存在于数据库中,则使用该同名卡对应的数据
if (cd.alias && _datas.find(cd.alias) != _datas.end()) {
target = _datas.find(cd.alias);
}
// 如果目标卡具有字段码,则构造并显示字段名
if (target->second.setcode[0]) {
offset = 23;// *yScale;
offset = 23; // 固定偏移量用于布局调整
const auto& setname = dataManager.FormatSetName(target->second.setcode);
myswprintf(formatBuffer, L"%ls%ls", dataManager.GetSysString(1329), setname.c_str());
stSetName->setText(formatBuffer);
......@@ -1944,61 +1964,85 @@ void Game::ShowCardInfo(int code) {
else {
stSetName->setText(L"");
}
if(is_valid && cit->second.type & TYPE_MONSTER) {
// 怪物卡信息处理分支
if (is_valid && cit->second.type & TYPE_MONSTER) {
auto& cd = cit->second;
// 构造并显示怪物卡的基本信息(类型、种族、属性)
const auto& type = dataManager.FormatType(cd.type);
const auto& race = dataManager.FormatRace(cd.race);
const auto& attribute = dataManager.FormatAttribute(cd.attribute);
myswprintf(formatBuffer, L"[%ls] %ls/%ls", type.c_str(), race.c_str(), attribute.c_str());
stInfo->setText(formatBuffer);
// 判断文本长度是否需要换行偏移
int offset_info = 0;
irr::core::dimension2d<unsigned int> dtxt = guiFont->getDimension(formatBuffer);
if(dtxt.Width > (300 * xScale - 13) - 15)
if (dtxt.Width > (300 * xScale - 13) - 15)
offset_info = 15;
const wchar_t* form = L"\u2605";
// 准备等级符号和攻防数值字符串
const wchar_t* form = L"\u2605"; // 默认星数标记
wchar_t adBuffer[64]{};
wchar_t scaleBuffer[16]{};
if(!(cd.type & TYPE_LINK)) {
if(cd.type & TYPE_XYZ)
form = L"\u2606";
if(cd.attack < 0 && cd.defense < 0)
// 非连接卡处理
if (!(cd.type & TYPE_LINK)) {
if (cd.type & TYPE_XYZ)
form = L"\u2606"; // XYZ卡使用不同标记
// 攻击力/防御力未知情况下的特殊处理
if (cd.attack < 0 && cd.defense < 0)
myswprintf(adBuffer, L"?/?");
else if(cd.attack < 0)
else if (cd.attack < 0)
myswprintf(adBuffer, L"?/%d", cd.defense);
else if(cd.defense < 0)
else if (cd.defense < 0)
myswprintf(adBuffer, L"%d/?", cd.attack);
else
myswprintf(adBuffer, L"%d/%d", cd.attack, cd.defense);
} else {
}
// 连接卡处理
else {
form = L"LINK-";
const auto& link_marker = dataManager.FormatLinkMarker(cd.link_marker);
if(cd.attack < 0)
if (cd.attack < 0)
myswprintf(adBuffer, L"?/- %ls", link_marker.c_str());
else
myswprintf(adBuffer, L"%d/- %ls", cd.attack, link_marker.c_str());
}
if(cd.type & TYPE_PENDULUM) {
// 摆钟卡额外显示左右刻度
if (cd.type & TYPE_PENDULUM) {
myswprintf(scaleBuffer, L" %d/%d", cd.lscale, cd.rscale);
}
// 组合最终数据信息并设置到界面上
myswprintf(formatBuffer, L"[%ls%d] %ls%ls", form, cd.level, adBuffer, scaleBuffer);
stDataInfo->setText(formatBuffer);
// 调整控件的位置
stSetName->setRelativePosition(Resize(10, 83, 250, 106));
stText->setRelativePosition(Resize(10, 83 + offset, 251, 340));
scrCardText->setRelativePosition(Resize(255, 83 + offset, 258, 340));
}
else {
}else {// 非怪物卡或无效卡处理
if (is_valid) {
const auto& type = dataManager.FormatType(cit->second.type);
myswprintf(formatBuffer, L"[%ls]", type.c_str());
}
else
myswprintf(formatBuffer, L"[%ls]", dataManager.unknown_string);
stInfo->setText(formatBuffer);
stDataInfo->setText(L"");
// 调整控件位置适应非怪物卡布局
stSetName->setRelativePosition(Resize(10, 60, 250, 106));
stText->setRelativePosition(Resize(10, 60 + offset, 251, 340));
scrCardText->setRelativePosition(Resize(255, 60 + offset, 258, 340));
}
// 获取并初始化卡牌描述文本
showingtext = dataManager.GetText(code);
const auto& tsize = stText->getRelativePosition();
InitStaticText(stText, tsize.getWidth(), tsize.getHeight(), textFont, showingtext);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment