Commit 00fcf99b authored by nanahira's avatar nanahira

merge script reader

parents 7e1d40b0 ae3da991
......@@ -18,7 +18,7 @@ ClientCard::ClientCard() {
is_showtarget = false;
is_showchaintarget = false;
is_highlighting = false;
is_disabled = false;
status = 0;
is_reversed = false;
cmdFlag = 0;
code = 0;
......@@ -132,7 +132,7 @@ void ClientCard::UpdateInfo(char* buf) {
int l = BufferIO::ReadInt8(buf);
int s = BufferIO::ReadInt8(buf);
BufferIO::ReadInt8(buf);
ClientCard* ecard = mainGame->dField.GetCard(c, l, s);
ClientCard* ecard = mainGame->dField.GetCard(mainGame->LocalPlayer(c), l, s);
equipTarget = ecard;
ecard->equipped.insert(this);
}
......@@ -143,7 +143,7 @@ void ClientCard::UpdateInfo(char* buf) {
int l = BufferIO::ReadInt8(buf);
int s = BufferIO::ReadInt8(buf);
BufferIO::ReadInt8(buf);
ClientCard* tcard = mainGame->dField.GetCard(c, l, s);
ClientCard* tcard = mainGame->dField.GetCard(mainGame->LocalPlayer(c), l, s);
cardTarget.insert(tcard);
tcard->ownerTarget.insert(this);
}
......@@ -164,10 +164,8 @@ void ClientCard::UpdateInfo(char* buf) {
}
if(flag & QUERY_OWNER)
owner = BufferIO::ReadInt32(buf);
if(flag & QUERY_IS_DISABLED)
is_disabled = BufferIO::ReadInt32(buf);
if(flag & QUERY_IS_PUBLIC)
is_public = BufferIO::ReadInt32(buf);
if(flag & QUERY_STATUS)
status = BufferIO::ReadInt32(buf);
if(flag & QUERY_LSCALE) {
lscale = BufferIO::ReadInt32(buf);
myswprintf(lscstring, L"%d", lscale);
......
......@@ -89,8 +89,7 @@ public:
u8 location;
u8 sequence;
u8 position;
u8 is_disabled;
u8 is_public;
u32 status;
u8 cHint;
u32 chValue;
u32 opParam;
......
......@@ -5,6 +5,7 @@ namespace ygo {
const wchar_t* DataManager::unknown_string = L"???";
wchar_t DataManager::strBuffer[4096];
byte DataManager::scriptBuffer[0x20000];
DataManager dataManager;
bool DataManager::LoadDB(const char* file) {
......@@ -315,5 +316,46 @@ int DataManager::CardReader(int code, void* pData) {
memset(pData, 0, sizeof(CardData));
return 0;
}
byte* DataManager::ScriptReaderEx(const char* script_name, int* slen) {
byte* buffer = ScriptReaderExDirectry("./expansions", script_name, slen);
if(buffer)
return buffer;
bool find = false;
FileSystem::TraversalDir("./expansions", [script_name, slen, &buffer, &find](const char* name, bool isdir) {
if(!find && isdir && strcmp(name, ".") && strcmp(name, "..") && strcmp(name, "pics") && strcmp(name, "script")) {
char subdir[1024];
sprintf(subdir, "./expansions/%s", name);
buffer = ScriptReaderExDirectry(subdir, script_name, slen);
if(buffer)
find = true;
}
});
if(find)
return buffer;
return ScriptReader(script_name, slen);
}
byte* DataManager::ScriptReaderExDirectry(const char* path, const char* script_name, int* slen) {
char sname[256];
sprintf(sname, "%s%s", path, script_name + 1); //default script name: ./script/c%d.lua
return ScriptReader(sname, slen);
}
byte* DataManager::ScriptReader(const char* script_name, int* slen) {
FILE *fp;
#ifdef _WIN32
wchar_t fname[256];
BufferIO::DecodeUTF8(script_name, fname);
fp = _wfopen(fname, L"rb");
#else
fp = fopen(script_name, "rb");
#endif
if(!fp)
return 0;
int len = fread(scriptBuffer, 1, sizeof(scriptBuffer), fp);
fclose(fp);
if(len >= sizeof(scriptBuffer))
return 0;
*slen = len;
return scriptBuffer;
}
}
......@@ -49,8 +49,12 @@ public:
wchar_t lmBuffer[32];
static wchar_t strBuffer[4096];
static byte scriptBuffer[0x20000];
static const wchar_t* unknown_string;
static int CardReader(int, void*);
static byte* ScriptReaderEx(const char* script_name, int* slen);
static byte* ScriptReaderExDirectry(const char* path, const char* script_name, int* slen);
static byte* ScriptReader(const char* script_name, int* slen);
};
......
......@@ -129,7 +129,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
switch(id) {
case BUTTON_CLEAR_DECK: {
mainGame->gMutex.Lock();
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, (wchar_t*)dataManager.GetSysString(1339));
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, dataManager.GetSysString(1339));
mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
prev_operation = id;
......@@ -185,7 +185,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
mainGame->gMutex.Lock();
wchar_t textBuffer[256];
myswprintf(textBuffer, L"%ls\n%ls", mainGame->cbDBDecks->getItem(sel), dataManager.GetSysString(1337));
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, (wchar_t*)textBuffer);
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, textBuffer);
mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
prev_operation = id;
......@@ -195,7 +195,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
case BUTTON_LEAVE_GAME: {
if(is_modified && !mainGame->chkIgnoreDeckChanges->isChecked()) {
mainGame->gMutex.Lock();
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, (wchar_t*)dataManager.GetSysString(1356));
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, dataManager.GetSysString(1356));
mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
prev_operation = id;
......@@ -362,7 +362,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
case COMBOBOX_DBDECKS: {
if(is_modified && !mainGame->chkIgnoreDeckChanges->isChecked()) {
mainGame->gMutex.Lock();
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, (wchar_t*)dataManager.GetSysString(1356));
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, dataManager.GetSysString(1356));
mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
prev_operation = id;
......@@ -676,14 +676,14 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
return false;
}
void DeckBuilder::GetHoveredCard() {
int pre_code = hovered_code;
hovered_pos = 0;
hovered_code = 0;
irr::gui::IGUIElement* root = mainGame->env->getRootGUIElement();
if(root->getElementFromPoint(mouse_pos) != root)
return;
int x = mouse_pos.X;
int y = mouse_pos.Y;
int pre_code = hovered_code;
hovered_pos = 0;
hovered_code = 0;
is_lastcard = 0;
if(x >= 314 && x <= 794) {
if(y >= 164 && y <= 435) {
......@@ -775,14 +775,78 @@ void DeckBuilder::StartFilter() {
}
void DeckBuilder::FilterCards() {
results.clear();
struct element_t {
std::wstring keyword;
int setcode;
enum class type_t {
all,
name,
setcode
} type;
bool exclude;
element_t(): setcode(0), type(type_t::all), exclude(false) {}
};
const wchar_t* pstr = mainGame->ebCardName->getText();
unsigned int set_code = 0;
if(pstr[0] == L'@')
set_code = dataManager.GetSetCode(&pstr[1]);
else
set_code = dataManager.GetSetCode(&pstr[0]);
if(pstr[0] == 0 || (pstr[0] == L'$' && pstr[1] == 0) || (pstr[0] == L'@' && pstr[1] == 0))
pstr = 0;
std::wstring str = std::wstring(pstr);
std::vector<element_t> query_elements;
if(mainGame->gameConf.search_multiple_keywords) {
const wchar_t separator = mainGame->gameConf.search_multiple_keywords == 1 ? L' ' : L'+';
const wchar_t minussign = L'-';
const wchar_t quotation = L'\"';
size_t element_start = 0;
for(;;) {
element_start = str.find_first_not_of(separator, element_start);
if(element_start == std::wstring::npos)
break;
element_t element;
if(str[element_start] == minussign) {
element.exclude = true;
element_start++;
}
if(element_start >= str.size())
break;
if(str[element_start] == L'$') {
element.type = element_t::type_t::name;
element_start++;
} else if(str[element_start] == L'@') {
element.type = element_t::type_t::setcode;
element_start++;
}
if(element_start >= str.size())
break;
wchar_t delimiter = separator;
if(str[element_start] == quotation) {
delimiter = quotation;
element_start++;
}
size_t element_end = str.find_first_of(delimiter, element_start);
if(element_end != std::wstring::npos) {
size_t length = element_end - element_start;
element.keyword = str.substr(element_start, length);
} else
element.keyword = str.substr(element_start);
element.setcode = dataManager.GetSetCode(element.keyword.c_str());
query_elements.push_back(element);
if(element_end == std::wstring::npos)
break;
element_start = element_end + 1;
}
} else {
element_t element;
size_t element_start = 0;
if(str[element_start] == L'$') {
element.type = element_t::type_t::name;
element_start++;
} else if(str[element_start] == L'@') {
element.type = element_t::type_t::setcode;
element_start++;
}
if(element_start < str.size()) {
element.keyword = str.substr(element_start);
element.setcode = dataManager.GetSetCode(element.keyword.c_str());
query_elements.push_back(element);
}
}
auto strpointer = dataManager._strings.begin();
for(code_pointer ptr = dataManager._datas.begin(); ptr != dataManager._datas.end(); ++ptr, ++strpointer) {
const CardDataC& data = ptr->second;
......@@ -856,24 +920,35 @@ void DeckBuilder::FilterCards() {
if(filter_lm == 7 && data.ot != 4)
continue;
}
if(pstr) {
if(pstr[0] == L'$') {
if(!CardNameContains(text.name.c_str(), &pstr[1]))
continue;
} else if(pstr[0] == L'@' && set_code) {
if(!check_set_code(data, set_code)) continue;
bool is_target = true;
for (auto elements_iterator = query_elements.begin(); elements_iterator != query_elements.end(); ++elements_iterator) {
bool match = false;
if (elements_iterator->type == element_t::type_t::name) {
match = CardNameContains(text.name.c_str(), elements_iterator->keyword.c_str());
} else if (elements_iterator->type == element_t::type_t::setcode) {
match = elements_iterator->setcode && check_set_code(data, elements_iterator->setcode);
} else {
int trycode = BufferIO::GetVal(pstr);
int trycode = BufferIO::GetVal(elements_iterator->keyword.c_str());
bool tryresult = dataManager.GetData(trycode, 0);
if(!tryresult && !CardNameContains(text.name.c_str(), pstr) && text.text.find(pstr) == std::wstring::npos
&& (!set_code || !check_set_code(data, set_code)))
continue;
if (tryresult && data.code != trycode
&& !(data.alias == trycode && (data.alias - data.code < CARD_ARTWORK_VERSIONS_OFFSET || data.code - data.alias < CARD_ARTWORK_VERSIONS_OFFSET)))
continue;
if(!tryresult) {
match = CardNameContains(text.name.c_str(), elements_iterator->keyword.c_str())
|| text.text.find(elements_iterator->keyword) != std::wstring::npos
|| (elements_iterator->setcode && check_set_code(data, elements_iterator->setcode));
} else {
match = data.code == trycode || data.alias == trycode;
}
}
if(elements_iterator->exclude)
match = !match;
if(!match) {
is_target = false;
break;
}
}
results.push_back(ptr);
if(is_target)
results.push_back(ptr);
else
continue;
}
myswprintf(result_string, L"%d", results.size());
if(results.size() > 7) {
......
......@@ -382,7 +382,8 @@ void Game::DrawCard(ClientCard* pcard) {
matManager.mTexture.setTexture(0, imageManager.tChainTarget);
driver->setMaterial(matManager.mTexture);
driver->drawVertexPrimitiveList(matManager.vSymbol, 4, matManager.iRectangle, 2);
} else if(pcard->is_disabled && (pcard->location & LOCATION_ONFIELD) && (pcard->position & POS_FACEUP)) {
} else if((pcard->status & (STATUS_DISABLED | STATUS_FORBIDDEN))
&& (pcard->location & LOCATION_ONFIELD) && (pcard->position & POS_FACEUP)) {
matManager.mTexture.setTexture(0, imageManager.tNegated);
driver->setMaterial(matManager.mTexture);
driver->drawVertexPrimitiveList(matManager.vNegate, 4, matManager.iRectangle, 2);
......
......@@ -24,6 +24,7 @@ char DuelClient::duel_client_read[0x2000];
char DuelClient::duel_client_write[0x2000];
bool DuelClient::is_closing = false;
int DuelClient::select_hint = 0;
int DuelClient::select_unselect_hint = 0;
wchar_t DuelClient::event_string[256];
mtrandom DuelClient::rnd;
......@@ -469,7 +470,7 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->stHostPrepDuelist[2]->setText(L"");
mainGame->stHostPrepDuelist[3]->setText(L"");
mainGame->stHostPrepOB->setText(L"");
mainGame->SetStaticText(mainGame->stHostPrepRule, 180, mainGame->guiFont, (wchar_t*)str.c_str());
mainGame->SetStaticText(mainGame->stHostPrepRule, 180, mainGame->guiFont, str.c_str());
mainGame->RefreshDeck(mainGame->cbDeckSelect);
mainGame->cbDeckSelect->setEnabled(true);
if(mainGame->wCreateHost->isVisible())
......@@ -1304,6 +1305,10 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
wchar_t ynbuf[256];
myswprintf(ynbuf, dataManager.GetSysString(200), dataManager.FormatLocation(l, s), dataManager.GetName(code));
myswprintf(textBuffer, L"%ls\n%ls", event_string, ynbuf);
} else if(desc == 221) {
wchar_t ynbuf[256];
myswprintf(ynbuf, dataManager.GetSysString(221), dataManager.FormatLocation(l, s), dataManager.GetName(code));
myswprintf(textBuffer, L"%ls\n%ls\n%ls", event_string, ynbuf, dataManager.GetSysString(223));
} else if(desc < 2048) {
myswprintf(textBuffer, dataManager.GetSysString(desc), dataManager.GetName(code));
} else {
......@@ -1320,7 +1325,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
int desc = BufferIO::ReadInt32(pbuf);
mainGame->dField.highlighting_card = 0;
mainGame->gMutex.Lock();
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, (wchar_t*)dataManager.GetDesc(desc));
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, dataManager.GetDesc(desc));
mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
return false;
......@@ -1448,7 +1453,9 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
}
std::sort(mainGame->dField.selectable_cards.begin(), mainGame->dField.selectable_cards.end(), ClientCard::client_card_sort);
if(select_hint)
myswprintf(textBuffer, L"%ls(%d-%d)", dataManager.GetDesc(select_hint),
select_unselect_hint = select_hint;
if(select_unselect_hint)
myswprintf(textBuffer, L"%ls(%d-%d)", dataManager.GetDesc(select_unselect_hint),
mainGame->dField.select_min, mainGame->dField.select_max);
else myswprintf(textBuffer, L"%ls(%d-%d)", dataManager.GetSysString(560), mainGame->dField.select_min, mainGame->dField.select_max);
select_hint = 0;
......@@ -1558,9 +1565,11 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
if(!forced) {
if(count == 0)
myswprintf(textBuffer, L"%ls\n%ls", dataManager.GetSysString(201), dataManager.GetSysString(202));
else if(select_trigger)
myswprintf(textBuffer, L"%ls\n%ls\n%ls", event_string, dataManager.GetSysString(222), dataManager.GetSysString(223));
else
myswprintf(textBuffer, L"%ls\n%ls", event_string, dataManager.GetSysString(203));
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, (wchar_t*)textBuffer);
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, textBuffer);
mainGame->PopupElement(mainGame->wQuery);
}
}
......
......@@ -30,6 +30,7 @@ private:
static char duel_client_write[0x2000];
static bool is_closing;
static int select_hint;
static int select_unselect_hint;
static wchar_t event_string[256];
static mtrandom rnd;
public:
......
......@@ -279,7 +279,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
mainGame->btnOptionn->setVisible(true);
if(selected_option == 0)
mainGame->btnOptionp->setVisible(false);
mainGame->SetStaticText(mainGame->stOptions, 310, mainGame->textFont, (wchar_t*)dataManager.GetDesc(select_options[selected_option]));
mainGame->SetStaticText(mainGame->stOptions, 310, mainGame->textFont, dataManager.GetDesc(select_options[selected_option]));
break;
}
case BUTTON_OPTION_NEXT: {
......@@ -288,7 +288,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
mainGame->btnOptionp->setVisible(true);
if(selected_option == select_options.size() - 1)
mainGame->btnOptionn->setVisible(false);
mainGame->SetStaticText(mainGame->stOptions, 310, mainGame->textFont, (wchar_t*)dataManager.GetDesc(select_options[selected_option]));
mainGame->SetStaticText(mainGame->stOptions, 310, mainGame->textFont, dataManager.GetDesc(select_options[selected_option]));
break;
}
case BUTTON_OPTION_0: {
......@@ -1797,6 +1797,15 @@ bool ClientField::OnCommonEvent(const irr::SEvent& event) {
switch(id) {
case CHECKBOX_AUTO_SEARCH: {
mainGame->gameConf.auto_search_limit = mainGame->chkAutoSearch->isChecked() ? 0 : -1;
if(mainGame->is_building && !mainGame->is_siding)
mainGame->deckBuilder.InstantSearch();
return true;
break;
}
case CHECKBOX_MULTI_KEYWORDS: {
mainGame->gameConf.search_multiple_keywords = mainGame->chkMultiKeywords->isChecked() ? 1 : 0;
if(mainGame->is_building && !mainGame->is_siding)
mainGame->deckBuilder.InstantSearch();
return true;
break;
}
......@@ -2234,6 +2243,9 @@ void ClientField::ShowCardInfoInList(ClientCard* pcard, irr::gui::IGUIElement* e
if(pcard->code) {
str.append(dataManager.GetName(pcard->code));
}
if((pcard->status & STATUS_PROC_COMPLETE)
&& (pcard->type & (TYPE_RITUAL | TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_LINK | TYPE_SPSUMMON)))
str.append(L"\n").append(dataManager.GetSysString(224));
for(size_t i = 0; i < chains.size(); ++i) {
wchar_t formatBuffer[2048];
auto chit = chains[i];
......
......@@ -10,7 +10,7 @@
#include "netserver.h"
#include "single_mode.h"
const unsigned short PRO_VERSION = 0x1346;
const unsigned short PRO_VERSION = 0x1348;
namespace ygo {
......@@ -297,6 +297,9 @@ bool Game::Initialize() {
chkAutoSearch = env->addCheckBox(false, rect<s32>(posX, posY, posX + 260, posY + 25), tabSystem, CHECKBOX_AUTO_SEARCH, dataManager.GetSysString(1358));
chkAutoSearch->setChecked(gameConf.auto_search_limit >= 0);
posY += 30;
chkMultiKeywords = env->addCheckBox(false, rect<s32>(posX, posY, posX + 260, posY + 25), tabSystem, CHECKBOX_MULTI_KEYWORDS, dataManager.GetSysString(1378));
chkMultiKeywords->setChecked(gameConf.search_multiple_keywords > 0);
posY += 30;
chkEnableSound = env->addCheckBox(gameConf.enable_sound, rect<s32>(posX, posY, posX + 120, posY + 25), tabSystem, -1, dataManager.GetSysString(1279));
chkEnableSound->setChecked(gameConf.enable_sound);
scrSoundVolume = env->addScrollBar(true, rect<s32>(posX + 126, posY + 4, posX + 260, posY + 21), tabSystem, SCROLL_VOLUME);
......@@ -998,6 +1001,7 @@ void Game::LoadConfig() {
gameConf.draw_field_spell = 1;
gameConf.separate_clear_button = 1;
gameConf.auto_search_limit = -1;
gameConf.search_multiple_keywords = 1;
gameConf.chkIgnoreDeckChanges = 0;
gameConf.defaultOT = 1;
gameConf.enable_bot_mode = 0;
......@@ -1064,6 +1068,8 @@ void Game::LoadConfig() {
gameConf.separate_clear_button = atoi(valbuf);
} else if(!strcmp(strbuf, "auto_search_limit")) {
gameConf.auto_search_limit = atoi(valbuf);
} else if(!strcmp(strbuf, "search_multiple_keywords")) {
gameConf.search_multiple_keywords = atoi(valbuf);
} else if(!strcmp(strbuf, "ignore_deck_changes")) {
gameConf.chkIgnoreDeckChanges = atoi(valbuf);
} else if(!strcmp(strbuf, "default_ot")) {
......@@ -1143,6 +1149,8 @@ void Game::SaveConfig() {
fprintf(fp, "separate_clear_button = %d\n", gameConf.separate_clear_button);
fprintf(fp, "#auto_search_limit >= 0: Start search automatically when the user enters N chars\n");
fprintf(fp, "auto_search_limit = %d\n", gameConf.auto_search_limit);
fprintf(fp, "#search_multiple_keywords = 0: Disable. 1: Search mutiple keywords with separator \" \". 2: with separator \"+\"\n");
fprintf(fp, "search_multiple_keywords = %d\n", gameConf.search_multiple_keywords);
fprintf(fp, "ignore_deck_changes = %d\n", (chkIgnoreDeckChanges->isChecked() ? 1 : 0));
fprintf(fp, "default_ot = %d\n", gameConf.defaultOT);
fprintf(fp, "enable_bot_mode = %d\n", gameConf.enable_bot_mode);
......
......@@ -39,6 +39,7 @@ struct Config {
int draw_field_spell;
int separate_clear_button;
int auto_search_limit;
int search_multiple_keywords;
int chkIgnoreDeckChanges;
int defaultOT;
int enable_bot_mode;
......@@ -250,6 +251,7 @@ public:
irr::gui::IGUICheckBox* chkHideHintButton;
irr::gui::IGUICheckBox* chkIgnoreDeckChanges;
irr::gui::IGUICheckBox* chkAutoSearch;
irr::gui::IGUICheckBox* chkMultiKeywords;
irr::gui::IGUICheckBox* chkEnableSound;
irr::gui::IGUICheckBox* chkEnableMusic;
irr::gui::IGUIScrollBar* scrSoundVolume;
......@@ -627,6 +629,7 @@ extern Game* mainGame;
#define BUTTON_LOAD_SINGLEPLAY 351
#define BUTTON_CANCEL_SINGLEPLAY 352
#define CHECKBOX_AUTO_SEARCH 360
#define CHECKBOX_MULTI_KEYWORDS 372
#define CHECKBOX_ENABLE_SOUND 361
#define CHECKBOX_ENABLE_MUSIC 362
#define SCROLL_VOLUME 363
......
......@@ -248,7 +248,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
mainGame->gMutex.Lock();
wchar_t textBuffer[256];
myswprintf(textBuffer, L"%ls\n%ls", mainGame->lstReplayList->getListItem(sel), dataManager.GetSysString(1363));
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, (wchar_t*)textBuffer);
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, textBuffer);
mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
prev_operation = id;
......
......@@ -5,10 +5,7 @@
#include <functional>
#include "bufferio.h"
#ifdef _WIN32
#include <direct.h>
#include <sys/stat.h>
#else
#ifndef _WIN32
#include <dirent.h>
#include <sys/stat.h>
#endif
......@@ -20,8 +17,8 @@
class FileSystem {
public:
static bool IsFileExists(const wchar_t* wfile) {
struct _stat fileStat;
return (_wstat(wfile, &fileStat) == 0) && !(fileStat.st_mode & _S_IFDIR);
DWORD attr = GetFileAttributesW(wfile);
return attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY);
}
static bool IsFileExists(const char* file) {
......@@ -31,8 +28,8 @@ public:
}
static bool IsDirExists(const wchar_t* wdir) {
struct _stat fileStat;
return (_wstat(wdir, &fileStat) == 0) && (fileStat.st_mode & _S_IFDIR);
DWORD attr = GetFileAttributesW(wdir);
return attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY);
}
static bool IsDirExists(const char* dir) {
......@@ -42,7 +39,7 @@ public:
}
static bool MakeDir(const wchar_t* wdir) {
return _wmkdir(wdir) == 0;
return CreateDirectoryW(wdir, NULL);
}
static bool MakeDir(const char* dir) {
......
......@@ -66,15 +66,9 @@ int ReplayMode::ReplayThread(void* param) {
mainGame->dInfo.isSingleMode = !!(rh.flag & REPLAY_SINGLE_MODE);
mainGame->dInfo.tag_player[0] = false;
mainGame->dInfo.tag_player[1] = false;
if(mainGame->dInfo.isSingleMode) {
set_script_reader((script_reader)SingleMode::ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)MessageHandler);
} else {
set_script_reader((script_reader)ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)MessageHandler);
}
set_script_reader((script_reader)DataManager::ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)MessageHandler);
if(!StartDuel()) {
EndDuel();
return 0;
......@@ -938,30 +932,6 @@ void ReplayMode::ReplayReload() {
/*len = */query_field_card(pduel, 1, LOCATION_REMOVED, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_REMOVED, (char*)queryBuffer);
}
byte* ReplayMode::ScriptReaderEx(const char* script_name, int* slen) {
byte* buffer = ScriptReaderExDirectry("./expansions", script_name, slen);
if(buffer)
return buffer;
bool find = false;
FileSystem::TraversalDir("./expansions", [script_name, slen, &buffer, &find](const char* name, bool isdir) {
if(!find && isdir && strcmp(name, ".") && strcmp(name, "..") && strcmp(name, "pics") && strcmp(name, "script")) {
char subdir[1024];
sprintf(subdir, "./expansions/%s", name);
buffer = ScriptReaderExDirectry(subdir, script_name, slen);
if(buffer)
find = true;
}
});
if(find)
return buffer;
return default_script_reader(script_name, slen);
}
byte* ReplayMode::ScriptReaderExDirectry(const char* path, const char* script_name, int* slen) {
char sname[256];
strcpy(sname, path);
strcat(sname, script_name + 1);//default script name: ./script/c%d.lua
return default_script_reader(sname, slen);
}
int ReplayMode::MessageHandler(long fduel, int type) {
if(!enable_log)
return 0;
......
......@@ -47,8 +47,6 @@ public:
static void ReplayRefreshSingle(int player, int location, int sequence, int flag = 0xf81fff);
static void ReplayReload();
static byte* ScriptReaderEx(const char* script_name, int* slen);
static byte* ScriptReaderExDirectry(const char* path, const char* script_name, int* slen);
static int MessageHandler(long fduel, int type);
};
......
......@@ -409,7 +409,7 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
}
time_limit[0] = host_info.time_limit;
time_limit[1] = host_info.time_limit;
set_script_reader((script_reader)ScriptReaderEx);
set_script_reader((script_reader)DataManager::ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)SingleDuel::MessageHandler);
rnd.reset(seed);
......@@ -1490,18 +1490,17 @@ void SingleDuel::RefreshHand(int player, int flag, int use_cache) {
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
BufferIO::WriteInt8(qbuf, LOCATION_HAND);
int len = query_field_card(pduel, player, LOCATION_HAND, flag | QUERY_IS_PUBLIC, (unsigned char*)qbuf, use_cache);
int len = query_field_card(pduel, player, LOCATION_HAND, flag | QUERY_POSITION, (unsigned char*)qbuf, use_cache);
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 3);
int qlen = 0;
while(qlen < len) {
int slen = BufferIO::ReadInt32(qbuf);
int qflag = *(int*)qbuf;
int pos = slen - 8;
if(qflag & QUERY_LSCALE)
pos -= 4;
if(qflag & QUERY_RSCALE)
pos -= 4;
if(!qbuf[pos])
int offset = 8;
if(!(qflag & QUERY_CODE))
offset -= 4;
unsigned position = ((*(int*)(qbuf + offset)) >> 24) & 0xff;
if(!(position & POS_FACEUP))
memset(qbuf, 0, slen - 4);
qbuf += slen - 4;
qlen += slen;
......@@ -1548,30 +1547,6 @@ void SingleDuel::RefreshSingle(int player, int location, int sequence, int flag)
NetServer::ReSendToPlayer(*pit);
}
}
byte* SingleDuel::ScriptReaderEx(const char* script_name, int* slen) {
byte* buffer = ScriptReaderExDirectry("./expansions", script_name, slen);
if(buffer)
return buffer;
bool find = false;
FileSystem::TraversalDir("./expansions", [script_name, slen, &buffer, &find](const char* name, bool isdir) {
if(!find && isdir && strcmp(name, ".") && strcmp(name, "..") && strcmp(name, "pics") && strcmp(name, "script")) {
char subdir[1024];
sprintf(subdir, "./expansions/%s", name);
buffer = ScriptReaderExDirectry(subdir, script_name, slen);
if(buffer)
find = true;
}
});
if(find)
return buffer;
return default_script_reader(script_name, slen);
}
byte* SingleDuel::ScriptReaderExDirectry(const char* path, const char* script_name, int* slen) {
char sname[256];
strcpy(sname, path);
strcat(sname, script_name + 1);//default script name: ./script/c%d.lua
return default_script_reader(sname, slen);
}
int SingleDuel::MessageHandler(long fduel, int type) {
if(!enable_log)
return 0;
......
......@@ -38,8 +38,6 @@ public:
void RefreshExtra(int player, int flag = 0x81fff, int use_cache = 1);
void RefreshSingle(int player, int location, int sequence, int flag = 0xf81fff);
static byte* ScriptReaderEx(const char* script_name, int* slen);
static byte* ScriptReaderExDirectry(const char* path, const char* script_name, int* slen);
static int MessageHandler(long fduel, int type);
static void SingleTimer(evutil_socket_t fd, short events, void* arg);
......
......@@ -14,8 +14,6 @@ bool SingleMode::is_closing = false;
bool SingleMode::is_continuing = false;
Replay SingleMode::last_replay;
static byte buffer[0x20000];
bool SingleMode::StartPlay() {
Thread::NewThread(SinglePlayThread, 0);
return true;
......@@ -41,7 +39,7 @@ int SingleMode::SinglePlayThread(void* param) {
mtrandom rnd;
time_t seed = time(0);
rnd.reset(seed);
set_script_reader((script_reader)ScriptReaderEx);
set_script_reader((script_reader)DataManager::ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)MessageHandler);
pduel = create_duel(rnd.rand());
......@@ -855,47 +853,6 @@ void SingleMode::SinglePlayReload() {
/*len = */query_field_card(pduel, 1, LOCATION_REMOVED, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_REMOVED, (char*)queryBuffer);
}
byte* SingleMode::ScriptReaderEx(const char* script_name, int* slen) {
byte* buffer = ScriptReaderExDirectry("./expansions", script_name, slen);
if(buffer)
return buffer;
bool find = false;
FileSystem::TraversalDir("./expansions", [script_name, slen, &buffer, &find](const char* name, bool isdir) {
if(!find && isdir && strcmp(name, ".") && strcmp(name, "..") && strcmp(name, "pics") && strcmp(name, "script")) {
char subdir[1024];
sprintf(subdir, "./expansions/%s", name);
buffer = ScriptReaderExDirectry(subdir, script_name, slen);
if(buffer)
find = true;
}
});
if(find)
return buffer;
return ScriptReader(script_name, slen);
}
byte* SingleMode::ScriptReaderExDirectry(const char* path, const char* script_name, int* slen) {
char sname[256];
sprintf(sname, "%s%s", path, script_name + 1); //default script name: ./script/c%d.lua
return ScriptReader(sname, slen);
}
byte* SingleMode::ScriptReader(const char* script_name, int* slen) {
FILE *fp;
#ifdef _WIN32
wchar_t fname[256];
BufferIO::DecodeUTF8(script_name, fname);
fp = _wfopen(fname, L"rb");
#else
fp = fopen(script_name, "rb");
#endif
if(!fp)
return 0;
int len = fread(buffer, 1, sizeof(buffer), fp);
fclose(fp);
if(len >= sizeof(buffer))
return 0;
*slen = len;
return buffer;
}
int SingleMode::MessageHandler(long fduel, int type) {
if(!enable_log)
return 0;
......
......@@ -26,9 +26,6 @@ public:
static void SinglePlayRefreshSingle(int player, int location, int sequence, int flag = 0xf81fff);
static void SinglePlayReload();
static byte* ScriptReaderEx(const char* script_name, int* slen);
static byte* ScriptReaderExDirectry(const char* path, const char* script_name, int* slen);
static byte* ScriptReader(const char* script_name, int* slen);
static int MessageHandler(long fduel, int type);
protected:
......
......@@ -384,7 +384,7 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
}
time_limit[0] = host_info.time_limit;
time_limit[1] = host_info.time_limit;
set_script_reader((script_reader)ScriptReaderEx);
set_script_reader((script_reader)DataManager::ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)TagDuel::MessageHandler);
rnd.reset(seed);
......@@ -1586,18 +1586,17 @@ void TagDuel::RefreshHand(int player, int flag, int use_cache) {
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
BufferIO::WriteInt8(qbuf, LOCATION_HAND);
int len = query_field_card(pduel, player, LOCATION_HAND, flag | QUERY_IS_PUBLIC, (unsigned char*)qbuf, use_cache);
int len = query_field_card(pduel, player, LOCATION_HAND, flag | QUERY_POSITION, (unsigned char*)qbuf, use_cache);
NetServer::SendBufferToPlayer(cur_player[player], STOC_GAME_MSG, query_buffer, len + 3);
int qlen = 0;
while(qlen < len) {
int slen = BufferIO::ReadInt32(qbuf);
int qflag = *(int*)qbuf;
int pos = slen - 8;
if(qflag & QUERY_LSCALE)
pos -= 4;
if(qflag & QUERY_RSCALE)
pos -= 4;
if(!qbuf[pos])
int offset = 8;
if(!(qflag & QUERY_CODE))
offset -= 4;
unsigned position = ((*(int*)(qbuf + offset)) >> 24) & 0xff;
if(!(position & POS_FACEUP))
memset(qbuf, 0, slen - 4);
qbuf += slen - 4;
qlen += slen;
......@@ -1665,31 +1664,6 @@ void TagDuel::RefreshSingle(int player, int location, int sequence, int flag) {
}
}
}
byte* TagDuel::ScriptReaderEx(const char* script_name, int* slen) {
byte* buffer = ScriptReaderExDirectry("./expansions", script_name, slen);
if(buffer)
return buffer;
bool find = false;
FileSystem::TraversalDir("./expansions", [script_name, slen, &buffer, &find](const char* name, bool isdir) {
if(!find && isdir && strcmp(name, ".") && strcmp(name, "..") && strcmp(name, "pics") && strcmp(name, "script")) {
char subdir[1024];
sprintf(subdir, "./expansions/%s", name);
buffer = ScriptReaderExDirectry(subdir, script_name, slen);
if(buffer)
find = true;
}
});
if(find)
return buffer;
return default_script_reader(script_name, slen);
}
byte* TagDuel::ScriptReaderExDirectry(const char* path, const char* script_name, int* slen) {
char sname[256];
strcpy(sname, path);
strcat(sname, script_name + 1);//default script name: ./script/c%d.lua
return default_script_reader(sname, slen);
}
int TagDuel::MessageHandler(long fduel, int type) {
if(!enable_log)
return 0;
......
......@@ -38,8 +38,6 @@ public:
void RefreshExtra(int player, int flag = 0x81fff, int use_cache = 1);
void RefreshSingle(int player, int location, int sequence, int flag = 0xf81fff);
static byte* ScriptReaderEx(const char* script_name, int* slen);
static byte* ScriptReaderExDirectry(const char* path, const char* script_name, int* slen);
static int MessageHandler(long fduel, int type);
static void TagTimer(evutil_socket_t fd, short events, void* arg);
......
#[2018.10][2018.9 TCG][2018.7][2018.4][2018.1][2017.10][2017.7][2017.4][2017.1][2016.10][2016.7][2016.4][2016.1][2015.10][2015.4][2015.1][2014.10][2014.7][2014.4][2014.2][2013.9][2018.5 TCG][2018.2 TCG][2017.11 TCG][2017.9 TCG][2017.6 TCG][2017.3 TCG][2016.8 TCG][2016.4 TCG][2015.11 TCG][2015.7 TCG][2015.4 TCG][2015.1 TCG][2014.10 TCG][2014.7 TCG][2014.4 TCG][2014.1.1 TCG][2013.10.11 TCG][2013.3.1][2012.9.1][2012.3.1][2011.9.1]
#[2018.10][2018.12 TCG][2018.7][2018.4][2018.1][2017.10][2017.7][2017.4][2017.1][2016.10][2016.7][2016.4][2016.1][2015.10][2015.4][2015.1][2014.10][2014.7][2014.4][2014.2][2013.9][2018.9 TCG][2018.5 TCG][2018.2 TCG][2017.11 TCG][2017.9 TCG][2017.6 TCG][2017.3 TCG][2016.8 TCG][2016.4 TCG][2015.11 TCG][2015.7 TCG][2015.4 TCG][2015.1 TCG][2014.10 TCG][2014.7 TCG][2014.4 TCG][2014.1.1 TCG][2013.10.11 TCG][2013.3.1][2012.9.1][2012.3.1][2011.9.1]
!2018.10
#forbidden
......@@ -167,8 +167,9 @@
35125879 2 --真竜皇の復活
83555666 2 --破壊輪
!2018.9 TCG
!2018.12 TCG
#forbidden
05043010 0 --ファイアウォール・ドラゴン
05592689 0 --サクリファイス・ロータス
39064822 0 --トロイメア・ゴブリン
04423206 0 --M.X-セイバー インヴォーカー
......@@ -254,7 +255,7 @@
80604091 0 --血の代償
28566710 0 --ラストバトル!
#limit
30012506 1 --A-アサルト・コア
28985331 1 --終末の騎士
40044918 1 --E·HERO エアーマン
33508719 1 --メタモルポット
24094258 1 --ヘビーメタルフォーゼ・エレクトラム
......@@ -291,7 +292,6 @@
20758643 1 --彼岸の悪鬼 グラバースニッチ
70583986 1 --氷結界の虎王ドゥローレン
52687916 1 --氷結界の龍 トリシューラ
05043010 1 --ファイアウォール・ドラゴン
33396948 1 --封印されしエクゾディア
07902349 1 --封印されし者の左腕
70903634 1 --封印されし者の右腕
......@@ -341,8 +341,7 @@
32723153 1 --マジカル·エクスプロージョン
54974237 1 --闇のデッキ破壊ウイルス
#semi limit
55885348 2 --Kozmo-ダークシミター
24224830 2 --墓穴の指名者
09411399 2 --DHERO ディアボリックガイ
23171610 2 --リミッター解除
73915051 2 --スケープ・ゴート
73628505 2 --テラ・フォーミング
......@@ -3263,6 +3262,190 @@
53582587 2 --激流葬
29401950 2 --奈落の落とし穴
!2018.9 TCG
#forbidden
05592689 0 --サクリファイス・ロータス
39064822 0 --トロイメア・ゴブリン
04423206 0 --M.X-セイバー インヴォーカー
76794549 0 --アストログラフ・マジシャン
20663556 0 --イレカエル
44910027 0 --ヴィクトリー・ドラゴン
20366274 0 --エルシャドール・ネフィリム
25862681 0 --エンシェント・フェアリー・ドラゴン
53804307 0 --焔征竜-ブラスター
07563579 0 --Emヒグルミ
40318957 0 --EMドクロバット・ジョーカー
17330916 0 --EMモンキーボード
82301904 0 --混沌帝龍 -終焉の使者-
79106360 0 --カオスポッド
90411554 0 --巌征竜-レドックス
08903700 0 --儀式魔人リリーサー
17412721 0 --旧神ノーデン
65536818 0 --源竜星-ボウテンコウ
49684352 0 --虹彩の魔術師
34124316 0 --サイバーポッド
88071625 0 --The tyrant NEPTUNE
48905153 0 --十二獣ドランシア
85115440 0 --十二獣ブルホーン
21593977 0 --処刑人-マキュラ
30539496 0 --真竜皇リトスアジムD
21377582 0 --真竜剣皇マスターP
81122844 0 --発条空母ゼンマイティ
23434538 0 --増殖するG
00581014 0 --ダイガスタ・エメラル
15341821 0 --ダンディライオン
69015963 0 --デビル·フランケン
18326736 0 --星守の騎士 プトレマイオス
33184167 0 --同族感染ウィルス
90307777 0 --影霊衣の術士 シュリット
54719828 0 --No.16 色の支配者ショック·ルーラー
43387895 0 --覇王眷竜スターヴ・ヴェノム
26400609 0 --瀑征竜-タイダル
78706415 0 --ファイバーポッド
93369354 0 --フィッシュボーグ-ガンナー
23558733 0 --フェニキシアン・クラスター・アマリリス
09929398 0 --BF-朧影のゴウフウ
31178212 0 --マジェスペクター・ユニコーン
34206604 0 --魔導サイエンティスト
96782886 0 --メンタルマスター
03078576 0 --八汰烏
34086406 0 --ラヴァルバル·チェイン
89399912 0 --嵐征竜-テンペスト
57421866 0 --レベル・スティーラー
41482598 0 --悪夢の蜃気楼
44763025 0 --いたずら好きな双子悪魔
19613556 0 --大嵐
17375316 0 --押収
35059553 0 --カイザーコロシアム
74191942 0 --苦渋の選択
42829885 0 --強引な番兵
45986603 0 --強奪
55144522 0 --強欲な壺
04031928 0 --心変わり
23557835 0 --次元融合
57953380 0 --生還の宝札
60682203 0 --大寒波
67616300 0 --チキンレース
67169062 0 --貪欲な壺
27770341 0 --超再生能力
69243953 0 --蝶の短剣-エルマ
79571449 0 --天使の施し
11110587 0 --隣の芝刈り
42703248 0 --ハリケーン
18144506 0 --ハーピィの羽根帚
70828912 0 --早すぎた埋葬
34906152 0 --マスドライバー
46448938 0 --魔導書の神判
46411259 0 --突然変異
85602018 0 --遺言状
94220427 0 --RUM-アージェント・カオス・フォース
27174286 0 --異次元からの帰還
93016201 0 --王宮の弾圧
05851097 0 --虚無空間
57585212 0 --自爆スイッチ
03280747 0 --第六感
64697231 0 --ダスト·シュート
35316708 0 --刻の封印
80604091 0 --血の代償
28566710 0 --ラストバトル!
#limit
30012506 1 --A-アサルト・コア
40044918 1 --E·HERO エアーマン
33508719 1 --メタモルポット
24094258 1 --ヘビーメタルフォーゼ・エレクトラム
74586817 1 --PSYフレームロード・Ω
46772449 1 --励輝士 ヴェルズビュート
08949584 1 --ヒーローアライブ
72892473 1 --手札抹殺
52340444 1 --閃刀機-ホーネットビット
48130397 1 --超融合
64034255 1 --A·ジェネクス·バードマン
45222299 1 --イビリチュア·ガストクラーケ
11877465 1 --イビリチュア·マインドオーガス
99177923 1 --インフェルニティ·デーモン
68184115 1 --甲虫装機 ダンセル
69207766 1 --甲虫装機 ホーネット
27552504 1 --永遠の淑女 ベアトリーチェ
68819554 1 --Emダメージ・ジャグラー
65518099 1 --クリフォート・ツール
38572779 1 --幻創のミセラサウルス
39512984 1 --ジェムナイトマスター・ダイヤ
78872731 1 --十二獣モルモラット
78868119 1 --深海のディーヴァ
58984738 1 --真竜拳士ダイナマイトK
04474060 1 --SPYRAL GEAR-ドローン
78080961 1 --SPYRAL-ジーニアス
81275020 1 --SRベイゴマックス
48063985 1 --聖霊獣騎 カンナホーク
65192027 1 --ダーク·アームド·ドラゴン
96570609 1 --天帝アイテール
75732622 1 --トーチ・ゴーレム
16226786 1 --深淵の暗殺者
18239909 1 --爆竜剣士イグニスターP
57143342 1 --彼岸の悪鬼 ガトルホッグ
20758643 1 --彼岸の悪鬼 グラバースニッチ
70583986 1 --氷結界の虎王ドゥローレン
52687916 1 --氷結界の龍 トリシューラ
05043010 1 --ファイアウォール・ドラゴン
33396948 1 --封印されしエクゾディア
07902349 1 --封印されし者の左腕
70903634 1 --封印されし者の右腕
44519536 1 --封印されし者の左足
08124921 1 --封印されし者の右足
26674724 1 --ブリューナクの影霊衣
10802915 1 --魔界発現世行きデスガイド
89463537 1 --ユニコールの影霊衣
88264978 1 --レッドアイズ·ダークネスメタルドラゴン
33782437 1 --一時休戦
66957584 1 --インフェルニティガン
72405967 1 --王家の生け贄
81439173 1 --おろかな埋葬
67723438 1 --緊急テレポート
45305419 1 --継承の印
99330325 1 --妨げられた壊獣の眠り
12580477 1 --サンダー·ボルト
95308449 1 --終焉のカウントダウン
74845897 1 --真炎の爆発
35125879 1 --真竜皇の復活
54631665 1 --SPYRAL RESORT
32807846 1 --増援
54447022 1 --ソウル・チャージ
14087893 1 --月の書
81674782 1 --次元の裂け目
83764718 1 --死者蘇生
91623717 1 --連鎖爆撃
79844764 1 --帝王の烈旋
70368879 1 --成金ゴブリン
22842126 1 --汎神の帝王
53129443 1 --ブラック·ホール
73468603 1 --盆回し
15854426 1 --霞の谷の神風
58577036 1 --名推理
43040603 1 --モンスターゲート
14733538 1 --竜呼相打つ
27970830 1 --六武の門
02295440 1 --ワン·フォー·ワン
09059700 1 --インフェルニティ・バリア
61740673 1 --王宮の勅命
84749824 1 --神の警告
41420027 1 --神の宣告
82732705 1 --スキルドレイン
73599290 1 --ソウルドレイン
17078030 1 --光の護封壁
30241314 1 --マクロコスモス
32723153 1 --マジカル·エクスプロージョン
54974237 1 --闇のデッキ破壊ウイルス
#semi limit
55885348 2 --Kozmo-ダークシミター
24224830 2 --墓穴の指名者
23171610 2 --リミッター解除
73915051 2 --スケープ・ゴート
73628505 2 --テラ・フォーミング
59297550 2 --ゼンマイマジシャン
90953320 2 --TG ハイパー·ライブラリアン
28297833 2 --ネクロフェイス
92746535 2 --竜剣士ラスターP
!2018.5 TCG
#forbidden
76794549 0 --アストログラフ・マジシャン
......
Subproject commit f05e302c4aa9e4eee7789f1e45708708148a3d18
Subproject commit d5d91f86a177244c2ae1b88a4a74a5f59bf82ce5
Subproject commit 4abdd05e56bfb3a3c369f7f8bed8230f7e10e4c2
Subproject commit 9845ffd083503c65aed5b4660b3eb0c49b173fce
......@@ -70,6 +70,13 @@
!system 215 已选择数字:
!system 216 在连锁%d发动
!system 217 被连锁%d的[%ls]选择为对象
!system 218 是否使用[%ls]的效果代替支付基本分?
!system 219 是否使用[%ls]的效果代替取除超量素材?
!system 220 是否使用[%ls]的效果代替取除指示物?
!system 221 是否在[%ls]发动[%ls]的诱发效果?
!system 222 是否要发动诱发效果?
!system 223 稍后将询问其他可以发动的效果。
!system 224 已用正规方法特殊召唤
!system 500 请选择要解放的卡
!system 501 请选择要丢弃的手卡
!system 502 请选择要破坏的卡
......@@ -393,6 +400,7 @@
!system 1372 守备↑
!system 1373 名称↓
!system 1374 连接标记
!system 1378 使用多个关键词搜索卡片
!system 1380 人机模式
!system 1381 残局模式
!system 1382 人机信息:
......@@ -733,7 +741,7 @@
!setname 0x82 怒怒怒 ドドド
!setname 0x83 机关傀儡 ギミック・パペット
!setname 0x84 燃烧拳击手 BK(バーニングナックラー)
!setname 0x85 超级防机器人 SDロボ
!setname 0x85 超级防机器人 SDロボ
!setname 0x86 光天使
!setname 0x87 阴影 アンブラル
!setname 0x88 武神
......@@ -744,7 +752,7 @@
#setname 0x8c 德鲁伊 ドルイド
!setname 0x8d 鬼计 ゴーストリック
!setname 0x8e 吸血鬼 ヴァンパイア
!setname 0x8f啦啦 ズババ
!setname 0x8f拉拉 ズババ
!setname 0x90 森罗 森羅
!setname 0x91 王家长眠之谷 ネクロバレー
!setname 0x92 纹章 メダリオン
......@@ -811,6 +819,7 @@
!setname 0xbf 灵使 霊使い
!setname 0xc0 凭依装着 憑依装着
!setname 0xc1 PSY骨架 PSYフレーム
!setname 0x10c1 PSY骨架装备 PSYフレームギア
!setname 0xc2 动力工具 パワー・ツール
!setname 0xc3 锋利小鬼 エッジインプ
!setname 0xc4 神数 セフィラ
......
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