Commit 5eb692c0 authored by mercury233's avatar mercury233

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

parents a469babe 99c60dfa
## ygopro
## YGOPro
A script engine for "yu-gi-oh!" and sample gui
[中文说明](https://github.com/Fluorohydride/ygopro/wiki/%E4%B8%AD%E6%96%87%E8%AF%B4%E6%98%8E)
......@@ -7,6 +7,7 @@ A script engine for "yu-gi-oh!" and sample gui
* ESC: Minimize the window.
* A: Holding down this button will let the system stop at every timing.
* S: Holding down this button will let the system skip every timing.
* D: Holding down this button will let the system stop at available timing.
* R: Fix the font error.
* F1~F4: Show the cards in your grave, banished zone, extra deck, xyz materials.
* F5~F8: Show the cards in your opponent's grave, banished zone, extra deck, xyz materials.
......@@ -26,7 +27,7 @@ Xyz materials:
* Monster Zone: 1~5, starting from the left hand side.
* Spell & Trap Zone: 1~5, starting from the left hand side.
* Field Zone: 6
* Pendulum Zone: 7~8, starting from the left hand side.
* Pendulum Zone: 0~1, starting from the left hand side.
* The others: 1~n, starting from the bottom.
### Deck edit page:
......@@ -34,11 +35,25 @@ Xyz materials:
* Card name: Search card names and texts by default, $foo will only search foo in card names, and @foo will search cards of "foo" archetype(due to translation, card name contains "foo" does not mean that card is "foo" card).
### Command-line options:
* -j: Join the host in system.conf file.
* -d: Enter the deck edit page.
* -r: Enter the replay mode page.
* -s: Enter the single mode page.
* -efoo: Load foo as the extra database.
* `-e foo.cdb`: Load foo.cdb as the extra database.
* `-n nickname`: Set the nickname.
* `-h 192.168.0.2`: Set the h**ost to join in LAN mode.
* `-p 7911`: Set theport to join in LAN mode.
* `-w abc`: Set the password to join in LAN mode.
* `-d`: Enter the deck edit page.
* `-d deck`: If used along with `-j` it mean select the deck, or it will open the deck to edit.
* `-c`: Create host with default settings.
* `-j`: Join the host specified in above, or if absent, lasthost in system.conf file.
* `-r`: Enter the replay mode page.
* `-r replay.yrp`: Load the replay.yrp in replay mode.
* `-s`: Enter the single mode page.
* `-s puzzle.lua`: Load the puzzle.lua in single mode.
* `-k`: Keep when duel finished. See below.
#### Note:
* `-c` `-j` `-e` `-r` `-s` shoule be the last parameter, because any parameters after it will get ignored.
* `-d` `-c` `-j` `-e` `-r` `-s` will make YGOPro automatically exit when the duel or deck editing finished. This is useful for some launchers. If you want to keep it, add `-k` before them.
* `-d` `-r` `-s` support full path of file, or just filename. But remember deck filename should NOT have extension when replay and single filename MUST have extension.
### Directories:
* pics: .jpg card images(177*254).
......
......@@ -159,18 +159,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
break;
}
case BUTTON_START_FILTER: {
filter_type = mainGame->cbCardType->getSelected();
filter_type2 = mainGame->cbCardType2->getItemData(mainGame->cbCardType2->getSelected());
filter_lm = mainGame->cbLimit->getSelected();
if(filter_type == 1) {
filter_attrib = mainGame->cbAttribute->getItemData(mainGame->cbAttribute->getSelected());
filter_race = mainGame->cbRace->getItemData(mainGame->cbRace->getSelected());
filter_atk = parse_filter(mainGame->ebAttack->getText(), &filter_atktype);
filter_def = parse_filter(mainGame->ebDefense->getText(), &filter_deftype);
filter_lv = parse_filter(mainGame->ebStar->getText(), &filter_lvtype);
filter_scl = parse_filter(mainGame->ebScale->getText(), &filter_scltype);
}
FilterCards();
StartFilter();
if(!mainGame->gameConf.separate_clear_button)
ClearFilter();
break;
......@@ -285,12 +274,17 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
case irr::gui::EGET_EDITBOX_ENTER: {
switch(id) {
case EDITBOX_KEYWORD: {
irr::SEvent me;
me.EventType = irr::EET_GUI_EVENT;
me.GUIEvent.EventType = irr::gui::EGET_BUTTON_CLICKED;
me.GUIEvent.Caller = mainGame->btnStartFilter;
me.GUIEvent.Element = mainGame->btnStartFilter;
mainGame->device->postEventFromUser(me);
StartFilter();
break;
}
}
break;
}
case irr::gui::EGET_EDITBOX_CHANGED: {
switch(id) {
case EDITBOX_KEYWORD: {
if(mainGame->gameConf.auto_search_limit >= 0 && (wcslen(mainGame->ebCardName->getText()) >= mainGame->gameConf.auto_search_limit))
StartFilter();
break;
}
}
......@@ -810,6 +804,20 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
}
return false;
}
void DeckBuilder::StartFilter() {
filter_type = mainGame->cbCardType->getSelected();
filter_type2 = mainGame->cbCardType2->getItemData(mainGame->cbCardType2->getSelected());
filter_lm = mainGame->cbLimit->getSelected();
if(filter_type == 1) {
filter_attrib = mainGame->cbAttribute->getItemData(mainGame->cbAttribute->getSelected());
filter_race = mainGame->cbRace->getItemData(mainGame->cbRace->getSelected());
filter_atk = parse_filter(mainGame->ebAttack->getText(), &filter_atktype);
filter_def = parse_filter(mainGame->ebDefense->getText(), &filter_deftype);
filter_lv = parse_filter(mainGame->ebStar->getText(), &filter_lvtype);
filter_scl = parse_filter(mainGame->ebScale->getText(), &filter_scltype);
}
FilterCards();
}
void DeckBuilder::FilterCards() {
results.clear();
const wchar_t* pstr = mainGame->ebCardName->getText();
......@@ -903,12 +911,12 @@ void DeckBuilder::FilterCards() {
}
if(pstr) {
if(pstr[0] == L'$') {
if(wcsstr(text.name, &pstr[1]) == 0)
if(!CardNameContains(text.name, &pstr[1]))
continue;
} else if(pstr[0] == L'@' && set_code) {
if(!check_set_code(data, set_code)) continue;
} else {
if(wcsstr(text.name, pstr) == 0 && wcsstr(text.text, pstr) == 0
if(!CardNameContains(text.name, pstr) && wcsstr(text.text, pstr) == 0
&& (!set_code || !check_set_code(data, set_code)))
continue;
}
......@@ -938,6 +946,8 @@ void DeckBuilder::ClearSearch() {
mainGame->ebScale->setEnabled(false);
mainGame->ebCardName->setText(L"");
ClearFilter();
results.clear();
myswprintf(result_string, L"%d", 0);
}
void DeckBuilder::ClearFilter() {
mainGame->cbAttribute->setSelected(0);
......@@ -978,5 +988,46 @@ void DeckBuilder::SortList() {
break;
}
}
static inline wchar_t NormalizeChar(wchar_t c) {
/*
// Convert all symbols and punctuations to space.
if (c != 0 && c < 128 && !isalnum(c)) {
return ' ';
}
*/
// Convert latin chararacters to uppercase to ignore case.
if (c < 128 && isalpha(c)) {
return toupper(c);
}
// Remove some accentued characters that are not supported by the editbox.
if (c >= 232 && c <= 235) {
return 'E';
}
if (c >= 238 && c <= 239) {
return 'I';
}
return c;
}
bool DeckBuilder::CardNameContains(const wchar_t *haystack, const wchar_t *needle)
{
if (!needle[0]) {
return true;
}
int i = 0;
int j = 0;
while (haystack[i]) {
wchar_t ca = NormalizeChar(haystack[i]);
wchar_t cb = NormalizeChar(needle[j]);
if (ca == cb) {
j++;
if (!needle[j]) {
return true;
}
} else {
j = 0;
}
i++;
}
return false;
}
}
......@@ -12,10 +12,13 @@ class DeckBuilder: public irr::IEventReceiver {
public:
virtual bool OnEvent(const irr::SEvent& event);
void FilterCards();
void StartFilter();
void ClearFilter();
void ClearSearch();
void SortList();
bool CardNameContains(const wchar_t *haystack, const wchar_t *needle);
long long filter_effect;
unsigned int filter_type;
unsigned int filter_type2;
......
......@@ -923,6 +923,7 @@ void Game::LoadConfig() {
gameConf.control_mode = 0;
gameConf.draw_field_spell = 1;
gameConf.separate_clear_button = 1;
gameConf.auto_search_limit = -1;
fseek(fp, 0, SEEK_END);
int fsize = ftell(fp);
fseek(fp, 0, SEEK_SET);
......@@ -977,6 +978,8 @@ void Game::LoadConfig() {
gameConf.draw_field_spell = atoi(valbuf);
} else if(!strcmp(strbuf, "separate_clear_button")) {
gameConf.separate_clear_button = atoi(valbuf);
} else if(!strcmp(strbuf, "auto_search_limit")) {
gameConf.auto_search_limit = atoi(valbuf);
} else {
// options allowing multiple words
sscanf(linebuf, "%s = %240[^\n]", strbuf, valbuf);
......@@ -1030,6 +1033,8 @@ void Game::SaveConfig() {
fprintf(fp, "control_mode = %d\n", gameConf.control_mode);
fprintf(fp, "draw_field_spell = %d\n", gameConf.draw_field_spell);
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);
fclose(fp);
}
void Game::ShowCardInfo(int code) {
......
......@@ -36,6 +36,7 @@ struct Config {
int control_mode;
int draw_field_spell;
int separate_clear_button;
int auto_search_limit;
};
struct DuelInfo {
......
......@@ -23,3 +23,5 @@ hide_hint_button = 0
control_mode = 0
draw_field_spell = 1
separate_clear_button = 1
#auto_search_limit >= 0: Start search automatically when the user enters N chars.
auto_search_limit = -1
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