Commit f49949d1 authored by mercury233's avatar mercury233

Merge branch 'master' of https://github.com/Fluorohydride/ygopro into server

parents 6000028b 741c229c
Pipeline #36437 passed with stages
in 5 minutes and 37 seconds
...@@ -369,34 +369,21 @@ bool DeckManager::DeleteCategory(const wchar_t* name) { ...@@ -369,34 +369,21 @@ bool DeckManager::DeleteCategory(const wchar_t* name) {
return false; return false;
return FileSystem::DeleteDir(localname); return FileSystem::DeleteDir(localname);
} }
bool DeckManager::SaveDeckBuffer(const int deckbuf[], const wchar_t* name) { bool DeckManager::SaveDeckArray(const DeckArray& deck, const wchar_t* name) {
if (!FileSystem::IsDirExists(L"./deck") && !FileSystem::MakeDir(L"./deck")) if (!FileSystem::IsDirExists(L"./deck") && !FileSystem::MakeDir(L"./deck"))
return false; return false;
FILE* fp = OpenDeckFile(name, "w"); FILE* fp = OpenDeckFile(name, "w");
if (!fp) if (!fp)
return false; return false;
int it = 0;
const int mainc = deckbuf[it];
++it;
std::fprintf(fp, "#created by ...\n#main\n"); std::fprintf(fp, "#created by ...\n#main\n");
for (int i = 0; i < mainc; ++i) { for (const auto& code : deck.main)
std::fprintf(fp, "%d\n", deckbuf[it]); std::fprintf(fp, "%u\n", code);
++it;
}
const int extrac = deckbuf[it];
++it;
std::fprintf(fp, "#extra\n"); std::fprintf(fp, "#extra\n");
for (int i = 0; i < extrac; ++i) { for (const auto& code : deck.extra)
std::fprintf(fp, "%d\n", deckbuf[it]); std::fprintf(fp, "%u\n", code);
++it;
}
const int sidec = deckbuf[it];
++it;
std::fprintf(fp, "!side\n"); std::fprintf(fp, "!side\n");
for (int i = 0; i < sidec; ++i) { for (const auto& code : deck.side)
std::fprintf(fp, "%d\n", deckbuf[it]); std::fprintf(fp, "%u\n", code);
++it;
}
std::fclose(fp); std::fclose(fp);
return true; return true;
} }
......
...@@ -51,6 +51,12 @@ struct Deck { ...@@ -51,6 +51,12 @@ struct Deck {
} }
}; };
struct DeckArray {
std::vector<uint32_t> main;
std::vector<uint32_t> extra;
std::vector<uint32_t> side;
};
class DeckManager { class DeckManager {
public: public:
Deck current_deck; Deck current_deck;
...@@ -68,7 +74,6 @@ public: ...@@ -68,7 +74,6 @@ public:
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
bool LoadCurrentDeck(const wchar_t* file, bool is_packlist = false); bool LoadCurrentDeck(const wchar_t* file, bool is_packlist = false);
bool LoadCurrentDeck(int category_index, const wchar_t* category_name, const wchar_t* deckname); bool LoadCurrentDeck(int category_index, const wchar_t* category_name, const wchar_t* deckname);
bool SaveDeckBuffer(const int deckbuf[], const wchar_t* name);
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
static uint32_t LoadDeck(Deck& deck, uint32_t dbuf[], int mainc, int sidec, bool is_packlist = false); static uint32_t LoadDeck(Deck& deck, uint32_t dbuf[], int mainc, int sidec, bool is_packlist = false);
...@@ -84,6 +89,7 @@ public: ...@@ -84,6 +89,7 @@ public:
static bool CreateCategory(const wchar_t* name); static bool CreateCategory(const wchar_t* name);
static bool RenameCategory(const wchar_t* oldname, const wchar_t* newname); static bool RenameCategory(const wchar_t* oldname, const wchar_t* newname);
static bool DeleteCategory(const wchar_t* name); static bool DeleteCategory(const wchar_t* name);
static bool SaveDeckArray(const DeckArray& deck, const wchar_t* name);
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
}; };
......
...@@ -1621,6 +1621,10 @@ void Game::ShowCardInfo(int code, bool resize) { ...@@ -1621,6 +1621,10 @@ void Game::ShowCardInfo(int code, bool resize) {
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(code), code); myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(code), code);
} }
stName->setText(formatBuffer); stName->setText(formatBuffer);
if(guiFont->getDimension(formatBuffer).Width > stName->getRelativePosition().getWidth() - gameConf.textfontsize)
stName->setToolTipText(formatBuffer);
else
stName->setToolTipText(nullptr);
int offset = 0; int offset = 0;
if (is_valid && !gameConf.hide_setname) { if (is_valid && !gameConf.hide_setname) {
auto& cd = cit->second; auto& cd = cit->second;
...@@ -2103,6 +2107,9 @@ void Game::OnResize() { ...@@ -2103,6 +2107,9 @@ void Game::OnResize() {
btnBigCardZoomIn->setRelativePosition(Resize(205, 140, 295, 175)); btnBigCardZoomIn->setRelativePosition(Resize(205, 140, 295, 175));
btnBigCardZoomOut->setRelativePosition(Resize(205, 180, 295, 215)); btnBigCardZoomOut->setRelativePosition(Resize(205, 180, 295, 215));
btnBigCardClose->setRelativePosition(Resize(205, 230, 295, 265)); btnBigCardClose->setRelativePosition(Resize(205, 230, 295, 265));
irr::s32 barWidth = (xScale > 1) ? gameConf.textfontsize * xScale : gameConf.textfontsize;
env->getSkin()->setSize(irr::gui::EGDS_SCROLLBAR_SIZE, barWidth);
} }
void Game::ResizeChatInputWindow() { void Game::ResizeChatInputWindow() {
irr::s32 x = wInfos->getRelativePosition().LowerRightCorner.X + 6; irr::s32 x = wInfos->getRelativePosition().LowerRightCorner.X + 6;
......
...@@ -300,42 +300,23 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -300,42 +300,23 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
if(selected == -1) if(selected == -1)
break; break;
Replay replay; Replay replay;
wchar_t ex_filename[256]{}; wchar_t replay_filename[256]{};
wchar_t namebuf[4][20]{}; wchar_t namebuf[4][20]{};
wchar_t filename[256]{}; wchar_t filename[256]{};
wchar_t replay_path[256]{}; wchar_t replay_path[256]{};
BufferIO::CopyWideString(mainGame->lstReplayList->getListItem(selected), ex_filename); BufferIO::CopyWideString(mainGame->lstReplayList->getListItem(selected), replay_filename);
myswprintf(replay_path, L"./replay/%ls", ex_filename); myswprintf(replay_path, L"./replay/%ls", replay_filename);
if (!replay.OpenReplay(replay_path)) if (!replay.OpenReplay(replay_path))
break; break;
const ReplayHeader& rh = replay.pheader; if (replay.pheader.flag & REPLAY_SINGLE_MODE)
if(rh.flag & REPLAY_SINGLE_MODE) break;
break; for (size_t i = 0; i < replay.decks.size(); ++i) {
int player_count = (rh.flag & REPLAY_TAG) ? 4 : 2; BufferIO::CopyWideString(replay.players[Replay::GetDeckPlayer(i)].c_str(), namebuf[i]);
//player name
for(int i = 0; i < player_count; ++i)
replay.ReadName(namebuf[i]);
//skip pre infos
for(int i = 0; i < 4; ++i)
replay.ReadInt32();
//deck
std::vector<int> deckbuf;
for(int i = 0; i < player_count; ++i) {
deckbuf.clear();
int main = replay.ReadInt32();
deckbuf.push_back(main);
for (int j = 0; j < main; ++j) {
deckbuf.push_back(replay.ReadInt32());
}
int extra = replay.ReadInt32();
deckbuf.push_back(extra);
for (int j = 0; j < extra; ++j) {
deckbuf.push_back(replay.ReadInt32());
}
deckbuf.push_back(0);
FileSystem::SafeFileName(namebuf[i]); FileSystem::SafeFileName(namebuf[i]);
myswprintf(filename, L"deck/%ls-%d %ls.ydk", ex_filename, i + 1, namebuf[i]); }
deckManager.SaveDeckBuffer(deckbuf.data(), filename); for (size_t i = 0; i < replay.decks.size(); ++i) {
myswprintf(filename, L"./deck/%ls-%d %ls.ydk", replay_filename, i + 1, namebuf[i]);
DeckManager::SaveDeckArray(replay.decks[i], filename);
} }
mainGame->stACMessage->setText(dataManager.GetSysString(1335)); mainGame->stACMessage->setText(dataManager.GetSysString(1335));
mainGame->PopupElement(mainGame->wACMessage, 20); mainGame->PopupElement(mainGame->wACMessage, 20);
...@@ -546,7 +527,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -546,7 +527,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
wchar_t replay_path[256]{}; wchar_t replay_path[256]{};
myswprintf(replay_path, L"./replay/%ls", mainGame->lstReplayList->getListItem(sel)); myswprintf(replay_path, L"./replay/%ls", mainGame->lstReplayList->getListItem(sel));
if (!ReplayMode::cur_replay.OpenReplay(replay_path)) { if (!ReplayMode::cur_replay.OpenReplay(replay_path)) {
mainGame->stReplayInfo->setText(L""); mainGame->stReplayInfo->setText(L"Error");
break; break;
} }
wchar_t infobuf[256]{}; wchar_t infobuf[256]{};
...@@ -558,17 +539,17 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -558,17 +539,17 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
curtime = ReplayMode::cur_replay.pheader.seed; curtime = ReplayMode::cur_replay.pheader.seed;
std::wcsftime(infobuf, sizeof infobuf / sizeof infobuf[0], L"%Y/%m/%d %H:%M:%S\n", std::localtime(&curtime)); std::wcsftime(infobuf, sizeof infobuf / sizeof infobuf[0], L"%Y/%m/%d %H:%M:%S\n", std::localtime(&curtime));
repinfo.append(infobuf); repinfo.append(infobuf);
wchar_t namebuf[4][20]{}; if (ReplayMode::cur_replay.pheader.flag & REPLAY_SINGLE_MODE) {
ReplayMode::cur_replay.ReadName(namebuf[0]); wchar_t path[256]{};
ReplayMode::cur_replay.ReadName(namebuf[1]); BufferIO::DecodeUTF8(ReplayMode::cur_replay.script_name.c_str(), path);
if(ReplayMode::cur_replay.pheader.flag & REPLAY_TAG) { repinfo.append(path);
ReplayMode::cur_replay.ReadName(namebuf[2]); repinfo.append(L"\n");
ReplayMode::cur_replay.ReadName(namebuf[3]);
} }
const auto& player_names = ReplayMode::cur_replay.players;
if(ReplayMode::cur_replay.pheader.flag & REPLAY_TAG) if(ReplayMode::cur_replay.pheader.flag & REPLAY_TAG)
myswprintf(infobuf, L"%ls\n%ls\n===VS===\n%ls\n%ls\n", namebuf[0], namebuf[1], namebuf[2], namebuf[3]); myswprintf(infobuf, L"%ls\n%ls\n===VS===\n%ls\n%ls\n", player_names[0].c_str(), player_names[1].c_str(), player_names[2].c_str(), player_names[3].c_str());
else else
myswprintf(infobuf, L"%ls\n===VS===\n%ls\n", namebuf[0], namebuf[1]); myswprintf(infobuf, L"%ls\n===VS===\n%ls\n", player_names[0].c_str(), player_names[1].c_str());
repinfo.append(infobuf); repinfo.append(infobuf);
mainGame->ebRepStartTurn->setText(L"1"); mainGame->ebRepStartTurn->setText(L"1");
mainGame->SetStaticText(mainGame->stReplayInfo, 180, mainGame->guiFont, repinfo.c_str()); mainGame->SetStaticText(mainGame->stReplayInfo, 180, mainGame->guiFont, repinfo.c_str());
......
#include "replay.h" #include "replay.h"
#include "myfilesystem.h" #include "myfilesystem.h"
#include "network.h"
#include "lzma/LzmaLib.h" #include "lzma/LzmaLib.h"
namespace ygo { namespace ygo {
...@@ -58,9 +59,7 @@ void Replay::BeginRecord() { ...@@ -58,9 +59,7 @@ void Replay::BeginRecord() {
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
} }
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
replay_size = 0; Reset();
comp_size = 0;
is_replaying = false;
is_recording = true; is_recording = true;
} }
void Replay::WriteHeader(ReplayHeader& header) { void Replay::WriteHeader(ReplayHeader& header) {
...@@ -156,11 +155,7 @@ bool Replay::OpenReplay(const wchar_t* name) { ...@@ -156,11 +155,7 @@ bool Replay::OpenReplay(const wchar_t* name) {
if(!rfp) if(!rfp)
return false; return false;
data_position = 0; Reset();
is_recording = false;
is_replaying = false;
replay_size = 0;
comp_size = 0;
if(std::fread(&pheader, sizeof pheader, 1, rfp) < 1) { if(std::fread(&pheader, sizeof pheader, 1, rfp) < 1) {
std::fclose(rfp); std::fclose(rfp);
return false; return false;
...@@ -183,6 +178,13 @@ bool Replay::OpenReplay(const wchar_t* name) { ...@@ -183,6 +178,13 @@ bool Replay::OpenReplay(const wchar_t* name) {
comp_size = 0; comp_size = 0;
} }
is_replaying = true; is_replaying = true;
can_read = true;
if (!ReadInfo()) {
Reset();
return false;
}
info_offset = data_position;
data_position = 0;
return true; return true;
} }
bool Replay::CheckReplay(const wchar_t* name) { bool Replay::CheckReplay(const wchar_t* name) {
...@@ -222,10 +224,6 @@ bool Replay::ReadNextResponse(unsigned char resp[]) { ...@@ -222,10 +224,6 @@ bool Replay::ReadNextResponse(unsigned char resp[]) {
unsigned char len{}; unsigned char len{};
if (!ReadData(&len, sizeof len)) if (!ReadData(&len, sizeof len))
return false; return false;
if (len > SIZE_RETURN_VALUE) {
is_replaying = false;
return false;
}
if (!ReadData(resp, len)) if (!ReadData(resp, len))
return false; return false;
return true; return true;
...@@ -242,10 +240,10 @@ void Replay::ReadHeader(ReplayHeader& header) { ...@@ -242,10 +240,10 @@ void Replay::ReadHeader(ReplayHeader& header) {
header = pheader; header = pheader;
} }
bool Replay::ReadData(void* data, size_t length) { bool Replay::ReadData(void* data, size_t length) {
if(!is_replaying) if (!is_replaying || !can_read)
return false; return false;
if (data_position + length > replay_size) { if (data_position + length > replay_size) {
is_replaying = false; can_read = false;
return false; return false;
} }
if (length) if (length)
...@@ -258,6 +256,73 @@ int32_t Replay::ReadInt32() { ...@@ -258,6 +256,73 @@ int32_t Replay::ReadInt32() {
} }
void Replay::Rewind() { void Replay::Rewind() {
data_position = 0; data_position = 0;
can_read = true;
}
void Replay::Reset() {
is_recording = false;
is_replaying = false;
can_read = false;
replay_size = 0;
comp_size = 0;
data_position = 0;
info_offset = 0;
players.clear();
params = { 0 };
decks.clear();
script_name.clear();
}
void Replay::SkipInfo(){
data_position += info_offset;
}
bool Replay::ReadInfo() {
int player_count = (pheader.flag & REPLAY_TAG) ? 4 : 2;
for (int i = 0; i < player_count; ++i) {
wchar_t name[20]{};
if (!ReadName(name))
return false;
players.push_back(name);
}
if (!ReadData(&params, sizeof params))
return false;
bool is_tag1 = pheader.flag & REPLAY_TAG;
bool is_tag2 = params.duel_flag & DUEL_TAG_MODE;
if (is_tag1 != is_tag2)
return false;
if (pheader.flag & REPLAY_SINGLE_MODE) {
uint16_t slen = Read<uint16_t>();
char filename[256]{};
if (slen == 0 || slen > sizeof(filename) - 1)
return false;
if (!ReadData(filename, slen))
return false;
filename[slen] = 0;
if (std::strncmp(filename, "./single/", 9))
return false;
script_name = filename + 9;
if (script_name.find_first_of(R"(/\)") != std::string::npos)
return false;
}
else {
for (int p = 0; p < player_count; ++p) {
DeckArray deck;
uint32_t main = Read<uint32_t>();
if (main > MAINC_MAX)
return false;
if (main)
deck.main.resize(main);
if (!ReadData(deck.main.data(), main * sizeof(uint32_t)))
return false;
uint32_t extra = Read<uint32_t>();
if (extra > MAINC_MAX)
return false;
if (extra)
deck.extra.resize(extra);
if (!ReadData(deck.extra.data(), extra * sizeof(uint32_t)))
return false;
decks.push_back(deck);
}
}
return true;
} }
} }
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define REPLAY_H #define REPLAY_H
#include "config.h" #include "config.h"
#include "deck_manager.h"
namespace ygo { namespace ygo {
...@@ -13,7 +14,7 @@ namespace ygo { ...@@ -13,7 +14,7 @@ namespace ygo {
#define REPLAY_UNIFORM 0x10 #define REPLAY_UNIFORM 0x10
// max size // max size
constexpr int MAX_REPLAY_SIZE = 0x20000; constexpr int MAX_REPLAY_SIZE = 0x80000;
constexpr int MAX_COMP_SIZE = UINT16_MAX + 1; constexpr int MAX_COMP_SIZE = UINT16_MAX + 1;
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
...@@ -32,6 +33,13 @@ struct ReplayHeader { ...@@ -32,6 +33,13 @@ struct ReplayHeader {
uint8_t props[8]{}; uint8_t props[8]{};
}; };
struct DuelParameters {
int32_t start_lp{};
int32_t start_hand{};
int32_t draw_count{};
uint32_t duel_flag{};
};
class Replay { class Replay {
public: public:
Replay(); Replay();
...@@ -51,10 +59,20 @@ public: ...@@ -51,10 +59,20 @@ public:
void SaveReplay(const wchar_t* name); void SaveReplay(const wchar_t* name);
// play // play
bool OpenReplay(const wchar_t* name);
static bool CheckReplay(const wchar_t* name); static bool CheckReplay(const wchar_t* name);
static bool DeleteReplay(const wchar_t* name); static bool DeleteReplay(const wchar_t* name);
static bool RenameReplay(const wchar_t* oldname, const wchar_t* newname); static bool RenameReplay(const wchar_t* oldname, const wchar_t* newname);
static size_t GetDeckPlayer(size_t deck_index) {
switch (deck_index) {
case 2:
return 3;
case 3:
return 2;
default:
return deck_index;
}
}
bool OpenReplay(const wchar_t* name);
bool ReadNextResponse(unsigned char resp[]); bool ReadNextResponse(unsigned char resp[]);
bool ReadName(wchar_t* data); bool ReadName(wchar_t* data);
void ReadHeader(ReplayHeader& header); void ReadHeader(ReplayHeader& header);
...@@ -67,6 +85,8 @@ public: ...@@ -67,6 +85,8 @@ public:
} }
int32_t ReadInt32(); int32_t ReadInt32();
void Rewind(); void Rewind();
void Reset();
void SkipInfo();
FILE* fp{ nullptr }; FILE* fp{ nullptr };
#ifdef _WIN32 #ifdef _WIN32
...@@ -77,12 +97,22 @@ public: ...@@ -77,12 +97,22 @@ public:
unsigned char* comp_data; unsigned char* comp_data;
size_t comp_size{}; size_t comp_size{};
std::vector<std::wstring> players; // 80 or 160 bytes
DuelParameters params; // 16 bytes
std::vector<DeckArray> decks; // 4 bytes, main deck, 4 bytes, extra deck
std::string script_name; // 2 bytes, script name (max: 256 bytes)
private: private:
bool ReadInfo();
unsigned char* replay_data; unsigned char* replay_data;
size_t replay_size{}; size_t replay_size{};
size_t data_position{}; size_t data_position{};
size_t info_offset{};
bool is_recording{}; bool is_recording{};
bool is_replaying{}; bool is_replaying{};
bool can_read{};
}; };
} }
......
...@@ -158,89 +158,65 @@ bool ReplayMode::StartDuel() { ...@@ -158,89 +158,65 @@ bool ReplayMode::StartDuel() {
const ReplayHeader& rh = cur_replay.pheader; const ReplayHeader& rh = cur_replay.pheader;
unsigned int seed = rh.seed; unsigned int seed = rh.seed;
std::mt19937 rnd(seed); std::mt19937 rnd(seed);
cur_replay.SkipInfo();
if(mainGame->dInfo.isTag) { if(mainGame->dInfo.isTag) {
cur_replay.ReadName(mainGame->dInfo.hostname); BufferIO::CopyWideString(cur_replay.players[0].c_str(), mainGame->dInfo.hostname);
cur_replay.ReadName(mainGame->dInfo.hostname_tag); BufferIO::CopyWideString(cur_replay.players[1].c_str(), mainGame->dInfo.hostname_tag);
cur_replay.ReadName(mainGame->dInfo.clientname_tag); BufferIO::CopyWideString(cur_replay.players[2].c_str(), mainGame->dInfo.clientname_tag);
cur_replay.ReadName(mainGame->dInfo.clientname); BufferIO::CopyWideString(cur_replay.players[3].c_str(), mainGame->dInfo.clientname);
} else { } else {
cur_replay.ReadName(mainGame->dInfo.hostname); BufferIO::CopyWideString(cur_replay.players[0].c_str(), mainGame->dInfo.hostname);
cur_replay.ReadName(mainGame->dInfo.clientname); BufferIO::CopyWideString(cur_replay.players[1].c_str(), mainGame->dInfo.clientname);
} }
pduel = create_duel(rnd()); pduel = create_duel(rnd());
int start_lp = cur_replay.ReadInt32(); mainGame->dInfo.duel_rule = cur_replay.params.duel_flag >> 16;
int start_hand = cur_replay.ReadInt32(); set_player_info(pduel, 0, cur_replay.params.start_lp, cur_replay.params.start_hand, cur_replay.params.draw_count);
int draw_count = cur_replay.ReadInt32(); set_player_info(pduel, 1, cur_replay.params.start_lp, cur_replay.params.start_hand, cur_replay.params.draw_count);
int opt = cur_replay.ReadInt32(); mainGame->dInfo.lp[0] = cur_replay.params.start_lp;
int duel_rule = opt >> 16; mainGame->dInfo.lp[1] = cur_replay.params.start_lp;
mainGame->dInfo.duel_rule = duel_rule; mainGame->dInfo.start_lp = cur_replay.params.start_lp;
set_player_info(pduel, 0, start_lp, start_hand, draw_count);
set_player_info(pduel, 1, start_lp, start_hand, draw_count);
mainGame->dInfo.lp[0] = start_lp;
mainGame->dInfo.lp[1] = start_lp;
mainGame->dInfo.start_lp = start_lp;
myswprintf(mainGame->dInfo.strLP[0], L"%d", mainGame->dInfo.lp[0]); myswprintf(mainGame->dInfo.strLP[0], L"%d", mainGame->dInfo.lp[0]);
myswprintf(mainGame->dInfo.strLP[1], L"%d", mainGame->dInfo.lp[1]); myswprintf(mainGame->dInfo.strLP[1], L"%d", mainGame->dInfo.lp[1]);
mainGame->dInfo.turn = 0; mainGame->dInfo.turn = 0;
if(!mainGame->dInfo.isSingleMode) { if(!(rh.flag & REPLAY_SINGLE_MODE)) {
if(!(opt & DUEL_TAG_MODE)) { if(!(rh.flag & REPLAY_TAG)) {
int main = cur_replay.ReadInt32(); for (int i = 0; i < 2; ++i) {
for(int i = 0; i < main; ++i) for (const auto& code : cur_replay.decks[i].main)
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE); new_card(pduel, code, i, i, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE);
int extra = cur_replay.ReadInt32(); for (const auto& code : cur_replay.decks[i].extra)
for(int i = 0; i < extra; ++i) new_card(pduel, code, i, i, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE); mainGame->dField.Initial(mainGame->LocalPlayer(i), cur_replay.decks[i].main.size(), cur_replay.decks[i].extra.size());
mainGame->dField.Initial(mainGame->LocalPlayer(0), main, extra);
main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE);
extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
mainGame->dField.Initial(mainGame->LocalPlayer(1), main, extra);
} else {
int main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE);
int extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
mainGame->dField.Initial(mainGame->LocalPlayer(0), main, extra);
main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
new_tag_card(pduel, cur_replay.ReadInt32(), 0, LOCATION_DECK);
extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_tag_card(pduel, cur_replay.ReadInt32(), 0, LOCATION_EXTRA);
main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE);
extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
mainGame->dField.Initial(mainGame->LocalPlayer(1), main, extra);
main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
new_tag_card(pduel, cur_replay.ReadInt32(), 1, LOCATION_DECK);
extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_tag_card(pduel, cur_replay.ReadInt32(), 1, LOCATION_EXTRA);
} }
} else { } else {
char filename[256]; for (const auto& code : cur_replay.decks[0].main)
auto slen = cur_replay.Read<uint16_t>(); new_card(pduel, code, 0, 0, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE);
if (slen > sizeof(filename) - 1) { for (const auto& code : cur_replay.decks[0].extra)
return false; new_card(pduel, code, 0, 0, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
mainGame->dField.Initial(mainGame->LocalPlayer(0), cur_replay.decks[0].main.size(), cur_replay.decks[0].extra.size());
for (const auto& code : cur_replay.decks[1].main)
new_tag_card(pduel, code, 0, LOCATION_DECK);
for (const auto& code : cur_replay.decks[1].extra)
new_tag_card(pduel, code, 0, LOCATION_EXTRA);
for (const auto& code : cur_replay.decks[2].main)
new_card(pduel, code, 1, 1, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE);
for (const auto& code : cur_replay.decks[2].extra)
new_card(pduel, code, 1, 1, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
mainGame->dField.Initial(mainGame->LocalPlayer(1), cur_replay.decks[2].main.size(), cur_replay.decks[2].extra.size());
for (const auto& code : cur_replay.decks[3].main)
new_tag_card(pduel, code, 1, LOCATION_DECK);
for (const auto& code : cur_replay.decks[3].extra)
new_tag_card(pduel, code, 1, LOCATION_EXTRA);
} }
cur_replay.ReadData(filename, slen); } else {
filename[slen] = 0; char filename[256]{};
std::snprintf(filename, sizeof filename, "./single/%s", cur_replay.script_name.c_str());
if(!preload_script(pduel, filename)) { if(!preload_script(pduel, filename)) {
return false; return false;
} }
} }
if (!(rh.flag & REPLAY_UNIFORM)) if (!(rh.flag & REPLAY_UNIFORM))
opt |= DUEL_OLD_REPLAY; cur_replay.params.duel_flag |= DUEL_OLD_REPLAY;
start_duel(pduel, opt); start_duel(pduel, cur_replay.params.duel_flag);
return true; return true;
} }
void ReplayMode::EndDuel() { void ReplayMode::EndDuel() {
......
...@@ -663,6 +663,7 @@ ...@@ -663,6 +663,7 @@
!counter 0x106b 狂爱指示物 !counter 0x106b 狂爱指示物
!counter 0x6c 访问指示物 !counter 0x6c 访问指示物
!counter 0x6d 祝台指示物 !counter 0x6d 祝台指示物
!counter 0x6e 四季指示物
#setnames, using tab for comment #setnames, using tab for comment
!setname 0x1 正义盟军 AOJ !setname 0x1 正义盟军 AOJ
!setname 0x2 次世代 ジェネクス !setname 0x2 次世代 ジェネクス
...@@ -1245,7 +1246,7 @@ ...@@ -1245,7 +1246,7 @@
!setname 0x1c0 龙华 竜華 !setname 0x1c0 龙华 竜華
!setname 0x1c1 阿尔戈☆群星 ARGS !setname 0x1c1 阿尔戈☆群星 ARGS
!setname 0x1c2 喷水引擎 アクア・ジェット !setname 0x1c2 喷水引擎 アクア・ジェット
!setname 0x1c3 Mitsurugi !setname 0x1c3 Mitsurugi
!setname 0x1c4 征龙 征竜 !setname 0x1c4 征龙 征竜
!setname 0x1c5 再世 再世 !setname 0x1c5 再世 再世
!setname 0x1c6 统王 ドミナス !setname 0x1c6 统王 ドミナス
...@@ -1254,3 +1255,6 @@ ...@@ -1254,3 +1255,6 @@
!setname 0x1c9 星辰 ドラゴンテイル !setname 0x1c9 星辰 ドラゴンテイル
!setname 0x1ca 味美喵 ヤミー !setname 0x1ca 味美喵 ヤミー
!setname 0x1cb K9 !setname 0x1cb K9
!setname 0x1cc 瞬间移动 テレポート
!setname 0x1cd 神艺 アルトメギア
!setname 0x1ce 狱神 獄神
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