Commit 26eb016b authored by nanahira's avatar nanahira

Merge branch 'server' of github.com:mycard/ygopro into server

parents 5d73c060 0d57a9e2
......@@ -7,9 +7,13 @@ namespace ygo {
ClientCard::~ClientCard() {
ClearTarget();
if (equipTarget)
if (equipTarget) {
equipTarget->is_showequip = false;
equipTarget->equipped.erase(this);
for (auto card : equipped) {
equipTarget = nullptr;
}
for (auto& card : equipped) {
card->is_showequip = false;
card->equipTarget = nullptr;
}
equipped.clear();
......@@ -21,8 +25,9 @@ ClientCard::~ClientCard() {
else
++it;
}
overlayTarget = nullptr;
}
for (auto card : overlayed) {
for (auto& card : overlayed) {
card->overlayTarget = nullptr;
}
overlayed.clear();
......@@ -206,10 +211,6 @@ void ClientCard::ClearData() {
rscstring[0] = 0;
lscstring[0] = 0;
counters.clear();
for (auto card : equipped) {
card->equipTarget = nullptr;
}
equipped.clear();
}
bool ClientCard::client_card_sort(ClientCard* c1, ClientCard* c2) {
if(c1->is_selected != c2->is_selected)
......@@ -220,23 +221,26 @@ bool ClientCard::client_card_sort(ClientCard* c1, ClientCard* c2) {
return cp1 < cp2;
if(c1->location != c2->location)
return c1->location < c2->location;
if(c1->location & LOCATION_OVERLAY)
if(c1->overlayTarget != c2->overlayTarget)
if (c1->location & LOCATION_OVERLAY) {
if (c1->overlayTarget != c2->overlayTarget)
return c1->overlayTarget->sequence < c2->overlayTarget->sequence;
else return c1->sequence < c2->sequence;
else
return c1->sequence < c2->sequence;
}
else {
if(c1->location & (LOCATION_DECK | LOCATION_GRAVE | LOCATION_REMOVED | LOCATION_EXTRA)) {
auto it1 = std::find_if(mainGame->dField.chains.rbegin(), mainGame->dField.chains.rend(), [c1](const auto& ch) {
auto it1 = std::find_if(mainGame->dField.chains.rbegin(), mainGame->dField.chains.rend(), [c1](const ChainInfo& ch) {
return c1 == ch.chain_card || ch.target.find(c1) != ch.target.end();
});
auto it2 = std::find_if(mainGame->dField.chains.rbegin(), mainGame->dField.chains.rend(), [c2](const auto& ch) {
auto it2 = std::find_if(mainGame->dField.chains.rbegin(), mainGame->dField.chains.rend(), [c2](const ChainInfo& ch) {
return c2 == ch.chain_card || ch.target.find(c2) != ch.target.end();
});
if(it1 != mainGame->dField.chains.rend() || it2 != mainGame->dField.chains.rend()) {
return it1 < it2;
}
return c1->sequence > c2->sequence;
} else
}
else
return c1->sequence < c2->sequence;
}
}
......
......@@ -33,6 +33,7 @@ struct CardString {
std::wstring desc[16];
};
typedef std::unordered_map<unsigned int, CardDataC>::const_iterator code_pointer;
typedef std::unordered_map<unsigned int, CardString>::const_iterator string_pointer;
class ClientCard {
public:
......@@ -93,12 +94,12 @@ public:
std::set<ClientCard*> ownerTarget;
std::map<int, int> counters;
std::map<int, int> desc_hints;
wchar_t atkstring[16]{ 0 };
wchar_t defstring[16]{ 0 };
wchar_t lvstring[16]{ 0 };
wchar_t linkstring[16]{ 0 };
wchar_t lscstring[16]{ 0 };
wchar_t rscstring[16]{ 0 };
wchar_t atkstring[16]{};
wchar_t defstring[16]{};
wchar_t lvstring[16]{};
wchar_t linkstring[16]{};
wchar_t lscstring[16]{};
wchar_t rscstring[16]{};
ClientCard() = default;
~ClientCard();
......
......@@ -19,39 +19,39 @@ ClientField::ClientField() {
}
ClientField::~ClientField() {
for (int i = 0; i < 2; ++i) {
for (auto card : deck[i]) {
for (auto& card : deck[i]) {
delete card;
}
deck[i].clear();
for (auto card : hand[i]) {
for (auto& card : hand[i]) {
delete card;
}
hand[i].clear();
for (auto card : mzone[i]) {
for (auto& card : mzone[i]) {
if (card)
delete card;
card = nullptr;
}
for (auto card : szone[i]) {
for (auto& card : szone[i]) {
if (card)
delete card;
card = nullptr;
}
for (auto card : grave[i]) {
for (auto& card : grave[i]) {
delete card;
}
grave[i].clear();
for (auto card : remove[i]) {
for (auto& card : remove[i]) {
delete card;
}
remove[i].clear();
for (auto card : extra[i]) {
for (auto& card : extra[i]) {
delete card;
}
extra[i].clear();
}
for (auto card : overlay_cards) {
for (auto& card : overlay_cards) {
delete card;
}
overlay_cards.clear();
......@@ -1555,9 +1555,11 @@ void ClientField::UpdateDeclarableList() {
}
mainGame->lstANCard->clear();
ancard.clear();
for(auto cit = dataManager._strings.begin(); cit != dataManager._strings.end(); ++cit) {
for(auto cit = dataManager.strings_begin; cit != dataManager.strings_end; ++cit) {
if(cit->second.name.find(pname) != std::wstring::npos) {
auto cp = dataManager.GetCodePointer(cit->first); //verified by _strings
auto cp = dataManager.GetCodePointer(cit->first);
if (cp == dataManager.datas_end)
continue;
//datas.alias can be double card names or alias
if(is_declarable(cp->second, declare_opcodes)) {
if(pname == cit->second.name || trycode == cit->first) { //exact match or last used
......
......@@ -46,7 +46,7 @@ public:
std::vector<int> select_options;
std::vector<int> select_options_index;
std::vector<ChainInfo> chains;
int extra_p_count[2]{ 0 };
int extra_p_count[2]{};
size_t selected_option{ 0 };
ClientCard* attacker{ nullptr };
......@@ -77,7 +77,7 @@ public:
bool remove_act{ false };
bool deck_act{ false };
bool extra_act{ false };
bool pzone_act[2]{ false };
bool pzone_act[2]{};
bool conti_act{ false };
bool chain_forced{ false };
ChainInfo current_chain;
......
......@@ -111,6 +111,10 @@ bool DataManager::LoadDB(const wchar_t* wfile) {
spmemvfs_close_db(&db);
spmemvfs_env_fini();
#endif
datas_begin = _datas.begin();
datas_end = _datas.end();
strings_begin = _strings.begin();
strings_end = _strings.end();
return true;
}
bool DataManager::LoadStrings(const char* file) {
......@@ -189,10 +193,10 @@ bool DataManager::Error(spmemvfs_db_t* pDB, sqlite3_stmt* pStmt) {
}
#endif //YGOPRO_SERVER_MODE
bool DataManager::GetData(unsigned int code, CardData* pData) {
auto cdit = _datas.find(code);
code_pointer cdit = _datas.find(code);
if(cdit == _datas.end())
return false;
auto data = cdit->second;
auto& data = cdit->second;
if (pData) {
pData->code = data.code;
pData->alias = data.alias;
......@@ -209,9 +213,12 @@ bool DataManager::GetData(unsigned int code, CardData* pData) {
}
return true;
}
code_pointer DataManager::GetCodePointer(int code) {
code_pointer DataManager::GetCodePointer(unsigned int code) const {
return _datas.find(code);
}
string_pointer DataManager::GetStringPointer(unsigned int code) const {
return _strings.find(code);
}
bool DataManager::GetString(int code, CardString* pStr) {
auto csit = _strings.find(code);
if(csit == _strings.end()) {
......
......@@ -13,7 +13,12 @@ namespace ygo {
class DataManager {
public:
DataManager(): _datas(16384), _strings(16384) {}
DataManager(): _datas(16384), _strings(16384) {
datas_begin = _datas.begin();
datas_end = _datas.end();
strings_begin = _strings.begin();
strings_end = _strings.end();
}
bool LoadDB(const wchar_t* wfile);
bool LoadStrings(const char* file);
#ifndef YGOPRO_SERVER_MODE
......@@ -26,7 +31,8 @@ public:
bool Error(sqlite3* pDB, sqlite3_stmt* pStmt = 0);
#endif //YGOPRO_SERVER_MODE
bool GetData(unsigned int code, CardData* pData);
code_pointer GetCodePointer(int code);
code_pointer GetCodePointer(unsigned int code) const;
string_pointer GetStringPointer(unsigned int code) const;
bool GetString(int code, CardString* pStr);
const wchar_t* GetName(int code);
const wchar_t* GetText(int code);
......@@ -44,12 +50,14 @@ public:
const wchar_t* FormatSetName(unsigned long long setcode);
const wchar_t* FormatLinkMarker(int link_marker);
std::unordered_map<unsigned int, CardDataC> _datas;
std::unordered_map<unsigned int, CardString> _strings;
std::unordered_map<unsigned int, std::wstring> _counterStrings;
std::unordered_map<unsigned int, std::wstring> _victoryStrings;
std::unordered_map<unsigned int, std::wstring> _setnameStrings;
std::unordered_map<unsigned int, std::wstring> _sysStrings;
code_pointer datas_begin;
code_pointer datas_end;
string_pointer strings_begin;
string_pointer strings_end;
wchar_t numStrings[301][4];
wchar_t numBuffer[6];
......@@ -67,6 +75,10 @@ public:
#if !defined(YGOPRO_SERVER_MODE) || defined(SERVER_ZIP_SUPPORT)
static IFileSystem* FileSystem;
#endif
private:
std::unordered_map<unsigned int, CardDataC> _datas;
std::unordered_map<unsigned int, CardString> _strings;
};
extern DataManager dataManager;
......
......@@ -43,8 +43,8 @@ static int parse_filter(const wchar_t* pstr, unsigned int* type) {
static bool check_set_code(const CardDataC& data, int set_code) {
unsigned long long sc = data.setcode;
if (data.alias) {
auto aptr = dataManager._datas.find(data.alias);
if (aptr != dataManager._datas.end())
auto aptr = dataManager.GetCodePointer(data.alias);
if (aptr != dataManager.datas_end)
sc = aptr->second.setcode;
}
bool res = false;
......@@ -1030,7 +1030,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
dragx = event.MouseInput.X;
dragy = event.MouseInput.Y;
draging_pointer = dataManager.GetCodePointer(hovered_code);
if(draging_pointer == dataManager._datas.end())
if(draging_pointer == dataManager.datas_end)
break;
if(hovered_pos == 4) {
if(!check_limit(draging_pointer))
......@@ -1084,7 +1084,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
if(hovered_pos == 0 || hovered_seq == -1)
break;
auto pointer = dataManager.GetCodePointer(hovered_code);
if(pointer == dataManager._datas.end())
if(pointer == dataManager.datas_end)
break;
soundManager.PlaySoundEffect(SOUND_CARD_DROP);
if(hovered_pos == 1) {
......@@ -1119,7 +1119,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
pop_side(hovered_seq);
} else {
auto pointer = dataManager.GetCodePointer(hovered_code);
if(pointer == dataManager._datas.end())
if(pointer == dataManager.datas_end)
break;
if(!check_limit(pointer))
break;
......@@ -1154,6 +1154,8 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
if (is_draging)
break;
auto pointer = dataManager.GetCodePointer(hovered_code);
if (pointer == dataManager.datas_end)
break;
if(!check_limit(pointer))
break;
soundManager.PlaySoundEffect(SOUND_CARD_PICK);
......@@ -1421,9 +1423,11 @@ void DeckBuilder::FilterCards() {
query_elements.push_back(element);
}
}
auto strpointer = dataManager._strings.begin();
for(code_pointer ptr = dataManager._datas.begin(); ptr != dataManager._datas.end(); ++ptr, ++strpointer) {
for(code_pointer ptr = dataManager.datas_begin; ptr != dataManager.datas_end; ++ptr) {
const CardDataC& data = ptr->second;
auto strpointer = dataManager.GetStringPointer(ptr->first);
if (strpointer == dataManager.strings_end)
continue;
const CardString& text = strpointer->second;
if(data.type & TYPE_TOKEN)
continue;
......
......@@ -166,7 +166,7 @@ int DeckManager::LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec, bool is_p
else if(cd.type & (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_LINK)) {
if(deck.extra.size() >= 15)
continue;
deck.extra.push_back(dataManager.GetCodePointer(code)); //verified by GetData()
deck.extra.push_back(dataManager.GetCodePointer(code));
} else if(deck.main.size() < 60) {
deck.main.push_back(dataManager.GetCodePointer(code));
}
......@@ -180,7 +180,7 @@ int DeckManager::LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec, bool is_p
if(cd.type & TYPE_TOKEN)
continue;
if(deck.side.size() < 15)
deck.side.push_back(dataManager.GetCodePointer(code)); //verified by GetData()
deck.side.push_back(dataManager.GetCodePointer(code));
}
return errorcode;
}
......
......@@ -2176,6 +2176,7 @@ void ClientField::GetHoverField(int x, int y) {
hovered_location = LOCATION_REMOVED;
}
} else if(rule == 1 && boardx >= matManager.vFieldSzone[1][7][rule][1].Pos.X && boardx <= matManager.vFieldSzone[1][7][rule][2].Pos.X) {
// deprecated szone[7]
if(boardy >= matManager.vFieldSzone[1][7][rule][2].Pos.Y && boardy <= matManager.vFieldSzone[1][7][rule][0].Pos.Y) {
hovered_controler = 1;
hovered_location = LOCATION_SZONE;
......@@ -2207,7 +2208,8 @@ void ClientField::GetHoverField(int x, int y) {
hovered_controler = 1;
hovered_location = LOCATION_EXTRA;
}
} else if(rule == 0 && boardx >= matManager.vFieldSzone[0][7][rule][0].Pos.X && boardx <= matManager.vFieldSzone[0][7][rule][1].Pos.X) {
} else if(rule == 1 && boardx >= matManager.vFieldSzone[0][7][rule][0].Pos.X && boardx <= matManager.vFieldSzone[0][7][rule][1].Pos.X) {
// deprecated szone[7]
if(boardy >= matManager.vFieldSzone[0][7][rule][0].Pos.Y && boardy <= matManager.vFieldSzone[0][7][rule][2].Pos.Y) {
hovered_controler = 0;
hovered_location = LOCATION_SZONE;
......
......@@ -125,9 +125,6 @@ bool Game::Initialize() {
is_building = false;
menuHandler.prev_operation = 0;
menuHandler.prev_sel = -1;
for (auto i : chatTiming) {
i = 0;
}
deckManager.LoadLFList();
driver = device->getVideoDriver();
driver->setTextureCreationFlag(irr::video::ETCF_CREATE_MIP_MAPS, false);
......@@ -1291,7 +1288,7 @@ void Game::RefreshDeck(irr::gui::IGUIComboBox* cbCategory, irr::gui::IGUIComboBo
}
void Game::RefreshDeck(const wchar_t* deckpath, const std::function<void(const wchar_t*)>& additem) {
if(!mywcsncasecmp(deckpath, L"./pack", 6)) {
for(auto pack : deckBuilder.expansionPacks) {
for(auto& pack : deckBuilder.expansionPacks) {
additem(pack.substr(5, pack.size() - 9).c_str());
}
}
......@@ -1378,57 +1375,6 @@ void Game::LoadConfig() {
char strbuf[32];
char valbuf[256];
wchar_t wstr[256];
gameConf.use_d3d = 0;
gameConf.use_image_scale = 1;
gameConf.antialias = 0;
gameConf.serverport = 7911;
gameConf.textfontsize = 14;
gameConf.nickname[0] = 0;
gameConf.gamename[0] = 0;
gameConf.lastcategory[0] = 0;
gameConf.lastdeck[0] = 0;
gameConf.numfont[0] = 0;
gameConf.textfont[0] = 0;
gameConf.lasthost[0] = 0;
gameConf.lastport[0] = 0;
gameConf.roompass[0] = 0;
gameConf.bot_deck_path[0] = 0;
//settings
gameConf.chkMAutoPos = 0;
gameConf.chkSTAutoPos = 1;
gameConf.chkRandomPos = 0;
gameConf.chkAutoChain = 0;
gameConf.chkWaitChain = 0;
gameConf.chkDefaultShowChain = 0;
gameConf.chkIgnore1 = 0;
gameConf.chkIgnore2 = 0;
gameConf.use_lflist = 1;
gameConf.default_lflist = 0;
gameConf.default_rule = DEFAULT_DUEL_RULE;
gameConf.hide_setname = 0;
gameConf.hide_hint_button = 0;
gameConf.control_mode = 0;
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;
gameConf.quick_animation = 0;
gameConf.auto_save_replay = 0;
gameConf.draw_single_chain = 0;
gameConf.hide_player_name = 0;
gameConf.prefer_expansion_script = 0;
gameConf.enable_sound = true;
gameConf.sound_volume = 0.5;
gameConf.enable_music = true;
gameConf.music_volume = 0.5;
gameConf.music_mode = 1;
gameConf.window_maximized = false;
gameConf.window_width = 1024;
gameConf.window_height = 640;
gameConf.resize_popup_menu = false;
while(fgets(linebuf, 256, fp)) {
sscanf(linebuf, "%s = %s", strbuf, valbuf);
if(!strcmp(strbuf, "antialias")) {
......@@ -1647,8 +1593,8 @@ void Game::ShowCardInfo(int code, bool resize) {
if(!gameConf.hide_setname) {
unsigned long long sc = cd.setcode;
if(cd.alias) {
auto aptr = dataManager._datas.find(cd.alias);
if(aptr != dataManager._datas.end())
auto aptr = dataManager.GetCodePointer(cd.alias);
if(aptr != dataManager.datas_end)
sc = aptr->second.setcode;
}
if(sc) {
......
......@@ -13,61 +13,63 @@
#include <vector>
#include <list>
#define DEFAULT_DUEL_RULE 5
namespace ygo {
#ifndef YGOPRO_SERVER_MODE
struct Config {
bool use_d3d;
bool use_image_scale;
unsigned short antialias;
unsigned short serverport;
unsigned char textfontsize;
wchar_t lasthost[100];
wchar_t lastport[10];
wchar_t nickname[20];
wchar_t gamename[20];
wchar_t lastcategory[64];
wchar_t lastdeck[64];
wchar_t textfont[256];
wchar_t numfont[256];
wchar_t roompass[20];
wchar_t bot_deck_path[64];
bool use_d3d{ false };
bool use_image_scale{ true };
unsigned short antialias{ 0 };
unsigned short serverport{ 7911 };
unsigned char textfontsize{ 14 };
wchar_t lasthost[100]{};
wchar_t lastport[10]{};
wchar_t nickname[20]{};
wchar_t gamename[20]{};
wchar_t lastcategory[64]{};
wchar_t lastdeck[64]{};
wchar_t textfont[256]{};
wchar_t numfont[256]{};
wchar_t roompass[20]{};
wchar_t bot_deck_path[64]{};
//settings
int chkMAutoPos;
int chkSTAutoPos;
int chkRandomPos;
int chkAutoChain;
int chkWaitChain;
int chkDefaultShowChain;
int chkIgnore1;
int chkIgnore2;
int use_lflist;
int default_lflist;
int default_rule;
int hide_setname;
int hide_hint_button;
int control_mode;
int draw_field_spell;
int separate_clear_button;
int auto_search_limit;
int search_multiple_keywords;
int chkIgnoreDeckChanges;
int defaultOT;
int enable_bot_mode;
int quick_animation;
int auto_save_replay;
int draw_single_chain;
int hide_player_name;
int prefer_expansion_script;
bool enable_sound;
bool enable_music;
double sound_volume;
double music_volume;
int music_mode;
bool window_maximized;
int window_width;
int window_height;
bool resize_popup_menu;
int chkMAutoPos{ 0 };
int chkSTAutoPos{ 1 };
int chkRandomPos{ 0 };
int chkAutoChain{ 0 };
int chkWaitChain{ 0 };
int chkDefaultShowChain{ 0 };
int chkIgnore1{ 0 };
int chkIgnore2{ 0 };
int use_lflist{ 1 };
int default_lflist{ 0 };
int default_rule{ DEFAULT_DUEL_RULE };
int hide_setname{ 0 };
int hide_hint_button{ 0 };
int control_mode{ 0 };
int draw_field_spell{ 1 };
int separate_clear_button{ 1 };
int auto_search_limit{ -1 };
int search_multiple_keywords{ 1 };
int chkIgnoreDeckChanges{ 0 };
int defaultOT{ 1 };
int enable_bot_mode{ 0 };
int quick_animation{ 0 };
int auto_save_replay{ 0 };
int draw_single_chain{ 0 };
int hide_player_name{ 0 };
int prefer_expansion_script{ 0 };
bool enable_sound{ true };
bool enable_music{ true };
double sound_volume{ 0.5 };
double music_volume{ 0.5 };
int music_mode{ 1 };
bool window_maximized{ false };
int window_width{ 1024 };
int window_height{ 640 };
bool resize_popup_menu{ false };
};
struct DuelInfo {
......@@ -79,35 +81,35 @@ struct DuelInfo {
bool isTag{ false };
bool isSingleMode{ false };
bool is_shuffling{ false };
bool tag_player[2]{ false };
bool tag_player[2]{};
bool isReplaySwapped{ false };
int lp[2]{ 0 };
int lp[2]{};
int start_lp{ 0 };
int duel_rule{ 0 };
int turn{ 0 };
short curMsg{ 0 };
wchar_t hostname[20]{ 0 };
wchar_t clientname[20]{ 0 };
wchar_t hostname_tag[20]{ 0 };
wchar_t clientname_tag[20]{ 0 };
wchar_t strLP[2][16]{ 0 };
wchar_t* vic_string{ 0 };
wchar_t hostname[20]{};
wchar_t clientname[20]{};
wchar_t hostname_tag[20]{};
wchar_t clientname_tag[20]{};
wchar_t strLP[2][16]{};
wchar_t* vic_string{ nullptr };
unsigned char player_type{ 0 };
unsigned char time_player{ 0 };
unsigned short time_limit{ 0 };
unsigned short time_left[2]{ 0 };
unsigned short time_left[2]{};
void Clear();
};
struct BotInfo {
wchar_t name[256];
wchar_t command[256];
wchar_t desc[256];
bool support_master_rule_3;
bool support_new_master_rule;
bool support_master_rule_2020;
bool select_deckfile;
wchar_t name[256]{};
wchar_t command[256]{};
wchar_t desc[256]{};
bool support_master_rule_3{ false };
bool support_new_master_rule{ false };
bool support_master_rule_2020{ false };
bool select_deckfile{ false };
};
struct FadingUnit {
......@@ -226,8 +228,8 @@ public:
int hideChatTimer;
bool hideChat;
int chatTiming[8];
int chatType[8];
int chatTiming[8]{};
int chatType[8]{};
unsigned short linePatternD3D;
unsigned short linePatternGL;
int waitFrame;
......@@ -846,8 +848,6 @@ extern unsigned int pre_seed[3];
#define AVAIL_SC 0x8
#define AVAIL_OCGTCG (AVAIL_OCG|AVAIL_TCG)
#define DEFAULT_DUEL_RULE 5
#define CARD_ARTWORK_VERSIONS_OFFSET 10
#define MAX_LAYER_COUNT 6
#endif // GAME_H
......@@ -21,11 +21,11 @@ public:
S3DVertex vFieldSpell2[4];
//S3DVertex vBackLine[76];
S3DVertex vFieldDeck[2][4];
S3DVertex vFieldGrave[2][2][4];
S3DVertex vFieldGrave[2][2][4]; //[player][rule], rule = 0: dule_rule <= 3, 1: dule_rule >= 4
S3DVertex vFieldExtra[2][4];
S3DVertex vFieldRemove[2][2][4];
S3DVertex vFieldMzone[2][7][4];
S3DVertex vFieldSzone[2][8][2][4];
S3DVertex vFieldRemove[2][2][4]; //[player][rule]
S3DVertex vFieldMzone[2][7][4]; //[player][sequence]
S3DVertex vFieldSzone[2][8][2][4]; //[player][sequence][rule]
irr::core::vector3df vFieldContiAct[4];
S3DVertex vArrow[40];
SColor c2d[4];
......
......@@ -314,11 +314,17 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
for(int i = 0; i < max; ++i) {
int main = replay.ReadInt32();
Deck tmp_deck;
for(int j = 0; j < main; ++j)
tmp_deck.main.push_back(dataManager.GetCodePointer(replay.ReadInt32()));
for (int j = 0; j < main; ++j) {
auto card = dataManager.GetCodePointer(replay.ReadInt32());
if (card != dataManager.datas_end)
tmp_deck.main.push_back(card);
}
int extra = replay.ReadInt32();
for(int j = 0; j < extra; ++j)
tmp_deck.extra.push_back(dataManager.GetCodePointer(replay.ReadInt32()));
for (int j = 0; j < extra; ++j) {
auto card = dataManager.GetCodePointer(replay.ReadInt32());
if (card != dataManager.datas_end)
tmp_deck.extra.push_back(card);
}
FileSystem::SafeFileName(namebuf[i]);
myswprintf(filename, L"deck/%ls-%d %ls.ydk", ex_filename, i + 1, namebuf[i]);
deckManager.SaveDeck(tmp_deck, filename);
......
......@@ -99,9 +99,8 @@ struct STOC_HS_WatchChange {
class DuelMode;
struct DuelPlayer {
unsigned short name[20]{ 0 };
unsigned short name[20]{};
DuelMode* game{ nullptr };
unsigned char player_id{ 0xff };
unsigned char type{ 0 };
unsigned char state{ 0 };
bufferevent* bev{ 0 };
......
......@@ -293,7 +293,7 @@ void ReplayMode::Restart(bool refresh) {
std::swap(mainGame->dInfo.hostname, mainGame->dInfo.clientname);
std::swap(mainGame->dInfo.hostname_tag, mainGame->dInfo.clientname_tag);
}
skip_turn = 0;
skip_turn = 0;
}
void ReplayMode::Undo() {
if(skip_step > 0 || current_step == 0)
......
......@@ -461,8 +461,6 @@ void SingleDuel::StartDuel(DuelPlayer* dp) {
hand_result[1] = 0;
players[0]->state = CTOS_HAND_RESULT;
players[1]->state = CTOS_HAND_RESULT;
players[0]->player_id = 0;
players[1]->player_id = 1;
duel_stage = DUEL_STAGE_FINGER;
}
void SingleDuel::HandResult(DuelPlayer* dp, unsigned char res) {
......@@ -513,6 +511,8 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
return;
duel_stage = DUEL_STAGE_DUELING;
bool swapped = false;
pplayer[0] = players[0];
pplayer[1] = players[1];
if((tp && dp->type == 1) || (!tp && dp->type == 0)) {
DuelPlayer* p = players[0];
players[0] = players[1];
......@@ -686,6 +686,15 @@ void SingleDuel::DuelEndProc() {
duel_stage = DUEL_STAGE_END;
#endif
} else {
if(players[0] != pplayer[0]) {
players[0] = pplayer[0];
players[1] = pplayer[1];
players[0]->type = 0;
players[1]->type = 1;
Deck d = pdeck[0];
pdeck[0] = pdeck[1];
pdeck[1] = d;
}
ready[0] = false;
ready[1] = false;
players[0]->state = CTOS_UPDATE_DECK;
......@@ -705,7 +714,7 @@ void SingleDuel::DuelEndProc() {
}
}
void SingleDuel::Surrender(DuelPlayer* dp) {
if (dp->type > 1 || dp->player_id > 1 || !pduel)
if(dp->type > 1 || !pduel)
return;
unsigned char wbuf[3];
uint32 player = dp->type;
......@@ -719,9 +728,13 @@ void SingleDuel::Surrender(DuelPlayer* dp) {
#ifdef YGOPRO_SERVER_MODE
NetServer::ReSendToPlayers(cache_recorder, replay_recorder);
#endif
match_result[duel_count] = 1 - dp->player_id;
++duel_count;
tp_player = player;
if(players[player] == pplayer[player]) {
match_result[duel_count++] = 1 - player;
tp_player = player;
} else {
match_result[duel_count++] = player;
tp_player = 1 - player;
}
EndDuel();
DuelEndProc();
event_del(etimer);
......@@ -792,14 +805,15 @@ int SingleDuel::Analyze(unsigned char* msgbuffer, unsigned int len) {
NetServer::ReSendToPlayers(cache_recorder, replay_recorder);
#endif
if(player > 1) {
match_result[duel_count] = 2;
match_result[duel_count++] = 2;
tp_player = 1 - tp_player;
}
else {
match_result[duel_count] = players[player]->player_id;
} else if(players[player] == pplayer[player]) {
match_result[duel_count++] = player;
tp_player = 1 - player;
} else {
match_result[duel_count++] = 1 - player;
tp_player = player;
}
++duel_count;
EndDuel();
return 2;
}
......@@ -2183,9 +2197,13 @@ void SingleDuel::SingleTimer(evutil_socket_t fd, short events, void* arg) {
#ifdef YGOPRO_SERVER_MODE
NetServer::ReSendToPlayers(sd->cache_recorder, sd->replay_recorder);
#endif
sd->match_result[sd->duel_count] = sd->players[1 - player]->player_id;
++sd->duel_count;
sd->tp_player = player;
if(sd->players[player] == sd->pplayer[player]) {
sd->match_result[sd->duel_count++] = 1 - player;
sd->tp_player = player;
} else {
sd->match_result[sd->duel_count++] = player;
sd->tp_player = 1 - player;
}
sd->EndDuel();
sd->DuelEndProc();
event_del(sd->etimer);
......
......@@ -57,11 +57,12 @@ private:
int WriteUpdateData(int& player, int location, int& flag, unsigned char*& qbuf, int& use_cache);
protected:
DuelPlayer* players[2]{ nullptr };
bool ready[2]{ false };
DuelPlayer* players[2]{};
DuelPlayer* pplayer[2]{};
bool ready[2]{};
Deck pdeck[2];
int deck_error[2]{ 0 };
unsigned char hand_result[2]{ 0 };
int deck_error[2]{};
unsigned char hand_result[2]{};
unsigned char last_response{ 0 };
std::set<DuelPlayer*> observers;
#ifdef YGOPRO_SERVER_MODE
......@@ -75,8 +76,8 @@ protected:
int match_kill{ 0 };
unsigned char duel_count{ 0 };
unsigned char tp_player{ 0 };
unsigned char match_result[3]{ 0 };
short time_limit[2]{ 0 };
unsigned char match_result[3]{};
short time_limit[2]{};
short time_elapsed{ 0 };
#ifdef YGOPRO_SERVER_MODE
short time_compensator[2];
......
#[2024.1][2024.1 TCG][2023.10][2023.7][2023.4][2023.1][2022.10][2022.7][2022.4][2022.1][2021.10][2021.7][2021.4][2021.1][2020.10][2020.7][2020.4][2020.1][2019.10][2019.7][2019.4][2019.1][2018.10][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][2023.9 TCG][2023.6 TCG][2023.2 TCG][2022.12 TCG][2022.10 TCG][2022.5 TCG][2022.2 TCG][2021.10 TCG][2021.7 TCG][2021.3 TCG][2020.12 TCG][2020.9 TCG][2020.6 TCG][2020.4 TCG][2020.1 TCG][2019.10 TCG][2019.7 TCG][2019.4 TCG][2019.1 TCG][2018.12 TCG][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]
!2024.1
#forbidden
91869203 0 --アマゾネスの射手
......@@ -139,11 +138,11 @@
33508719 1 --メタモルポット
89399912 1 --嵐征竜-テンペスト
92746535 1 --竜剣士ラスターP
19613556 1 --大嵐
77103950 1 --壱世壊=ペルレイノ
33782437 1 --一時休戦
61292243 1 --EMERGENCY!
01845204 1 --簡易融合
61292243 1 --EMERGENCY
19613556 1 --大嵐
81439173 1 --おろかな埋葬
84211599 1 --金満で謙虚な壺
23701465 1 --原初の種
......@@ -168,8 +167,8 @@
92107604 1 --神碑の泉
27970830 1 --六武の門
02295440 1 --ワン・フォー・ワン
82732705 1 --スキルドレイン
90846359 1 --群雄割拠
82732705 1 --スキルドレイン
35316708 1 --刻の封印
21076084 1 --トリックスター・リンカーネイション
23002292 1 --レッド・リブート
......@@ -184,16 +183,16 @@
35726888 2 --おろかな副葬
67723438 2 --緊急テレポート
35261759 2 --強欲で貪欲な壺
12580477 2 --サンダー・ボルト
04031928 2 --心変わり
12580477 2 --サンダー・ボルト
48130397 2 --超融合
11110587 2 --隣の芝刈り
24207889 2 --センサー万別
24224830 2 --墓穴の指名者
55584558 2 --ピュアリィ・デリシャスメモリー
56700100 2 --ピュアリィ・マイフレンド
92714517 2 --ビッグウェルカム・ラビュリンス
24224830 2 --墓穴の指名者
14532163 2 --ライトニング・ストーム
24207889 2 --センサー万別
92714517 2 --ビッグウェルカム・ラビュリンス
!2024.1 TCG
#forbidden
......@@ -213,10 +212,12 @@
93369354 0 --Fishborg Blaster
67441435 0 --Glow-Up Bulb
75732622 0 --Grinder Golem
25926710 0 --Kelbek the Ancient Vanguard
57421866 0 --Level Eater
34206604 0 --Magical Scientist
31178212 0 --Majespecter Unicorn - Kirin
21377582 0 --Master Peace, the True Dracoslaying King
36521307 0 --Mathmech Circular
23434538 0 --Maxx "C"
96782886 0 --Mind Master
07563579 0 --Performage Plushfire
......@@ -235,11 +236,10 @@
59537380 0 --Guardragon Agarpain
86148577 0 --Guardragon Elpy
24094258 0 --Heavymetalfoes Electrumite
25926710 0 --Kelbek the Ancient Vanguard
59934749 0 --Isolde, Two Tales of the Noble Knights
39064822 0 --Knightmare Goblin
03679218 0 --Knightmare Mermaid
85243784 0 --Linkross
36521307 0 --Mathmech Circular
44097050 0 --Mecha Phantom Beast Auroradon
25725326 0 --Prank-Kids Meow-Meow-Mu
70369116 0 --Predaplant Verte Anaconda
......@@ -251,7 +251,6 @@
83152482 0 --Union Carrier
03040496 0 --Chaos Ruler, the Chaotic Magical Dragon
63101919 0 --Tempest Magician
59934749 0 --Isolde, Two Tales of the Noble Knights
48626373 0 --Kashtira Arise-Heart
34086406 0 --Lavalval Chain
04423206 0 --M-X-Saber Invoker
......@@ -340,12 +339,12 @@
78872731 1 --Zoodiac Ratpier
39512984 1 --Gem-Knight Master Diamond
73539069 1 --Striker Dragon
93896655 1 --Sunavalon Dryas
65563871 1 --Sunvine Healer
25862681 1 --Ancient Fairy Dragon
65536818 1 --Denglong, First of the Yang Zing
94677445 1 --Ib the World Chalice Justiciar
74586817 1 --PSY-Framelord Omega
39880350 1 --Sunavalon Dryas
65563871 1 --Sunvine Healer
90953320 1 --T.G. Hyper Librarian
27552504 1 --Beatrice, Lady of the Eternal
00581014 1 --Daigusto Emeral
......@@ -361,7 +360,6 @@
81439173 1 --Foolish Burial
27970830 1 --Gateway of the Six
75500286 1 --Gold Sarcophagus
53334471 1 --Gozen Match
18144506 1 --Harpie's Feather Duster
66957584 1 --Infernity Launcher
01845204 1 --Instant Fusion
......@@ -374,22 +372,23 @@
55584558 1 --Purrely Delicious Memory
58577036 1 --Reasoning
32807846 1 --Reinforcement of the Army
90846359 1 --Rivalry of Warlords
24940422 1 --Sekka's Light
73468603 1 --Set Rotation
52340444 1 --Sky Striker Mecha - Hornet Drones
71344451 1 --Slash Draw
45986603 1 --Snatch Steal
73628505 1 --Terraforming
24207889 1 --There Can Be Only One
53334471 1 --Gozen Match
32723153 1 --Magical Explosion
03734202 1 --Naturia Sacred Tree
90846359 1 --Rivalry of Warlords
24207889 1 --There Can Be Only One
35316708 1 --Time Seal
#semi limit
09411399 2 --Destiny HERO - Malicious
82385847 2 --Dinowrestler Pankratops
14532163 2 --Lightning Storm
81275020 2 --Speedroid Terrortop
14532163 2 --Lightning Storm
21347668 2 --Purrely Sleepy Memory
92107604 2 --Runick Fountain
63166095 2 --Sky Striker Mobilize - Engage!
......
......@@ -318,8 +318,8 @@
!system 1260 大师规则
!system 1261 大师规则2
!system 1262 大师规则3
!system 1263 新大师规则
!system 1264 大师规则2020
!system 1263 新大师规则2017
!system 1264 大师规则2020
!system 1270 卡片信息
!system 1271 消息记录
!system 1272 清除记录
......@@ -1206,3 +1206,4 @@
!setname 0x1a5 于贝尔 ユベル
!setname 0x1a6 肃声 粛声
!setname 0x1a7 白斗气 ホワイト・オーラ
!setname 0x1a8 玩具 トイ
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