Commit 09f6fab7 authored by edo9300's avatar edo9300

Revert "Updated button displaying"

This reverts commit ac745dce.
parent ac745dce
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
#ifndef GAME_H
#define GAME_H
#include "config.h"
#include "client_field.h"
#include "deck_con.h"
#include "menu_handler.h"
#include <unordered_map>
#include <vector>
#include <list>
#include "CGUISkinSystem/CGUISkinSystem.h"
namespace ygo {
struct Config {
bool use_d3d;
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 lastdeck[64];
wchar_t textfont[256];
wchar_t numfont[256];
wchar_t roompass[20];
//settings
int chkMAutoPos;
int chkSTAutoPos;
int chkRandomPos;
int chkAutoChain;
int chkWaitChain;
int chkIgnore1;
int chkIgnore2;
int chkHideSetname;
int chkHideHintButton;
int draw_field_spell;
int separate_clear_button;
bool enablesound;
double volume;
bool enablemusic;
int skin_index;
};
struct DuelInfo {
bool isStarted;
bool isReplay;
bool isReplaySkiping;
bool isFirst;
bool isTag;
bool isSingleMode;
bool is_shuffling;
bool tag_player[2];
int lp[2];
int startlp;
int duel_rule;
int turn;
short curMsg;
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;
unsigned char player_type;
unsigned char time_player;
unsigned short time_limit;
unsigned short time_left[2];
};
struct FadingUnit {
bool signalAction;
bool isFadein;
int fadingFrame;
int autoFadeoutFrame;
irr::gui::IGUIElement* guiFading;
irr::core::recti fadingSize;
irr::core::vector2di fadingUL;
irr::core::vector2di fadingLR;
irr::core::vector2di fadingDiff;
};
class Game {
public:
bool Initialize();
void MainLoop();
void BuildProjectionMatrix(irr::core::matrix4& mProjection, f32 left, f32 right, f32 bottom, f32 top, f32 znear, f32 zfar);
void InitStaticText(irr::gui::IGUIStaticText* pControl, u32 cWidth, u32 cHeight, irr::gui::CGUITTFont* font, const wchar_t* text);
void SetStaticText(irr::gui::IGUIStaticText* pControl, u32 cWidth, irr::gui::CGUITTFont* font, const wchar_t* text, u32 pos = 0);
void LoadExpansionDB();
void RefreshDeck(irr::gui::IGUIComboBox* cbDeck);
void RefreshReplay();
void RefreshSingleplay();
void RefreshBGMList();
void DrawSelectionLine(irr::video::S3DVertex* vec, bool strip, int width, float* cv);
void DrawBackGround();
void DrawLinkedZones(ClientCard* pcard);
void DrawCards();
void DrawCard(ClientCard* pcard);
void DrawMisc();
void DrawStatus(ClientCard* pcard, int x1, int y1, int x2, int y2);
void DrawGUI();
void DrawSpec();
void ShowElement(irr::gui::IGUIElement* element, int autoframe = 0);
void HideElement(irr::gui::IGUIElement* element, bool set_action = false);
void PopupElement(irr::gui::IGUIElement* element, int hideframe = 0);
void WaitFrameSignal(int frame);
void DrawThumb(code_pointer cp, position2di pos, std::unordered_map<int, int>* lflist, bool drag = false);
void DrawDeckBd();
void LoadConfig();
void SaveConfig();
void ShowCardInfo(int code);
void AddChatMsg(wchar_t* msg, int player);
void AddDebugMsg(char* msgbuf);
void ClearTextures();
void CloseDuelWindow();
void PlaySoundEffect(char* sound);
void PlayMusic(char* song, bool loop);
void PlayBGM();
int LocalPlayer(int player);
const wchar_t* LocalName(int local_player);
bool HasFocus(EGUI_ELEMENT_TYPE type) const {
irr::gui::IGUIElement* focus = env->getFocus();
return focus && focus->hasType(type);
}
void OnResize();
recti Resize(s32 x, s32 y, s32 x2, s32 y2);
recti Resize(s32 x, s32 y, s32 x2, s32 y2, s32 dx, s32 dy, s32 dx2, s32 dy2);
position2di Resize(s32 x, s32 y, bool reverse = false);
recti ResizeElem(s32 x, s32 y, s32 x2, s32 y2);
recti ResizeWin(s32 x, s32 y, s32 x2, s32 y2, bool chat = false);
Mutex gMutex;
Mutex gBuffer;
Signal frameSignal;
Signal actionSignal;
Signal replaySignal;
Signal singleSignal;
Signal closeSignal;
Signal closeDoneSignal;
Config gameConf;
DuelInfo dInfo;
std::list<FadingUnit> fadingList;
std::vector<int> logParam;
std::wstring chatMsg[8];
std::vector<std::wstring> BGMList;
int hideChatTimer;
bool hideChat;
int chatTiming[8];
int chatType[8];
unsigned short linePattern;
int waitFrame;
int signalFrame;
int actionParam;
const wchar_t* showingtext;
int showcard;
int showcardcode;
int showcarddif;
int showcardp;
int is_attacking;
int attack_sv;
irr::core::vector3df atk_r;
irr::core::vector3df atk_t;
float atkdy;
int lpframe;
int lpd;
int lpplayer;
int lpccolor;
wchar_t* lpcstring;
bool always_chain;
bool ignore_chain;
bool chain_when_avail;
bool is_building;
bool is_siding;
irr::core::dimension2d<irr::u32> window_size;
CGUISkinSystem *skinSystem;
ClientField dField;
DeckBuilder deckBuilder;
MenuHandler menuHandler;
irr::IrrlichtDevice* device;
irr::video::IVideoDriver* driver;
irr::scene::ISceneManager* smgr;
irr::scene::ICameraSceneNode* camera;
//GUI
irr::gui::IGUIEnvironment* env;
irr::gui::CGUITTFont* guiFont;
irr::gui::CGUITTFont* textFont;
irr::gui::CGUITTFont* numFont;
irr::gui::CGUITTFont* adFont;
irr::gui::CGUITTFont* lpcFont;
std::map<irr::gui::CGUIImageButton*, int> imageLoading;
//card image
irr::gui::IGUIStaticText* wCardImg;
irr::gui::IGUIImage* imgCard;
//hint text
irr::gui::IGUIStaticText* stHintMsg;
irr::gui::IGUIStaticText* stTip;
//infos
irr::gui::IGUITabControl* wInfos;
irr::gui::IGUIStaticText* stName;
irr::gui::IGUIStaticText* stInfo;
irr::gui::IGUIStaticText* stDataInfo;
irr::gui::IGUIStaticText* stSetName;
irr::gui::IGUIStaticText* stText;
irr::gui::IGUIStaticText* stVolume;
irr::gui::IGUIScrollBar* scrCardText;
irr::gui::IGUICheckBox* chkMAutoPos;
irr::gui::IGUICheckBox* chkSTAutoPos;
irr::gui::IGUICheckBox* chkRandomPos;
irr::gui::IGUICheckBox* chkAutoChain;
irr::gui::IGUICheckBox* chkWaitChain;
irr::gui::IGUICheckBox* chkHideSetname;
irr::gui::IGUICheckBox* chkHideHintButton;
irr::gui::IGUICheckBox* chkEnableSound;
irr::gui::IGUICheckBox* chkEnableMusic;
irr::gui::IGUIListBox* lstLog;
irr::gui::IGUIButton* btnClearLog;
irr::gui::IGUIButton* btnSaveLog;
irr::gui::IGUIScrollBar* srcVolume;
//main menu
irr::gui::IGUIWindow* wMainMenu;
irr::gui::IGUIButton* btnLanMode;
irr::gui::IGUIButton* btnServerMode;
irr::gui::IGUIButton* btnReplayMode;
irr::gui::IGUIButton* btnTestMode;
irr::gui::IGUIButton* btnDeckEdit;
irr::gui::IGUIButton* btnModeExit;
//lan
irr::gui::IGUIWindow* wLanWindow;
irr::gui::IGUIEditBox* ebNickName;
irr::gui::IGUIListBox* lstHostList;
irr::gui::IGUIButton* btnLanRefresh;
irr::gui::IGUIEditBox* ebJoinHost;
irr::gui::IGUIEditBox* ebJoinPort;
irr::gui::IGUIEditBox* ebJoinPass;
irr::gui::IGUIButton* btnJoinHost;
irr::gui::IGUIButton* btnJoinCancel;
irr::gui::IGUIButton* btnCreateHost;
//create host
irr::gui::IGUIWindow* wCreateHost;
irr::gui::IGUIComboBox* cbLFlist;
irr::gui::IGUIComboBox* cbMatchMode;
irr::gui::IGUIComboBox* cbRule;
irr::gui::IGUIEditBox* ebTimeLimit;
irr::gui::IGUIEditBox* ebStartLP;
irr::gui::IGUIEditBox* ebStartHand;
irr::gui::IGUIEditBox* ebDrawCount;
irr::gui::IGUIEditBox* ebServerName;
irr::gui::IGUIEditBox* ebServerPass;
irr::gui::IGUIButton* btnRuleCards;
irr::gui::IGUIWindow* wRules;
irr::gui::IGUICheckBox* chkRules[14];
irr::gui::IGUIButton* btnRulesOK;
irr::gui::IGUICheckBox* chkDrawDestiny;
irr::gui::IGUIComboBox* cbDuelRule;
irr::gui::IGUICheckBox* chkNoCheckDeck;
irr::gui::IGUICheckBox* chkNoShuffleDeck;
irr::gui::IGUIButton* btnHostConfirm;
irr::gui::IGUIButton* btnHostCancel;
//host panel
irr::gui::IGUIWindow* wHostPrepare;
irr::gui::IGUIWindow* wHostPrepare2;
irr::gui::IGUIStaticText* stHostCardRule;
irr::gui::IGUIButton* btnHostPrepDuelist;
irr::gui::IGUIButton* btnHostPrepOB;
irr::gui::IGUIStaticText* stHostPrepDuelist[4];
irr::gui::IGUICheckBox* chkHostPrepReady[4];
irr::gui::IGUIButton* btnHostPrepKick[4];
irr::gui::IGUIComboBox* cbDeckSelect;
irr::gui::IGUIComboBox* cbDeckSelect2;
irr::gui::IGUIStaticText* stHostPrepRule;
irr::gui::IGUIStaticText* stHostPrepRule2;
irr::gui::IGUIStaticText* stHostPrepOB;
irr::gui::IGUIButton* btnHostPrepStart;
irr::gui::IGUIButton* btnHostPrepCancel;
//replay
irr::gui::IGUIWindow* wReplay;
irr::gui::IGUIListBox* lstReplayList;
irr::gui::IGUIStaticText* stReplayInfo;
irr::gui::IGUIButton* btnLoadReplay;
irr::gui::IGUIButton* btnReplayCancel;
irr::gui::IGUIEditBox* ebRepStartTurn;
//single play
irr::gui::IGUIWindow* wSinglePlay;
irr::gui::IGUIListBox* lstSinglePlayList;
irr::gui::IGUIStaticText* stSinglePlayInfo;
irr::gui::IGUIButton* btnLoadSinglePlay;
irr::gui::IGUIButton* btnSinglePlayCancel;
//hand
irr::gui::IGUIWindow* wHand;
irr::gui::IGUIButton* btnHand[3];
//
irr::gui::IGUIWindow* wFTSelect;
irr::gui::IGUIButton* btnFirst;
irr::gui::IGUIButton* btnSecond;
//message
irr::gui::IGUIWindow* wMessage;
irr::gui::IGUIStaticText* stMessage;
irr::gui::IGUIButton* btnMsgOK;
//auto close message
irr::gui::IGUIWindow* wACMessage;
irr::gui::IGUIStaticText* stACMessage;
//yes/no
irr::gui::IGUIWindow* wQuery;
irr::gui::IGUIStaticText* stQMessage;
irr::gui::IGUIButton* btnYes;
irr::gui::IGUIButton* btnNo;
//options
irr::gui::IGUIWindow* wOptions;
irr::gui::IGUIStaticText* stOptions;
irr::gui::IGUIButton* btnOptionp;
irr::gui::IGUIButton* btnOptionn;
irr::gui::IGUIButton* btnOptionOK;
//pos selection
irr::gui::IGUIWindow* wPosSelect;
irr::gui::CGUIImageButton* btnPSAU;
irr::gui::CGUIImageButton* btnPSAD;
irr::gui::CGUIImageButton* btnPSDU;
irr::gui::CGUIImageButton* btnPSDD;
//card selection
irr::gui::IGUIWindow* wCardSelect;
irr::gui::CGUIImageButton* btnCardSelect[5];
irr::gui::IGUIStaticText *stCardPos[5];
irr::gui::IGUIScrollBar *scrCardList;
irr::gui::IGUIButton* btnSelectOK;
//card display
irr::gui::IGUIWindow* wCardDisplay;
irr::gui::CGUIImageButton* btnCardDisplay[5];
irr::gui::IGUIStaticText *stDisplayPos[5];
irr::gui::IGUIScrollBar *scrDisplayList;
irr::gui::IGUIButton* btnDisplayOK;
//announce number
irr::gui::IGUIWindow* wANNumber;
irr::gui::IGUIComboBox* cbANNumber;
irr::gui::IGUIButton* btnANNumberOK;
//announce card
irr::gui::IGUIWindow* wANCard;
irr::gui::IGUIEditBox* ebANCard;
irr::gui::IGUIListBox* lstANCard;
irr::gui::IGUIButton* btnANCardOK;
//announce attribute
irr::gui::IGUIWindow* wANAttribute;
irr::gui::IGUICheckBox* chkAttribute[7];
//announce race
irr::gui::IGUIWindow* wANRace;
irr::gui::IGUICheckBox* chkRace[25];
//cmd menu
irr::gui::IGUIWindow* wCmdMenu;
irr::gui::IGUIButton* btnActivate;
irr::gui::IGUIButton* btnSummon;
irr::gui::IGUIButton* btnSPSummon;
irr::gui::IGUIButton* btnMSet;
irr::gui::IGUIButton* btnSSet;
irr::gui::IGUIButton* btnRepos;
irr::gui::IGUIButton* btnAttack;
irr::gui::IGUIButton* btnShowList;
irr::gui::IGUIButton* btnOperation;
irr::gui::IGUIButton* btnReset;
irr::gui::IGUIButton* btnShuffle;
//chat window
irr::gui::IGUIWindow* wChat;
irr::gui::IGUIListBox* lstChatLog;
irr::gui::IGUIEditBox* ebChatInput;
irr::gui::IGUICheckBox* chkIgnore1;
irr::gui::IGUICheckBox* chkIgnore2;
//phase button
irr::gui::IGUIStaticText* wPhase;
irr::gui::IGUIButton* btnDP;
irr::gui::IGUIButton* btnSP;
irr::gui::IGUIButton* btnM1;
irr::gui::IGUIButton* btnBP;
irr::gui::IGUIButton* btnM2;
irr::gui::IGUIButton* btnEP;
//deck edit
irr::gui::IGUIStaticText* wDeckEdit;
irr::gui::IGUIComboBox* cbDBLFList;
irr::gui::IGUIComboBox* cbDBDecks;
irr::gui::IGUIButton* btnClearDeck;
irr::gui::IGUIButton* btnSortDeck;
irr::gui::IGUIButton* btnShuffleDeck;
irr::gui::IGUIButton* btnSaveDeck;
irr::gui::IGUIButton* btnDeleteDeck;
irr::gui::IGUIButton* btnSaveDeckAs;
irr::gui::IGUIButton* btnSideOK;
irr::gui::IGUIEditBox* ebDeckname;
irr::gui::IGUIStaticText* stBanlist;
irr::gui::IGUIStaticText* stDeck;
irr::gui::IGUIStaticText* stCategory;
irr::gui::IGUIStaticText* stLimit;
irr::gui::IGUIStaticText* stAttribute;
irr::gui::IGUIStaticText* stRace;
irr::gui::IGUIStaticText* stAttack;
irr::gui::IGUIStaticText* stDefense;
irr::gui::IGUIStaticText* stStar;
irr::gui::IGUIStaticText* stSearch;
irr::gui::IGUIStaticText* stScale;
//filter
irr::gui::IGUIStaticText* wFilter;
irr::gui::IGUIScrollBar* scrFilter;
irr::gui::IGUIComboBox* cbCardType;
irr::gui::IGUIComboBox* cbCardType2;
irr::gui::IGUIComboBox* cbRace;
irr::gui::IGUIComboBox* cbAttribute;
irr::gui::IGUIComboBox* cbLimit;
irr::gui::IGUIEditBox* ebStar;
irr::gui::IGUIEditBox* ebScale;
irr::gui::IGUIEditBox* ebAttack;
irr::gui::IGUIEditBox* ebDefense;
irr::gui::IGUIEditBox* ebCardName;
irr::gui::IGUIButton* btnEffectFilter;
irr::gui::IGUIButton* btnStartFilter;
irr::gui::IGUIButton* btnClearFilter;
irr::gui::IGUIWindow* wCategories;
irr::gui::IGUICheckBox* chkCategory[32];
irr::gui::IGUIButton* btnCategoryOK;
irr::gui::IGUIButton* btnMarksFilter;
irr::gui::IGUIWindow* wLinkMarks;
irr::gui::IGUIButton* btnMark[8];
irr::gui::IGUIButton* btnMarksOK;
//sort type
irr::gui::IGUIStaticText* wSort;
irr::gui::IGUIComboBox* cbSortType;
//replay save
irr::gui::IGUIWindow* wReplaySave;
irr::gui::IGUIEditBox* ebRSName;
irr::gui::IGUIButton* btnRSYes;
irr::gui::IGUIButton* btnRSNo;
//replay control
irr::gui::IGUIStaticText* wReplayControl;
irr::gui::IGUIButton* btnReplayStart;
irr::gui::IGUIButton* btnReplayPause;
irr::gui::IGUIButton* btnReplayStep;
irr::gui::IGUIButton* btnReplayUndo;
irr::gui::IGUIButton* btnReplayExit;
irr::gui::IGUIButton* btnReplaySwap;
//surrender/leave
irr::gui::IGUIButton* btnLeaveGame;
//soundEngine
irrklang::ISoundEngine* engineSound;
irrklang::ISoundEngine* engineMusic;
//swap
irr::gui::IGUIButton* btnSpectatorSwap;
//chain control
irr::gui::IGUIButton* btnChainIgnore;
irr::gui::IGUIButton* btnChainAlways;
irr::gui::IGUIButton* btnChainWhenAvail;
//cancel or finish
irr::gui::IGUIButton* btnCancelOrFinish;
};
extern Game* mainGame;
}
#define UEVENT_EXIT 0x1
#define UEVENT_TOWINDOW 0x2
#define COMMAND_ACTIVATE 0x0001
#define COMMAND_SUMMON 0x0002
#define COMMAND_SPSUMMON 0x0004
#define COMMAND_MSET 0x0008
#define COMMAND_SSET 0x0010
#define COMMAND_REPOS 0x0020
#define COMMAND_ATTACK 0x0040
#define COMMAND_LIST 0x0080
#define COMMAND_OPERATION 0x0100
#define COMMAND_RESET 0x0200
#define POSITION_HINT 0x8000
#define BUTTON_LAN_MODE 100
#define BUTTON_SINGLE_MODE 101
#define BUTTON_REPLAY_MODE 102
#define BUTTON_TEST_MODE 103
#define BUTTON_DECK_EDIT 104
#define BUTTON_MODE_EXIT 105
#define LISTBOX_LAN_HOST 110
#define BUTTON_JOIN_HOST 111
#define BUTTON_JOIN_CANCEL 112
#define BUTTON_CREATE_HOST 113
#define BUTTON_HOST_CONFIRM 114
#define BUTTON_HOST_CANCEL 115
#define BUTTON_LAN_REFRESH 116
#define BUTTON_RULE_CARDS 117
#define BUTTON_RULE_OK 118
#define BUTTON_HP_DUELIST 120
#define BUTTON_HP_OBSERVER 121
#define BUTTON_HP_START 122
#define BUTTON_HP_CANCEL 123
#define BUTTON_HP_KICK 124
#define CHECKBOX_HP_READY 125
#define LISTBOX_REPLAY_LIST 130
#define BUTTON_LOAD_REPLAY 131
#define BUTTON_CANCEL_REPLAY 132
#define EDITBOX_CHAT 140
#define BUTTON_MSG_OK 200
#define BUTTON_YES 201
#define BUTTON_NO 202
#define BUTTON_HAND1 205
#define BUTTON_HAND2 206
#define BUTTON_HAND3 207
#define BUTTON_FIRST 208
#define BUTTON_SECOND 209
#define BUTTON_POS_AU 210
#define BUTTON_POS_AD 211
#define BUTTON_POS_DU 212
#define BUTTON_POS_DD 213
#define BUTTON_OPTION_PREV 220
#define BUTTON_OPTION_NEXT 221
#define BUTTON_OPTION_OK 222
#define BUTTON_CARD_0 230
#define BUTTON_CARD_1 231
#define BUTTON_CARD_2 232
#define BUTTON_CARD_3 233
#define BUTTON_CARD_4 234
#define SCROLL_CARD_SELECT 235
#define BUTTON_CARD_SEL_OK 236
#define BUTTON_CMD_ACTIVATE 240
#define BUTTON_CMD_SUMMON 241
#define BUTTON_CMD_SPSUMMON 242
#define BUTTON_CMD_MSET 243
#define BUTTON_CMD_SSET 244
#define BUTTON_CMD_REPOS 245
#define BUTTON_CMD_ATTACK 246
#define BUTTON_CMD_SHOWLIST 247
#define BUTTON_CMD_SHUFFLE 248
#define BUTTON_CMD_RESET 249
#define BUTTON_ANNUMBER_OK 250
#define BUTTON_ANCARD_OK 251
#define EDITBOX_ANCARD 252
#define LISTBOX_ANCARD 253
#define CHECK_ATTRIBUTE 254
#define CHECK_RACE 255
#define BUTTON_BP 260
#define BUTTON_M2 261
#define BUTTON_EP 262
#define BUTTON_LEAVE_GAME 263
#define BUTTON_CHAIN_IGNORE 264
#define BUTTON_CHAIN_ALWAYS 265
#define BUTTON_CHAIN_WHENAVAIL 266
#define BUTTON_CANCEL_OR_FINISH 267
#define BUTTON_CLEAR_LOG 270
#define LISTBOX_LOG 271
#define SCROLL_CARDTEXT 280
#define BUTTON_DISPLAY_0 290
#define BUTTON_DISPLAY_1 291
#define BUTTON_DISPLAY_2 292
#define BUTTON_DISPLAY_3 293
#define BUTTON_DISPLAY_4 294
#define SCROLL_CARD_DISPLAY 295
#define BUTTON_CARD_DISP_OK 296
#define BUTTON_CATEGORY_OK 300
#define COMBOBOX_DBLFLIST 301
#define COMBOBOX_DBDECKS 302
#define BUTTON_CLEAR_DECK 303
#define BUTTON_SAVE_DECK 304
#define BUTTON_SAVE_DECK_AS 305
#define BUTTON_DELETE_DECK 306
//#define BUTTON_DBEXIT 307
#define BUTTON_SORT_DECK 308
#define BUTTON_SIDE_OK 309
#define BUTTON_SHUFFLE_DECK 310
#define COMBOBOX_MAINTYPE 311
#define COMBOBOX_SECONDTYPE 312
#define BUTTON_EFFECT_FILTER 313
#define BUTTON_START_FILTER 314
#define SCROLL_FILTER 315
#define EDITBOX_KEYWORD 316
#define BUTTON_CLEAR_FILTER 317
#define COMBOBOX_OTHER_FILT 319
#define BUTTON_REPLAY_START 320
#define BUTTON_REPLAY_PAUSE 321
#define BUTTON_REPLAY_STEP 322
#define BUTTON_REPLAY_UNDO 323
#define BUTTON_REPLAY_EXIT 324
#define BUTTON_REPLAY_SWAP 325
#define BUTTON_REPLAY_SAVE 330
#define BUTTON_REPLAY_CANCEL 331
#define LISTBOX_SINGLEPLAY_LIST 350
#define BUTTON_LOAD_SINGLEPLAY 351
#define BUTTON_CANCEL_SINGLEPLAY 352
#define CHECK_SEALED_DUEL 353
#define CHECK_BOOSTER_DUEL 354
#define CHECK_ACTION_DUEL 355
#define CHECK_SPEED_DUEL 356
#define CHECK_CONCENTRATION_DUEL 357
#define CHECK_BOSS_DUEL 358
#define CHECK_BATTLE_CITY 359
#define CHECK_DUELIST_KINGDOM 360
#define CHECK_ROSE_DUEL 361
#define CHECK_TURBO_DUEL_1 362
#define CHECK_TURBO_DUEL_2 363
#define CHECK_DOUBLE_DECK 364
#define CHECK_COMMAND_DUEL 365
#define CHECK_DECK_MASTER_DUEL 366
#define CHECKBOX_ENABLE_MUSIC 361
#define SCROLL_VOLUME 362
#define COMBOBOX_SORTTYPE 370
#define BUTTON_MARKS_FILTER 380
#define BUTTON_MARKERS_OK 381
#define DEFAULT_DUEL_RULE 4
#endif // GAME_H
#ifndef GAME_H
#define GAME_H
#include "config.h"
#include "client_field.h"
#include "deck_con.h"
#include "menu_handler.h"
#include <unordered_map>
#include <vector>
#include <list>
#include "CGUISkinSystem/CGUISkinSystem.h"
namespace ygo {
struct Config {
bool use_d3d;
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 lastdeck[64];
wchar_t textfont[256];
wchar_t numfont[256];
wchar_t roompass[20];
//settings
int chkMAutoPos;
int chkSTAutoPos;
int chkRandomPos;
int chkAutoChain;
int chkWaitChain;
int chkIgnore1;
int chkIgnore2;
int chkHideSetname;
int chkHideHintButton;
int draw_field_spell;
int separate_clear_button;
bool enablesound;
double volume;
bool enablemusic;
int skin_index;
};
struct DuelInfo {
bool isStarted;
bool isReplay;
bool isReplaySkiping;
bool isFirst;
bool isTag;
bool isSingleMode;
bool is_shuffling;
bool tag_player[2];
int lp[2];
int startlp;
int duel_rule;
int turn;
short curMsg;
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;
unsigned char player_type;
unsigned char time_player;
unsigned short time_limit;
unsigned short time_left[2];
};
struct FadingUnit {
bool signalAction;
bool isFadein;
int fadingFrame;
int autoFadeoutFrame;
irr::gui::IGUIElement* guiFading;
irr::core::recti fadingSize;
irr::core::vector2di fadingUL;
irr::core::vector2di fadingLR;
irr::core::vector2di fadingDiff;
};
class Game {
public:
bool Initialize();
void MainLoop();
void BuildProjectionMatrix(irr::core::matrix4& mProjection, f32 left, f32 right, f32 bottom, f32 top, f32 znear, f32 zfar);
void InitStaticText(irr::gui::IGUIStaticText* pControl, u32 cWidth, u32 cHeight, irr::gui::CGUITTFont* font, const wchar_t* text);
void SetStaticText(irr::gui::IGUIStaticText* pControl, u32 cWidth, irr::gui::CGUITTFont* font, const wchar_t* text, u32 pos = 0);
void LoadExpansionDB();
void RefreshDeck(irr::gui::IGUIComboBox* cbDeck);
void RefreshReplay();
void RefreshSingleplay();
void RefreshBGMList();
void DrawSelectionLine(irr::video::S3DVertex* vec, bool strip, int width, float* cv);
void DrawBackGround();
void DrawLinkedZones(ClientCard* pcard);
void DrawCards();
void DrawCard(ClientCard* pcard);
void DrawMisc();
void DrawStatus(ClientCard* pcard, int x1, int y1, int x2, int y2);
void DrawGUI();
void DrawSpec();
void ShowElement(irr::gui::IGUIElement* element, int autoframe = 0);
void HideElement(irr::gui::IGUIElement* element, bool set_action = false);
void PopupElement(irr::gui::IGUIElement* element, int hideframe = 0);
void WaitFrameSignal(int frame);
void DrawThumb(code_pointer cp, position2di pos, std::unordered_map<int, int>* lflist, bool drag = false);
void DrawDeckBd();
void LoadConfig();
void SaveConfig();
void ShowCardInfo(int code);
void AddChatMsg(wchar_t* msg, int player);
void AddDebugMsg(char* msgbuf);
void ClearTextures();
void CloseDuelWindow();
void PlaySoundEffect(char* sound);
void PlayMusic(char* song, bool loop);
void PlayBGM();
int LocalPlayer(int player);
const wchar_t* LocalName(int local_player);
bool HasFocus(EGUI_ELEMENT_TYPE type) const {
irr::gui::IGUIElement* focus = env->getFocus();
return focus && focus->hasType(type);
}
void OnResize();
recti Resize(s32 x, s32 y, s32 x2, s32 y2);
recti Resize(s32 x, s32 y, s32 x2, s32 y2, s32 dx, s32 dy, s32 dx2, s32 dy2);
position2di Resize(s32 x, s32 y, bool reverse = false);
recti ResizeElem(s32 x, s32 y, s32 x2, s32 y2);
recti ResizeWin(s32 x, s32 y, s32 x2, s32 y2, bool chat = false);
Mutex gMutex;
Mutex gBuffer;
Signal frameSignal;
Signal actionSignal;
Signal replaySignal;
Signal singleSignal;
Signal closeSignal;
Signal closeDoneSignal;
Config gameConf;
DuelInfo dInfo;
std::list<FadingUnit> fadingList;
std::vector<int> logParam;
std::wstring chatMsg[8];
std::vector<std::wstring> BGMList;
int hideChatTimer;
bool hideChat;
int chatTiming[8];
int chatType[8];
unsigned short linePattern;
int waitFrame;
int signalFrame;
int actionParam;
const wchar_t* showingtext;
int showcard;
int showcardcode;
int showcarddif;
int showcardp;
int is_attacking;
int attack_sv;
irr::core::vector3df atk_r;
irr::core::vector3df atk_t;
float atkdy;
int lpframe;
int lpd;
int lpplayer;
int lpccolor;
wchar_t* lpcstring;
bool always_chain;
bool ignore_chain;
bool chain_when_avail;
bool is_building;
bool is_siding;
irr::core::dimension2d<irr::u32> window_size;
CGUISkinSystem *skinSystem;
ClientField dField;
DeckBuilder deckBuilder;
MenuHandler menuHandler;
irr::IrrlichtDevice* device;
irr::video::IVideoDriver* driver;
irr::scene::ISceneManager* smgr;
irr::scene::ICameraSceneNode* camera;
//GUI
irr::gui::IGUIEnvironment* env;
irr::gui::CGUITTFont* guiFont;
irr::gui::CGUITTFont* textFont;
irr::gui::CGUITTFont* numFont;
irr::gui::CGUITTFont* adFont;
irr::gui::CGUITTFont* lpcFont;
std::map<irr::gui::CGUIImageButton*, int> imageLoading;
//card image
irr::gui::IGUIStaticText* wCardImg;
irr::gui::IGUIImage* imgCard;
//hint text
irr::gui::IGUIStaticText* stHintMsg;
irr::gui::IGUIStaticText* stTip;
//infos
irr::gui::IGUITabControl* wInfos;
irr::gui::IGUIStaticText* stName;
irr::gui::IGUIStaticText* stInfo;
irr::gui::IGUIStaticText* stDataInfo;
irr::gui::IGUIStaticText* stSetName;
irr::gui::IGUIStaticText* stText;
irr::gui::IGUIStaticText* stVolume;
irr::gui::IGUIScrollBar* scrCardText;
irr::gui::IGUICheckBox* chkMAutoPos;
irr::gui::IGUICheckBox* chkSTAutoPos;
irr::gui::IGUICheckBox* chkRandomPos;
irr::gui::IGUICheckBox* chkAutoChain;
irr::gui::IGUICheckBox* chkWaitChain;
irr::gui::IGUICheckBox* chkHideSetname;
irr::gui::IGUICheckBox* chkHideHintButton;
irr::gui::IGUICheckBox* chkEnableSound;
irr::gui::IGUICheckBox* chkEnableMusic;
irr::gui::IGUIListBox* lstLog;
irr::gui::IGUIButton* btnClearLog;
irr::gui::IGUIButton* btnSaveLog;
irr::gui::IGUIScrollBar* srcVolume;
//main menu
irr::gui::IGUIWindow* wMainMenu;
irr::gui::IGUIButton* btnLanMode;
irr::gui::IGUIButton* btnServerMode;
irr::gui::IGUIButton* btnReplayMode;
irr::gui::IGUIButton* btnTestMode;
irr::gui::IGUIButton* btnDeckEdit;
irr::gui::IGUIButton* btnModeExit;
//lan
irr::gui::IGUIWindow* wLanWindow;
irr::gui::IGUIEditBox* ebNickName;
irr::gui::IGUIListBox* lstHostList;
irr::gui::IGUIButton* btnLanRefresh;
irr::gui::IGUIEditBox* ebJoinHost;
irr::gui::IGUIEditBox* ebJoinPort;
irr::gui::IGUIEditBox* ebJoinPass;
irr::gui::IGUIButton* btnJoinHost;
irr::gui::IGUIButton* btnJoinCancel;
irr::gui::IGUIButton* btnCreateHost;
//create host
irr::gui::IGUIWindow* wCreateHost;
irr::gui::IGUIComboBox* cbLFlist;
irr::gui::IGUIComboBox* cbMatchMode;
irr::gui::IGUIComboBox* cbRule;
irr::gui::IGUIEditBox* ebTimeLimit;
irr::gui::IGUIEditBox* ebStartLP;
irr::gui::IGUIEditBox* ebStartHand;
irr::gui::IGUIEditBox* ebDrawCount;
irr::gui::IGUIEditBox* ebServerName;
irr::gui::IGUIEditBox* ebServerPass;
irr::gui::IGUIButton* btnRuleCards;
irr::gui::IGUIWindow* wRules;
irr::gui::IGUICheckBox* chkRules[14];
irr::gui::IGUIButton* btnRulesOK;
irr::gui::IGUICheckBox* chkDrawDestiny;
irr::gui::IGUIComboBox* cbDuelRule;
irr::gui::IGUICheckBox* chkNoCheckDeck;
irr::gui::IGUICheckBox* chkNoShuffleDeck;
irr::gui::IGUIButton* btnHostConfirm;
irr::gui::IGUIButton* btnHostCancel;
//host panel
irr::gui::IGUIWindow* wHostPrepare;
irr::gui::IGUIWindow* wHostPrepare2;
irr::gui::IGUIStaticText* stHostCardRule;
irr::gui::IGUIButton* btnHostPrepDuelist;
irr::gui::IGUIButton* btnHostPrepOB;
irr::gui::IGUIStaticText* stHostPrepDuelist[4];
irr::gui::IGUICheckBox* chkHostPrepReady[4];
irr::gui::IGUIButton* btnHostPrepKick[4];
irr::gui::IGUIComboBox* cbDeckSelect;
irr::gui::IGUIComboBox* cbDeckSelect2;
irr::gui::IGUIStaticText* stHostPrepRule;
irr::gui::IGUIStaticText* stHostPrepRule2;
irr::gui::IGUIStaticText* stHostPrepOB;
irr::gui::IGUIButton* btnHostPrepStart;
irr::gui::IGUIButton* btnHostPrepCancel;
//replay
irr::gui::IGUIWindow* wReplay;
irr::gui::IGUIListBox* lstReplayList;
irr::gui::IGUIStaticText* stReplayInfo;
irr::gui::IGUIButton* btnLoadReplay;
irr::gui::IGUIButton* btnReplayCancel;
irr::gui::IGUIEditBox* ebRepStartTurn;
//single play
irr::gui::IGUIWindow* wSinglePlay;
irr::gui::IGUIListBox* lstSinglePlayList;
irr::gui::IGUIStaticText* stSinglePlayInfo;
irr::gui::IGUIButton* btnLoadSinglePlay;
irr::gui::IGUIButton* btnSinglePlayCancel;
//hand
irr::gui::IGUIWindow* wHand;
irr::gui::IGUIButton* btnHand[3];
//
irr::gui::IGUIWindow* wFTSelect;
irr::gui::IGUIButton* btnFirst;
irr::gui::IGUIButton* btnSecond;
//message
irr::gui::IGUIWindow* wMessage;
irr::gui::IGUIStaticText* stMessage;
irr::gui::IGUIButton* btnMsgOK;
//auto close message
irr::gui::IGUIWindow* wACMessage;
irr::gui::IGUIStaticText* stACMessage;
//yes/no
irr::gui::IGUIWindow* wQuery;
irr::gui::IGUIStaticText* stQMessage;
irr::gui::IGUIButton* btnYes;
irr::gui::IGUIButton* btnNo;
//options
irr::gui::IGUIWindow* wOptions;
irr::gui::IGUIStaticText* stOptions;
irr::gui::IGUIButton* btnOptionp;
irr::gui::IGUIButton* btnOptionn;
irr::gui::IGUIButton* btnOptionOK;
//pos selection
irr::gui::IGUIWindow* wPosSelect;
irr::gui::CGUIImageButton* btnPSAU;
irr::gui::CGUIImageButton* btnPSAD;
irr::gui::CGUIImageButton* btnPSDU;
irr::gui::CGUIImageButton* btnPSDD;
//card selection
irr::gui::IGUIWindow* wCardSelect;
irr::gui::CGUIImageButton* btnCardSelect[5];
irr::gui::IGUIStaticText *stCardPos[5];
irr::gui::IGUIScrollBar *scrCardList;
irr::gui::IGUIButton* btnSelectOK;
//card display
irr::gui::IGUIWindow* wCardDisplay;
irr::gui::CGUIImageButton* btnCardDisplay[5];
irr::gui::IGUIStaticText *stDisplayPos[5];
irr::gui::IGUIScrollBar *scrDisplayList;
irr::gui::IGUIButton* btnDisplayOK;
//announce number
irr::gui::IGUIWindow* wANNumber;
irr::gui::IGUIComboBox* cbANNumber;
irr::gui::IGUIButton* btnANNumberOK;
//announce card
irr::gui::IGUIWindow* wANCard;
irr::gui::IGUIEditBox* ebANCard;
irr::gui::IGUIListBox* lstANCard;
irr::gui::IGUIButton* btnANCardOK;
//announce attribute
irr::gui::IGUIWindow* wANAttribute;
irr::gui::IGUICheckBox* chkAttribute[7];
//announce race
irr::gui::IGUIWindow* wANRace;
irr::gui::IGUICheckBox* chkRace[25];
//cmd menu
irr::gui::IGUIWindow* wCmdMenu;
irr::gui::IGUIButton* btnActivate;
irr::gui::IGUIButton* btnSummon;
irr::gui::IGUIButton* btnSPSummon;
irr::gui::IGUIButton* btnMSet;
irr::gui::IGUIButton* btnSSet;
irr::gui::IGUIButton* btnRepos;
irr::gui::IGUIButton* btnAttack;
irr::gui::IGUIButton* btnShowList;
irr::gui::IGUIButton* btnOperation;
irr::gui::IGUIButton* btnReset;
irr::gui::IGUIButton* btnShuffle;
//chat window
irr::gui::IGUIWindow* wChat;
irr::gui::IGUIListBox* lstChatLog;
irr::gui::IGUIEditBox* ebChatInput;
irr::gui::IGUICheckBox* chkIgnore1;
irr::gui::IGUICheckBox* chkIgnore2;
//phase button
irr::gui::IGUIStaticText* wPhase;
irr::gui::IGUIButton* btnDP;
irr::gui::IGUIButton* btnSP;
irr::gui::IGUIButton* btnM1;
irr::gui::IGUIButton* btnBP;
irr::gui::IGUIButton* btnM2;
irr::gui::IGUIButton* btnEP;
//deck edit
irr::gui::IGUIStaticText* wDeckEdit;
irr::gui::IGUIComboBox* cbDBLFList;
irr::gui::IGUIComboBox* cbDBDecks;
irr::gui::IGUIButton* btnClearDeck;
irr::gui::IGUIButton* btnSortDeck;
irr::gui::IGUIButton* btnShuffleDeck;
irr::gui::IGUIButton* btnSaveDeck;
irr::gui::IGUIButton* btnDeleteDeck;
irr::gui::IGUIButton* btnSaveDeckAs;
irr::gui::IGUIButton* btnSideOK;
irr::gui::IGUIEditBox* ebDeckname;
irr::gui::IGUIStaticText* stBanlist;
irr::gui::IGUIStaticText* stDeck;
irr::gui::IGUIStaticText* stCategory;
irr::gui::IGUIStaticText* stLimit;
irr::gui::IGUIStaticText* stAttribute;
irr::gui::IGUIStaticText* stRace;
irr::gui::IGUIStaticText* stAttack;
irr::gui::IGUIStaticText* stDefense;
irr::gui::IGUIStaticText* stStar;
irr::gui::IGUIStaticText* stSearch;
irr::gui::IGUIStaticText* stScale;
//filter
irr::gui::IGUIStaticText* wFilter;
irr::gui::IGUIScrollBar* scrFilter;
irr::gui::IGUIComboBox* cbCardType;
irr::gui::IGUIComboBox* cbCardType2;
irr::gui::IGUIComboBox* cbRace;
irr::gui::IGUIComboBox* cbAttribute;
irr::gui::IGUIComboBox* cbLimit;
irr::gui::IGUIEditBox* ebStar;
irr::gui::IGUIEditBox* ebScale;
irr::gui::IGUIEditBox* ebAttack;
irr::gui::IGUIEditBox* ebDefense;
irr::gui::IGUIEditBox* ebCardName;
irr::gui::IGUIButton* btnEffectFilter;
irr::gui::IGUIButton* btnStartFilter;
irr::gui::IGUIButton* btnClearFilter;
irr::gui::IGUIWindow* wCategories;
irr::gui::IGUICheckBox* chkCategory[32];
irr::gui::IGUIButton* btnCategoryOK;
irr::gui::IGUIButton* btnMarksFilter;
irr::gui::IGUIWindow* wLinkMarks;
irr::gui::IGUIButton* btnMark[8];
irr::gui::IGUIButton* btnMarksOK;
//sort type
irr::gui::IGUIStaticText* wSort;
irr::gui::IGUIComboBox* cbSortType;
//replay save
irr::gui::IGUIWindow* wReplaySave;
irr::gui::IGUIEditBox* ebRSName;
irr::gui::IGUIButton* btnRSYes;
irr::gui::IGUIButton* btnRSNo;
//replay control
irr::gui::IGUIStaticText* wReplayControl;
irr::gui::IGUIButton* btnReplayStart;
irr::gui::IGUIButton* btnReplayPause;
irr::gui::IGUIButton* btnReplayStep;
irr::gui::IGUIButton* btnReplayUndo;
irr::gui::IGUIButton* btnReplayExit;
irr::gui::IGUIButton* btnReplaySwap;
//surrender/leave
irr::gui::IGUIButton* btnLeaveGame;
//soundEngine
irrklang::ISoundEngine* engineSound;
irrklang::ISoundEngine* engineMusic;
//swap
irr::gui::IGUIButton* btnSpectatorSwap;
//chain control
irr::gui::IGUIButton* btnChainIgnore;
irr::gui::IGUIButton* btnChainAlways;
irr::gui::IGUIButton* btnChainWhenAvail;
//cancel or finish
irr::gui::IGUIButton* btnCancelOrFinish;
};
extern Game* mainGame;
}
#define UEVENT_EXIT 0x1
#define UEVENT_TOWINDOW 0x2
#define COMMAND_ACTIVATE 0x0001
#define COMMAND_SUMMON 0x0002
#define COMMAND_SPSUMMON 0x0004
#define COMMAND_MSET 0x0008
#define COMMAND_SSET 0x0010
#define COMMAND_REPOS 0x0020
#define COMMAND_ATTACK 0x0040
#define COMMAND_LIST 0x0080
#define COMMAND_OPERATION 0x0100
#define COMMAND_RESET 0x0200
#define POSITION_HINT 0x8000
#define BUTTON_LAN_MODE 100
#define BUTTON_SINGLE_MODE 101
#define BUTTON_REPLAY_MODE 102
#define BUTTON_TEST_MODE 103
#define BUTTON_DECK_EDIT 104
#define BUTTON_MODE_EXIT 105
#define LISTBOX_LAN_HOST 110
#define BUTTON_JOIN_HOST 111
#define BUTTON_JOIN_CANCEL 112
#define BUTTON_CREATE_HOST 113
#define BUTTON_HOST_CONFIRM 114
#define BUTTON_HOST_CANCEL 115
#define BUTTON_LAN_REFRESH 116
#define BUTTON_RULE_CARDS 117
#define BUTTON_RULE_OK 118
#define BUTTON_HP_DUELIST 120
#define BUTTON_HP_OBSERVER 121
#define BUTTON_HP_START 122
#define BUTTON_HP_CANCEL 123
#define BUTTON_HP_KICK 124
#define CHECKBOX_HP_READY 125
#define LISTBOX_REPLAY_LIST 130
#define BUTTON_LOAD_REPLAY 131
#define BUTTON_CANCEL_REPLAY 132
#define EDITBOX_CHAT 140
#define BUTTON_MSG_OK 200
#define BUTTON_YES 201
#define BUTTON_NO 202
#define BUTTON_HAND1 205
#define BUTTON_HAND2 206
#define BUTTON_HAND3 207
#define BUTTON_FIRST 208
#define BUTTON_SECOND 209
#define BUTTON_POS_AU 210
#define BUTTON_POS_AD 211
#define BUTTON_POS_DU 212
#define BUTTON_POS_DD 213
#define BUTTON_OPTION_PREV 220
#define BUTTON_OPTION_NEXT 221
#define BUTTON_OPTION_OK 222
#define BUTTON_CARD_0 230
#define BUTTON_CARD_1 231
#define BUTTON_CARD_2 232
#define BUTTON_CARD_3 233
#define BUTTON_CARD_4 234
#define SCROLL_CARD_SELECT 235
#define BUTTON_CARD_SEL_OK 236
#define BUTTON_CMD_ACTIVATE 240
#define BUTTON_CMD_SUMMON 241
#define BUTTON_CMD_SPSUMMON 242
#define BUTTON_CMD_MSET 243
#define BUTTON_CMD_SSET 244
#define BUTTON_CMD_REPOS 245
#define BUTTON_CMD_ATTACK 246
#define BUTTON_CMD_SHOWLIST 247
#define BUTTON_CMD_SHUFFLE 248
#define BUTTON_CMD_RESET 249
#define BUTTON_ANNUMBER_OK 250
#define BUTTON_ANCARD_OK 251
#define EDITBOX_ANCARD 252
#define LISTBOX_ANCARD 253
#define CHECK_ATTRIBUTE 254
#define CHECK_RACE 255
#define BUTTON_BP 260
#define BUTTON_M2 261
#define BUTTON_EP 262
#define BUTTON_LEAVE_GAME 263
#define BUTTON_CHAIN_IGNORE 264
#define BUTTON_CHAIN_ALWAYS 265
#define BUTTON_CHAIN_WHENAVAIL 266
#define BUTTON_CANCEL_OR_FINISH 267
#define BUTTON_CLEAR_LOG 270
#define LISTBOX_LOG 271
#define SCROLL_CARDTEXT 280
#define BUTTON_DISPLAY_0 290
#define BUTTON_DISPLAY_1 291
#define BUTTON_DISPLAY_2 292
#define BUTTON_DISPLAY_3 293
#define BUTTON_DISPLAY_4 294
#define SCROLL_CARD_DISPLAY 295
#define BUTTON_CARD_DISP_OK 296
#define BUTTON_CATEGORY_OK 300
#define COMBOBOX_DBLFLIST 301
#define COMBOBOX_DBDECKS 302
#define BUTTON_CLEAR_DECK 303
#define BUTTON_SAVE_DECK 304
#define BUTTON_SAVE_DECK_AS 305
#define BUTTON_DELETE_DECK 306
//#define BUTTON_DBEXIT 307
#define BUTTON_SORT_DECK 308
#define BUTTON_SIDE_OK 309
#define BUTTON_SHUFFLE_DECK 310
#define COMBOBOX_MAINTYPE 311
#define COMBOBOX_SECONDTYPE 312
#define BUTTON_EFFECT_FILTER 313
#define BUTTON_START_FILTER 314
#define SCROLL_FILTER 315
#define EDITBOX_KEYWORD 316
#define BUTTON_CLEAR_FILTER 317
#define COMBOBOX_OTHER_FILT 319
#define BUTTON_REPLAY_START 320
#define BUTTON_REPLAY_PAUSE 321
#define BUTTON_REPLAY_STEP 322
#define BUTTON_REPLAY_UNDO 323
#define BUTTON_REPLAY_EXIT 324
#define BUTTON_REPLAY_SWAP 325
#define BUTTON_REPLAY_SAVE 330
#define BUTTON_REPLAY_CANCEL 331
#define LISTBOX_SINGLEPLAY_LIST 350
#define BUTTON_LOAD_SINGLEPLAY 351
#define BUTTON_CANCEL_SINGLEPLAY 352
#define CHECK_SEALED_DUEL 353
#define CHECK_BOOSTER_DUEL 354
#define CHECK_ACTION_DUEL 355
#define CHECK_SPEED_DUEL 356
#define CHECK_CONCENTRATION_DUEL 357
#define CHECK_BOSS_DUEL 358
#define CHECK_BATTLE_CITY 359
#define CHECK_DUELIST_KINGDOM 360
#define CHECK_ROSE_DUEL 361
#define CHECK_TURBO_DUEL_1 362
#define CHECK_TURBO_DUEL_2 363
#define CHECK_DOUBLE_DECK 364
#define CHECK_COMMAND_DUEL 365
#define CHECK_DECK_MASTER_DUEL 366
#define CHECKBOX_ENABLE_MUSIC 361
#define SCROLL_VOLUME 362
#define COMBOBOX_SORTTYPE 370
#define BUTTON_MARKS_FILTER 380
#define BUTTON_MARKERS_OK 381
#define DEFAULT_DUEL_RULE 4
#endif // GAME_H
#include "replay_mode.h"
#include "duelclient.h"
#include "game.h"
#include "../ocgcore/duel.h"
#include "../ocgcore/field.h"
#include "../ocgcore/mtrandom.h"
namespace ygo {
long ReplayMode::pduel = 0;
Replay ReplayMode::cur_replay;
bool ReplayMode::is_continuing = true;
bool ReplayMode::is_closing = false;
bool ReplayMode::is_pausing = false;
bool ReplayMode::is_paused = false;
bool ReplayMode::is_swaping = false;
bool ReplayMode::is_restarting = false;
bool ReplayMode::exit_pending = false;
int ReplayMode::skip_turn = 0;
int ReplayMode::current_step = 0;
int ReplayMode::skip_step = 0;
bool ReplayMode::StartReplay(int skipturn) {
skip_turn = skipturn;
Thread::NewThread(ReplayThread, 0);
return true;
}
void ReplayMode::StopReplay(bool is_exiting) {
is_pausing = false;
is_continuing = false;
is_closing = is_exiting;
exit_pending = true;
mainGame->actionSignal.Set();
}
void ReplayMode::SwapField() {
if(is_paused)
mainGame->dField.ReplaySwap();
else
is_swaping = true;
}
void ReplayMode::Pause(bool is_pause, bool is_step) {
if(is_pause)
is_pausing = true;
else {
if(!is_step)
is_pausing = false;
mainGame->actionSignal.Set();
}
}
bool ReplayMode::ReadReplayResponse() {
unsigned char resp[64];
bool result = cur_replay.ReadNextResponse(resp);
if(result)
set_responseb(pduel, resp);
return result;
}
int ReplayMode::ReplayThread(void* param) {
const ReplayHeader& rh = cur_replay.pheader;
mainGame->dInfo.isFirst = true;
mtrandom rnd;
int seed = rh.seed;
rnd.reset(seed);
if(rh.flag & REPLAY_TAG) {
cur_replay.ReadData(mainGame->dInfo.hostname, 40);
cur_replay.ReadData(mainGame->dInfo.hostname_tag, 40);
cur_replay.ReadData(mainGame->dInfo.clientname_tag, 40);
cur_replay.ReadData(mainGame->dInfo.clientname, 40);
mainGame->dInfo.isTag = true;
mainGame->dInfo.tag_player[0] = false;
mainGame->dInfo.tag_player[1] = false;
} else {
cur_replay.ReadData(mainGame->dInfo.hostname, 40);
cur_replay.ReadData(mainGame->dInfo.clientname, 40);
}
set_script_reader(default_script_reader);
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)MessageHandler);
pduel = create_duel(rnd.rand());
int start_lp = cur_replay.ReadInt32();
int start_hand = cur_replay.ReadInt32();
int draw_count = cur_replay.ReadInt32();
int opt = cur_replay.ReadInt32();
int duel_rule = opt >> 16;
mainGame->dInfo.duel_rule = duel_rule;
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;
myswprintf(mainGame->dInfo.strLP[0], L"%d", mainGame->dInfo.lp[0]);
myswprintf(mainGame->dInfo.strLP[1], L"%d", mainGame->dInfo.lp[1]);
mainGame->dInfo.turn = 0;
// reset master rule 4 phase button position
if (mainGame->dInfo.duel_rule >= 4) {
mainGame->btnSP->setRelativePosition(mainGame->Resize(0, 0, 50, 20));
mainGame->btnM1->setRelativePosition(mainGame->Resize(160, 0, 210, 20));
mainGame->btnBP->setRelativePosition(mainGame->Resize(160, 0, 210, 20));
mainGame->btnM2->setRelativePosition(mainGame->Resize(160, 0, 210, 20));
} else {
mainGame->btnSP->setRelativePosition(mainGame->Resize(65, 0, 115, 20));
mainGame->btnM1->setRelativePosition(mainGame->Resize(130, 0, 180, 20));
mainGame->btnBP->setRelativePosition(mainGame->Resize(195, 0, 245, 20));
mainGame->btnM2->setRelativePosition(mainGame->Resize(260, 0, 310, 20));
}
if(!(opt & DUEL_TAG_MODE)) {
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(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(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(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(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);
}
start_duel(pduel, opt);
ReplayRefreshDeck(0);
ReplayRefreshDeck(1);
ReplayRefreshExtra(0);
ReplayRefreshExtra(1);
mainGame->dInfo.isStarted = true;
mainGame->dInfo.isReplay = true;
char engineBuffer[0x1000];
is_continuing = true;
exit_pending = false;
current_step = 0;
skip_step = 0;
if(skip_turn < 0)
skip_turn = 0;
if(skip_turn) {
mainGame->dInfo.isReplaySkiping = true;
mainGame->gMutex.Lock();
} else
mainGame->dInfo.isReplaySkiping = false;
int len = 0;
while (is_continuing && !exit_pending) {
int result = process(pduel);
len = result & 0xffff;
/*int flag = result >> 16;*/
if (len > 0) {
get_message(pduel, (byte*)engineBuffer);
is_continuing = ReplayAnalyze(engineBuffer, len);
}
}
if(mainGame->dInfo.isReplaySkiping) {
mainGame->dInfo.isReplaySkiping = false;
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
}
end_duel(pduel);
if(!is_closing) {
mainGame->actionSignal.Reset();
mainGame->gMutex.Lock();
mainGame->stMessage->setText(dataManager.GetSysString(1501));
if(mainGame->wCardSelect->isVisible())
mainGame->HideElement(mainGame->wCardSelect);
mainGame->PopupElement(mainGame->wMessage);
mainGame->gMutex.Unlock();
mainGame->actionSignal.Wait();
mainGame->gMutex.Lock();
mainGame->dInfo.isStarted = false;
mainGame->dInfo.isReplay = false;
mainGame->gMutex.Unlock();
mainGame->closeDoneSignal.Reset();
mainGame->closeSignal.Set();
mainGame->closeDoneSignal.Wait();
mainGame->gMutex.Lock();
mainGame->ShowElement(mainGame->wReplay);
mainGame->device->setEventReceiver(&mainGame->menuHandler);
mainGame->gMutex.Unlock();
if(exit_on_return)
mainGame->device->closeDevice();
}
return 0;
}
void ReplayMode::Restart(bool refresh) {
end_duel(pduel);
mainGame->dInfo.isStarted = false;
mainGame->dField.panel = 0;
mainGame->dField.hovered_card = 0;
mainGame->dField.clicked_card = 0;
mainGame->dField.Clear();
//mainGame->device->setEventReceiver(&mainGame->dField);
cur_replay.Rewind();
const ReplayHeader& rh = cur_replay.pheader;
//mainGame->dInfo.isFirst = true;
mtrandom rnd;
int seed = rh.seed;
rnd.reset(seed);
if(rh.flag & REPLAY_TAG) {
cur_replay.ReadData(mainGame->dInfo.hostname, 40);
cur_replay.ReadData(mainGame->dInfo.hostname_tag, 40);
cur_replay.ReadData(mainGame->dInfo.clientname_tag, 40);
cur_replay.ReadData(mainGame->dInfo.clientname, 40);
mainGame->dInfo.isTag = true;
mainGame->dInfo.tag_player[0] = false;
mainGame->dInfo.tag_player[1] = false;
} else {
cur_replay.ReadData(mainGame->dInfo.hostname, 40);
cur_replay.ReadData(mainGame->dInfo.clientname, 40);
}
//set_card_reader((card_reader)DataManager::CardReader);
//set_message_handler((message_handler)MessageHandler);
pduel = create_duel(rnd.rand());
int start_lp = cur_replay.ReadInt32();
int start_hand = cur_replay.ReadInt32();
int draw_count = cur_replay.ReadInt32();
int opt = cur_replay.ReadInt32();
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;
myswprintf(mainGame->dInfo.strLP[0], L"%d", mainGame->dInfo.lp[0]);
myswprintf(mainGame->dInfo.strLP[1], L"%d", mainGame->dInfo.lp[1]);
mainGame->dInfo.turn = 0;
if(!(opt & DUEL_TAG_MODE)) {
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(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(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(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(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);
}
start_duel(pduel, opt);
if(refresh) {
mainGame->dField.RefreshAllCards();
mainGame->dInfo.isStarted = true;
//mainGame->dInfo.isReplay = true;
}
skip_turn = 0;
is_restarting = true;
}
void ReplayMode::Undo() {
Restart(false);
skip_step = current_step - 1;
if(skip_step < 0)
skip_step = 0;
current_step = 0;
if(skip_step) {
mainGame->dInfo.isReplaySkiping = true;
mainGame->gMutex.Lock();
Pause(false, false);
} else
mainGame->dInfo.isReplaySkiping = false;
}
bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
char* pbuf = msg;
int player, count;
is_restarting = false;
while (pbuf - msg < (int)len) {
if(is_closing)
return false;
if(is_restarting) {
is_restarting = false;
return true;
}
if(is_swaping) {
mainGame->gMutex.Lock();
mainGame->dField.ReplaySwap();
mainGame->gMutex.Unlock();
is_swaping = false;
}
char* offset = pbuf;
bool pauseable = true;
mainGame->dInfo.curMsg = BufferIO::ReadUInt8(pbuf);
switch (mainGame->dInfo.curMsg) {
case MSG_RETRY: {
if(mainGame->dInfo.isReplaySkiping) {
mainGame->dInfo.isReplaySkiping = false;
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
}
mainGame->gMutex.Lock();
mainGame->stMessage->setText(L"Error occurs.");
mainGame->PopupElement(mainGame->wMessage);
mainGame->gMutex.Unlock();
mainGame->actionSignal.Reset();
mainGame->actionSignal.Wait();
return false;
}
case MSG_HINT: {
pbuf += 6;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_WIN: {
if(mainGame->dInfo.isReplaySkiping) {
mainGame->dInfo.isReplaySkiping = false;
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
}
pbuf += 2;
DuelClient::ClientAnalyze(offset, pbuf - offset);
return false;
}
case MSG_SELECT_BATTLECMD: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 11;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8 + 2;
ReplayRefresh();
return ReadReplayResponse();
}
case MSG_SELECT_IDLECMD: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 11 + 3;
ReplayRefresh();
return ReadReplayResponse();
}
case MSG_SELECT_EFFECTYN: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 8;
return ReadReplayResponse();
}
case MSG_SELECT_YESNO: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
return ReadReplayResponse();
}
case MSG_SELECT_OPTION: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
return ReadReplayResponse();
}
case MSG_SELECT_CARD:
case MSG_SELECT_TRIBUTE: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 3;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8;
return ReadReplayResponse();
}
case MSG_SELECT_UNSELECT_CARD: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8;
return ReadReplayResponse();
}
case MSG_SELECT_CHAIN: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += 10 + count * 13;
return ReadReplayResponse();
}
case MSG_SELECT_PLACE:
case MSG_SELECT_DISFIELD: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 5;
return ReadReplayResponse();
}
case MSG_SELECT_POSITION: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 5;
return ReadReplayResponse();
}
case MSG_SELECT_COUNTER: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 9;
return ReadReplayResponse();
}
case MSG_SELECT_SUM: {
pbuf++;
player = BufferIO::ReadInt8(pbuf);
pbuf += 6;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 11;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 11;
return ReadReplayResponse();
}
case MSG_SORT_CARD:
case MSG_SORT_CHAIN: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
return ReadReplayResponse();
}
case MSG_CONFIRM_DECKTOP: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CONFIRM_CARDS: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SHUFFLE_DECK: {
player = BufferIO::ReadInt8(pbuf);
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefreshDeck(player);
break;
}
case MSG_SHUFFLE_HAND: {
/*int oplayer = */BufferIO::ReadInt8(pbuf);
int count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_REFRESH_DECK: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SWAP_GRAVE_DECK: {
player = BufferIO::ReadInt8(pbuf);
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefreshGrave(player);
break;
}
case MSG_REVERSE_DECK: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefreshDeck(0);
ReplayRefreshDeck(1);
break;
}
case MSG_DECK_TOP: {
pbuf += 6;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SHUFFLE_SET_CARD: {
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_NEW_TURN: {
if(skip_turn) {
skip_turn--;
if(skip_turn == 0) {
mainGame->dInfo.isReplaySkiping = false;
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
}
}
player = BufferIO::ReadInt8(pbuf);
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_NEW_PHASE: {
pbuf += 2;
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefresh();
break;
}
case MSG_MOVE: {
int pc = pbuf[4];
int pl = pbuf[5];
/*int ps = pbuf[6];*/
/*int pp = pbuf[7];*/
int cc = pbuf[8];
int cl = pbuf[9];
int cs = pbuf[10];
/*int cp = pbuf[11];*/
pbuf += 16;
DuelClient::ClientAnalyze(offset, pbuf - offset);
if(cl && !(cl & 0x80) && (pl != cl || pc != cc))
ReplayRefreshSingle(cc, cl, cs);
break;
}
case MSG_POS_CHANGE: {
pbuf += 9;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SET: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_SWAP: {
pbuf += 16;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_FIELD_DISABLED: {
pbuf += 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_SUMMONING: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_SUMMONED: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefresh();
break;
}
case MSG_SPSUMMONING: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_SPSUMMONED: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefresh();
break;
}
case MSG_FLIPSUMMONING: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_FLIPSUMMONED: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefresh();
break;
}
case MSG_CHAINING: {
pbuf += 16;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CHAINED: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefresh();
break;
}
case MSG_CHAIN_SOLVING: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_CHAIN_SOLVED: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefresh();
pauseable = false;
break;
}
case MSG_CHAIN_END: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefresh();
pauseable = false;
break;
}
case MSG_CHAIN_NEGATED: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CHAIN_DISABLED: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CARD_SELECTED:
case MSG_RANDOM_SELECTED: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_BECOME_TARGET: {
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_DRAW: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_DAMAGE: {
pbuf += 5;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_RECOVER: {
pbuf += 5;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_EQUIP: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_LPUPDATE: {
pbuf += 5;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_UNEQUIP: {
pbuf += 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_CARD_TARGET: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_CANCEL_TARGET: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_PAY_LPCOST: {
pbuf += 5;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_ADD_COUNTER: {
pbuf += 7;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_REMOVE_COUNTER: {
pbuf += 7;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_ATTACK: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_BATTLE: {
pbuf += 26;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_ATTACK_DISABLED: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_DAMAGE_STEP_START: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefresh();
pauseable = false;
break;
}
case MSG_DAMAGE_STEP_END: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefresh();
pauseable = false;
break;
}
case MSG_MISSED_EFFECT: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_TOSS_COIN: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_TOSS_DICE: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_ROCK_PAPER_SCISSORS: {
player = BufferIO::ReadInt8(pbuf);
return ReadReplayResponse();
}
case MSG_HAND_RES: {
pbuf += 1;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_ANNOUNCE_RACE: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 5;
return ReadReplayResponse();
}
case MSG_ANNOUNCE_ATTRIB: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 5;
return ReadReplayResponse();
}
case MSG_ANNOUNCE_CARD: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
return ReadReplayResponse();
}
case MSG_ANNOUNCE_NUMBER:
case MSG_ANNOUNCE_CARD_FILTER: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += 4 * count;
return ReadReplayResponse();
}
case MSG_CARD_HINT: {
pbuf += 9;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_PLAYER_HINT: {
pbuf += 6;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_MATCH_KILL: {
pbuf += 4;
break;
}
case MSG_TAG_SWAP: {
player = pbuf[0];
pbuf += pbuf[2] * 4 + pbuf[4] * 4 + 9;
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefreshDeck(player);
ReplayRefreshExtra(player);
break;
}
}
if(pauseable) {
if(skip_step) {
skip_step--;
if(skip_step == 0) {
Pause(true, false);
mainGame->dInfo.isStarted = true;
mainGame->dInfo.isReplaySkiping = false;
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
}
}
if(is_pausing) {
is_paused = true;
mainGame->actionSignal.Reset();
mainGame->actionSignal.Wait();
is_paused = false;
}
current_step++;
}
}
return true;
}
void ReplayMode::ReplayRefresh(int flag) {
unsigned char queryBuffer[0x4000];
/*int len = */query_field_card(pduel, 0, LOCATION_MZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_MZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_MZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_MZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_SZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_SZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_SZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_SZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_HAND, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_HAND, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_HAND, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_HAND, (char*)queryBuffer);
}
void ReplayMode::ReplayRefreshHand(int player, int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_field_card(pduel, player, LOCATION_HAND, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(player), LOCATION_HAND, (char*)queryBuffer);
}
void ReplayMode::ReplayRefreshGrave(int player, int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_field_card(pduel, player, LOCATION_GRAVE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(player), LOCATION_GRAVE, (char*)queryBuffer);
}
void ReplayMode::ReplayRefreshDeck(int player, int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_field_card(pduel, player, LOCATION_DECK, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(player), LOCATION_DECK, (char*)queryBuffer);
}
void ReplayMode::ReplayRefreshExtra(int player, int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_field_card(pduel, player, LOCATION_EXTRA, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(player), LOCATION_EXTRA, (char*)queryBuffer);
}
void ReplayMode::ReplayRefreshSingle(int player, int location, int sequence, int flag) {
unsigned char queryBuffer[0x4000];
/*int len = */query_card(pduel, player, location, sequence, flag, queryBuffer, 0);
mainGame->dField.UpdateCard(mainGame->LocalPlayer(player), location, sequence, (char*)queryBuffer);
}
int ReplayMode::MessageHandler(long fduel, int type) {
if(!enable_log)
return 0;
char msgbuf[1024];
get_log_message(fduel, (byte*)msgbuf);
mainGame->AddDebugMsg(msgbuf);
return 0;
}
}
#include "replay_mode.h"
#include "duelclient.h"
#include "game.h"
#include "../ocgcore/duel.h"
#include "../ocgcore/field.h"
#include "../ocgcore/mtrandom.h"
namespace ygo {
long ReplayMode::pduel = 0;
Replay ReplayMode::cur_replay;
bool ReplayMode::is_continuing = true;
bool ReplayMode::is_closing = false;
bool ReplayMode::is_pausing = false;
bool ReplayMode::is_paused = false;
bool ReplayMode::is_swaping = false;
bool ReplayMode::is_restarting = false;
bool ReplayMode::exit_pending = false;
int ReplayMode::skip_turn = 0;
int ReplayMode::current_step = 0;
int ReplayMode::skip_step = 0;
bool ReplayMode::StartReplay(int skipturn) {
skip_turn = skipturn;
Thread::NewThread(ReplayThread, 0);
return true;
}
void ReplayMode::StopReplay(bool is_exiting) {
is_pausing = false;
is_continuing = false;
is_closing = is_exiting;
exit_pending = true;
mainGame->actionSignal.Set();
}
void ReplayMode::SwapField() {
if(is_paused)
mainGame->dField.ReplaySwap();
else
is_swaping = true;
}
void ReplayMode::Pause(bool is_pause, bool is_step) {
if(is_pause)
is_pausing = true;
else {
if(!is_step)
is_pausing = false;
mainGame->actionSignal.Set();
}
}
bool ReplayMode::ReadReplayResponse() {
unsigned char resp[64];
bool result = cur_replay.ReadNextResponse(resp);
if(result)
set_responseb(pduel, resp);
return result;
}
int ReplayMode::ReplayThread(void* param) {
const ReplayHeader& rh = cur_replay.pheader;
mainGame->dInfo.isFirst = true;
mtrandom rnd;
int seed = rh.seed;
rnd.reset(seed);
if(rh.flag & REPLAY_TAG) {
cur_replay.ReadData(mainGame->dInfo.hostname, 40);
cur_replay.ReadData(mainGame->dInfo.hostname_tag, 40);
cur_replay.ReadData(mainGame->dInfo.clientname_tag, 40);
cur_replay.ReadData(mainGame->dInfo.clientname, 40);
mainGame->dInfo.isTag = true;
mainGame->dInfo.tag_player[0] = false;
mainGame->dInfo.tag_player[1] = false;
} else {
cur_replay.ReadData(mainGame->dInfo.hostname, 40);
cur_replay.ReadData(mainGame->dInfo.clientname, 40);
}
set_script_reader(default_script_reader);
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)MessageHandler);
pduel = create_duel(rnd.rand());
int start_lp = cur_replay.ReadInt32();
int start_hand = cur_replay.ReadInt32();
int draw_count = cur_replay.ReadInt32();
int opt = cur_replay.ReadInt32();
int duel_rule = opt >> 16;
mainGame->dInfo.duel_rule = duel_rule;
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;
myswprintf(mainGame->dInfo.strLP[0], L"%d", mainGame->dInfo.lp[0]);
myswprintf(mainGame->dInfo.strLP[1], L"%d", mainGame->dInfo.lp[1]);
mainGame->dInfo.turn = 0;
if(!(opt & DUEL_TAG_MODE)) {
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(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(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(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(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);
}
start_duel(pduel, opt);
ReplayRefreshDeck(0);
ReplayRefreshDeck(1);
ReplayRefreshExtra(0);
ReplayRefreshExtra(1);
mainGame->dInfo.isStarted = true;
mainGame->dInfo.isReplay = true;
char engineBuffer[0x1000];
is_continuing = true;
exit_pending = false;
current_step = 0;
skip_step = 0;
if(skip_turn < 0)
skip_turn = 0;
if(skip_turn) {
mainGame->dInfo.isReplaySkiping = true;
mainGame->gMutex.Lock();
} else
mainGame->dInfo.isReplaySkiping = false;
int len = 0;
while (is_continuing && !exit_pending) {
int result = process(pduel);
len = result & 0xffff;
/*int flag = result >> 16;*/
if (len > 0) {
get_message(pduel, (byte*)engineBuffer);
is_continuing = ReplayAnalyze(engineBuffer, len);
}
}
if(mainGame->dInfo.isReplaySkiping) {
mainGame->dInfo.isReplaySkiping = false;
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
}
end_duel(pduel);
if(!is_closing) {
mainGame->actionSignal.Reset();
mainGame->gMutex.Lock();
mainGame->stMessage->setText(dataManager.GetSysString(1501));
if(mainGame->wCardSelect->isVisible())
mainGame->HideElement(mainGame->wCardSelect);
mainGame->PopupElement(mainGame->wMessage);
mainGame->gMutex.Unlock();
mainGame->actionSignal.Wait();
mainGame->gMutex.Lock();
mainGame->dInfo.isStarted = false;
mainGame->dInfo.isReplay = false;
mainGame->gMutex.Unlock();
mainGame->closeDoneSignal.Reset();
mainGame->closeSignal.Set();
mainGame->closeDoneSignal.Wait();
mainGame->gMutex.Lock();
mainGame->ShowElement(mainGame->wReplay);
mainGame->device->setEventReceiver(&mainGame->menuHandler);
mainGame->gMutex.Unlock();
if(exit_on_return)
mainGame->device->closeDevice();
}
return 0;
}
void ReplayMode::Restart(bool refresh) {
end_duel(pduel);
mainGame->dInfo.isStarted = false;
mainGame->dField.panel = 0;
mainGame->dField.hovered_card = 0;
mainGame->dField.clicked_card = 0;
mainGame->dField.Clear();
//mainGame->device->setEventReceiver(&mainGame->dField);
cur_replay.Rewind();
const ReplayHeader& rh = cur_replay.pheader;
//mainGame->dInfo.isFirst = true;
mtrandom rnd;
int seed = rh.seed;
rnd.reset(seed);
if(rh.flag & REPLAY_TAG) {
cur_replay.ReadData(mainGame->dInfo.hostname, 40);
cur_replay.ReadData(mainGame->dInfo.hostname_tag, 40);
cur_replay.ReadData(mainGame->dInfo.clientname_tag, 40);
cur_replay.ReadData(mainGame->dInfo.clientname, 40);
mainGame->dInfo.isTag = true;
mainGame->dInfo.tag_player[0] = false;
mainGame->dInfo.tag_player[1] = false;
} else {
cur_replay.ReadData(mainGame->dInfo.hostname, 40);
cur_replay.ReadData(mainGame->dInfo.clientname, 40);
}
//set_card_reader((card_reader)DataManager::CardReader);
//set_message_handler((message_handler)MessageHandler);
pduel = create_duel(rnd.rand());
int start_lp = cur_replay.ReadInt32();
int start_hand = cur_replay.ReadInt32();
int draw_count = cur_replay.ReadInt32();
int opt = cur_replay.ReadInt32();
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;
myswprintf(mainGame->dInfo.strLP[0], L"%d", mainGame->dInfo.lp[0]);
myswprintf(mainGame->dInfo.strLP[1], L"%d", mainGame->dInfo.lp[1]);
mainGame->dInfo.turn = 0;
if(!(opt & DUEL_TAG_MODE)) {
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(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(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(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(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);
}
start_duel(pduel, opt);
if(refresh) {
mainGame->dField.RefreshAllCards();
mainGame->dInfo.isStarted = true;
//mainGame->dInfo.isReplay = true;
}
skip_turn = 0;
is_restarting = true;
}
void ReplayMode::Undo() {
Restart(false);
skip_step = current_step - 1;
if(skip_step < 0)
skip_step = 0;
current_step = 0;
if(skip_step) {
mainGame->dInfo.isReplaySkiping = true;
mainGame->gMutex.Lock();
Pause(false, false);
} else
mainGame->dInfo.isReplaySkiping = false;
}
bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
char* pbuf = msg;
int player, count;
is_restarting = false;
while (pbuf - msg < (int)len) {
if(is_closing)
return false;
if(is_restarting) {
is_restarting = false;
return true;
}
if(is_swaping) {
mainGame->gMutex.Lock();
mainGame->dField.ReplaySwap();
mainGame->gMutex.Unlock();
is_swaping = false;
}
char* offset = pbuf;
bool pauseable = true;
mainGame->dInfo.curMsg = BufferIO::ReadUInt8(pbuf);
switch (mainGame->dInfo.curMsg) {
case MSG_RETRY: {
if(mainGame->dInfo.isReplaySkiping) {
mainGame->dInfo.isReplaySkiping = false;
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
}
mainGame->gMutex.Lock();
mainGame->stMessage->setText(L"Error occurs.");
mainGame->PopupElement(mainGame->wMessage);
mainGame->gMutex.Unlock();
mainGame->actionSignal.Reset();
mainGame->actionSignal.Wait();
return false;
}
case MSG_HINT: {
pbuf += 6;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_WIN: {
if(mainGame->dInfo.isReplaySkiping) {
mainGame->dInfo.isReplaySkiping = false;
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
}
pbuf += 2;
DuelClient::ClientAnalyze(offset, pbuf - offset);
return false;
}
case MSG_SELECT_BATTLECMD: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 11;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8 + 2;
ReplayRefresh();
return ReadReplayResponse();
}
case MSG_SELECT_IDLECMD: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 11 + 3;
ReplayRefresh();
return ReadReplayResponse();
}
case MSG_SELECT_EFFECTYN: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 8;
return ReadReplayResponse();
}
case MSG_SELECT_YESNO: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
return ReadReplayResponse();
}
case MSG_SELECT_OPTION: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
return ReadReplayResponse();
}
case MSG_SELECT_CARD:
case MSG_SELECT_TRIBUTE: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 3;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8;
return ReadReplayResponse();
}
case MSG_SELECT_UNSELECT_CARD: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8;
return ReadReplayResponse();
}
case MSG_SELECT_CHAIN: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += 10 + count * 13;
return ReadReplayResponse();
}
case MSG_SELECT_PLACE:
case MSG_SELECT_DISFIELD: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 5;
return ReadReplayResponse();
}
case MSG_SELECT_POSITION: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 5;
return ReadReplayResponse();
}
case MSG_SELECT_COUNTER: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 9;
return ReadReplayResponse();
}
case MSG_SELECT_SUM: {
pbuf++;
player = BufferIO::ReadInt8(pbuf);
pbuf += 6;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 11;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 11;
return ReadReplayResponse();
}
case MSG_SORT_CARD:
case MSG_SORT_CHAIN: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
return ReadReplayResponse();
}
case MSG_CONFIRM_DECKTOP: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CONFIRM_CARDS: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SHUFFLE_DECK: {
player = BufferIO::ReadInt8(pbuf);
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefreshDeck(player);
break;
}
case MSG_SHUFFLE_HAND: {
/*int oplayer = */BufferIO::ReadInt8(pbuf);
int count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_REFRESH_DECK: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SWAP_GRAVE_DECK: {
player = BufferIO::ReadInt8(pbuf);
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefreshGrave(player);
break;
}
case MSG_REVERSE_DECK: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefreshDeck(0);
ReplayRefreshDeck(1);
break;
}
case MSG_DECK_TOP: {
pbuf += 6;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SHUFFLE_SET_CARD: {
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_NEW_TURN: {
if(skip_turn) {
skip_turn--;
if(skip_turn == 0) {
mainGame->dInfo.isReplaySkiping = false;
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
}
}
player = BufferIO::ReadInt8(pbuf);
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_NEW_PHASE: {
pbuf += 2;
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefresh();
break;
}
case MSG_MOVE: {
int pc = pbuf[4];
int pl = pbuf[5];
/*int ps = pbuf[6];*/
/*int pp = pbuf[7];*/
int cc = pbuf[8];
int cl = pbuf[9];
int cs = pbuf[10];
/*int cp = pbuf[11];*/
pbuf += 16;
DuelClient::ClientAnalyze(offset, pbuf - offset);
if(cl && !(cl & 0x80) && (pl != cl || pc != cc))
ReplayRefreshSingle(cc, cl, cs);
break;
}
case MSG_POS_CHANGE: {
pbuf += 9;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SET: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_SWAP: {
pbuf += 16;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_FIELD_DISABLED: {
pbuf += 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_SUMMONING: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_SUMMONED: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefresh();
break;
}
case MSG_SPSUMMONING: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_SPSUMMONED: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefresh();
break;
}
case MSG_FLIPSUMMONING: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_FLIPSUMMONED: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefresh();
break;
}
case MSG_CHAINING: {
pbuf += 16;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CHAINED: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefresh();
break;
}
case MSG_CHAIN_SOLVING: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_CHAIN_SOLVED: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefresh();
pauseable = false;
break;
}
case MSG_CHAIN_END: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefresh();
pauseable = false;
break;
}
case MSG_CHAIN_NEGATED: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CHAIN_DISABLED: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CARD_SELECTED:
case MSG_RANDOM_SELECTED: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_BECOME_TARGET: {
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_DRAW: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_DAMAGE: {
pbuf += 5;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_RECOVER: {
pbuf += 5;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_EQUIP: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_LPUPDATE: {
pbuf += 5;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_UNEQUIP: {
pbuf += 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_CARD_TARGET: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_CANCEL_TARGET: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_PAY_LPCOST: {
pbuf += 5;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_ADD_COUNTER: {
pbuf += 7;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_REMOVE_COUNTER: {
pbuf += 7;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_ATTACK: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_BATTLE: {
pbuf += 26;
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_ATTACK_DISABLED: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
pauseable = false;
break;
}
case MSG_DAMAGE_STEP_START: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefresh();
pauseable = false;
break;
}
case MSG_DAMAGE_STEP_END: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefresh();
pauseable = false;
break;
}
case MSG_MISSED_EFFECT: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_TOSS_COIN: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_TOSS_DICE: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_ROCK_PAPER_SCISSORS: {
player = BufferIO::ReadInt8(pbuf);
return ReadReplayResponse();
}
case MSG_HAND_RES: {
pbuf += 1;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_ANNOUNCE_RACE: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 5;
return ReadReplayResponse();
}
case MSG_ANNOUNCE_ATTRIB: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 5;
return ReadReplayResponse();
}
case MSG_ANNOUNCE_CARD: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
return ReadReplayResponse();
}
case MSG_ANNOUNCE_NUMBER:
case MSG_ANNOUNCE_CARD_FILTER: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += 4 * count;
return ReadReplayResponse();
}
case MSG_CARD_HINT: {
pbuf += 9;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_PLAYER_HINT: {
pbuf += 6;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_MATCH_KILL: {
pbuf += 4;
break;
}
case MSG_TAG_SWAP: {
player = pbuf[0];
pbuf += pbuf[2] * 4 + pbuf[4] * 4 + 9;
DuelClient::ClientAnalyze(offset, pbuf - offset);
ReplayRefreshDeck(player);
ReplayRefreshExtra(player);
break;
}
}
if(pauseable) {
if(skip_step) {
skip_step--;
if(skip_step == 0) {
Pause(true, false);
mainGame->dInfo.isStarted = true;
mainGame->dInfo.isReplaySkiping = false;
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
}
}
if(is_pausing) {
is_paused = true;
mainGame->actionSignal.Reset();
mainGame->actionSignal.Wait();
is_paused = false;
}
current_step++;
}
}
return true;
}
void ReplayMode::ReplayRefresh(int flag) {
unsigned char queryBuffer[0x4000];
/*int len = */query_field_card(pduel, 0, LOCATION_MZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_MZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_MZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_MZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_SZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_SZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_SZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_SZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_HAND, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_HAND, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_HAND, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_HAND, (char*)queryBuffer);
}
void ReplayMode::ReplayRefreshHand(int player, int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_field_card(pduel, player, LOCATION_HAND, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(player), LOCATION_HAND, (char*)queryBuffer);
}
void ReplayMode::ReplayRefreshGrave(int player, int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_field_card(pduel, player, LOCATION_GRAVE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(player), LOCATION_GRAVE, (char*)queryBuffer);
}
void ReplayMode::ReplayRefreshDeck(int player, int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_field_card(pduel, player, LOCATION_DECK, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(player), LOCATION_DECK, (char*)queryBuffer);
}
void ReplayMode::ReplayRefreshExtra(int player, int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_field_card(pduel, player, LOCATION_EXTRA, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(player), LOCATION_EXTRA, (char*)queryBuffer);
}
void ReplayMode::ReplayRefreshSingle(int player, int location, int sequence, int flag) {
unsigned char queryBuffer[0x4000];
/*int len = */query_card(pduel, player, location, sequence, flag, queryBuffer, 0);
mainGame->dField.UpdateCard(mainGame->LocalPlayer(player), location, sequence, (char*)queryBuffer);
}
int ReplayMode::MessageHandler(long fduel, int type) {
if(!enable_log)
return 0;
char msgbuf[1024];
get_log_message(fduel, (byte*)msgbuf);
mainGame->AddDebugMsg(msgbuf);
return 0;
}
}
#include "single_mode.h"
#include "duelclient.h"
#include "game.h"
#include "../ocgcore/duel.h"
#include "../ocgcore/field.h"
#include "../ocgcore/mtrandom.h"
namespace ygo {
long SingleMode::pduel = 0;
bool SingleMode::is_closing = false;
bool SingleMode::is_continuing = false;
static byte buffer[0x20000];
bool SingleMode::StartPlay() {
Thread::NewThread(SinglePlayThread, 0);
return true;
}
void SingleMode::StopPlay(bool is_exiting) {
is_closing = is_exiting;
is_continuing = false;
mainGame->actionSignal.Set();
mainGame->singleSignal.Set();
}
void SingleMode::SetResponse(unsigned char* resp) {
if(!pduel)
return;
set_responseb(pduel, resp);
}
int SingleMode::SinglePlayThread(void* param) {
char fname2[256];
size_t slen;
if(open_file) {
slen = BufferIO::EncodeUTF8(open_file_name, fname2);
open_file = false;
} else {
const wchar_t* name = mainGame->lstSinglePlayList->getListItem(mainGame->lstSinglePlayList->getSelected());
wchar_t fname[256];
myswprintf(fname, L"./single/%ls", name);
slen = BufferIO::EncodeUTF8(fname, fname2);
}
mtrandom rnd;
time_t seed = time(0);
rnd.reset(seed);
set_script_reader((script_reader)ScriptReader);
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)MessageHandler);
pduel = create_duel(rnd.rand());
set_player_info(pduel, 0, 8000, 5, 1);
set_player_info(pduel, 1, 8000, 5, 1);
mainGame->dInfo.lp[0] = 8000;
mainGame->dInfo.lp[1] = 8000;
mainGame->dInfo.startlp = 8000;
myswprintf(mainGame->dInfo.strLP[0], L"%d", mainGame->dInfo.lp[0]);
myswprintf(mainGame->dInfo.strLP[1], L"%d", mainGame->dInfo.lp[1]);
BufferIO::CopyWStr(mainGame->ebNickName->getText(), mainGame->dInfo.hostname, 20);
mainGame->dInfo.clientname[0] = 0;
mainGame->dInfo.turn = 0;
if(!preload_script(pduel, fname2, slen)) {
wchar_t fname[256];
myswprintf(fname, L"./single/%ls", open_file_name);
slen = BufferIO::EncodeUTF8(fname, fname2);
if(!preload_script(pduel, fname2, slen)) {
end_duel(pduel);
return 0;
}
}
mainGame->gMutex.Lock();
mainGame->HideElement(mainGame->wSinglePlay);
mainGame->wCardImg->setVisible(true);
mainGame->wInfos->setVisible(true);
mainGame->btnLeaveGame->setVisible(true);
mainGame->btnLeaveGame->setText(dataManager.GetSysString(1210));
mainGame->stName->setText(L"");
mainGame->stInfo->setText(L"");
mainGame->stDataInfo->setText(L"");
mainGame->stSetName->setText(L"");
mainGame->stText->setText(L"");
mainGame->scrCardText->setVisible(false);
mainGame->wPhase->setVisible(true);
mainGame->dField.panel = 0;
mainGame->dField.hovered_card = 0;
mainGame->dField.clicked_card = 0;
mainGame->dField.Clear();
mainGame->dInfo.isFirst = true;
mainGame->dInfo.isStarted = true;
mainGame->dInfo.isSingleMode = true;
mainGame->device->setEventReceiver(&mainGame->dField);
mainGame->gMutex.Unlock();
start_duel(pduel, 0);
char engineBuffer[0x1000];
is_closing = false;
is_continuing = true;
int len = 0;
while (is_continuing) {
int result = process(pduel);
len = result & 0xffff;
/* int flag = result >> 16; */
if (len > 0) {
get_message(pduel, (byte*)engineBuffer);
is_continuing = SinglePlayAnalyze(engineBuffer, len);
}
}
end_duel(pduel);
if(!is_closing) {
mainGame->gMutex.Lock();
mainGame->dInfo.isStarted = false;
mainGame->dInfo.isSingleMode = false;
mainGame->gMutex.Unlock();
mainGame->closeDoneSignal.Reset();
mainGame->closeSignal.Set();
mainGame->closeDoneSignal.Wait();
mainGame->gMutex.Lock();
mainGame->ShowElement(mainGame->wSinglePlay);
mainGame->device->setEventReceiver(&mainGame->menuHandler);
mainGame->gMutex.Unlock();
if(exit_on_return)
mainGame->device->closeDevice();
}
return 0;
}
bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
char* offset, *pbuf = msg;
int player, count;
while (pbuf - msg < (int)len) {
if(is_closing || !is_continuing)
return false;
offset = pbuf;
mainGame->dInfo.curMsg = BufferIO::ReadUInt8(pbuf);
switch (mainGame->dInfo.curMsg) {
case MSG_RETRY: {
mainGame->gMutex.Lock();
mainGame->stMessage->setText(L"Error occurs.");
mainGame->PopupElement(mainGame->wMessage);
mainGame->gMutex.Unlock();
mainGame->actionSignal.Reset();
mainGame->actionSignal.Wait();
return false;
}
case MSG_HINT: {
/*int type = */BufferIO::ReadInt8(pbuf);
int player = BufferIO::ReadInt8(pbuf);
/*int data = */BufferIO::ReadInt32(pbuf);
if(player == 0)
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_WIN: {
pbuf += 2;
DuelClient::ClientAnalyze(offset, pbuf - offset);
return false;
}
case MSG_SELECT_BATTLECMD: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 11;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8 + 2;
SinglePlayRefresh();
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_IDLECMD: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 11 + 3;
SinglePlayRefresh();
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_EFFECTYN: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_YESNO: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_OPTION: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_CARD:
case MSG_SELECT_TRIBUTE: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 3;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_UNSELECT_CARD: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_CHAIN: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += 10 + count * 13;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_PLACE:
case MSG_SELECT_DISFIELD: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 5;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_POSITION: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 5;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_COUNTER: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 9;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_SUM: {
pbuf++;
player = BufferIO::ReadInt8(pbuf);
pbuf += 6;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 11;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 11;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SORT_CARD:
case MSG_SORT_CHAIN: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_CONFIRM_DECKTOP: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CONFIRM_CARDS: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SHUFFLE_DECK: {
player = BufferIO::ReadInt8(pbuf);
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefreshDeck(player);
break;
}
case MSG_SHUFFLE_HAND: {
/*int oplayer = */BufferIO::ReadInt8(pbuf);
int count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_REFRESH_DECK: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SWAP_GRAVE_DECK: {
player = BufferIO::ReadInt8(pbuf);
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefreshGrave(player);
break;
}
case MSG_REVERSE_DECK: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefreshDeck(0);
SinglePlayRefreshDeck(1);
break;
}
case MSG_DECK_TOP: {
pbuf += 6;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SHUFFLE_SET_CARD: {
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_NEW_TURN: {
player = BufferIO::ReadInt8(pbuf);
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_NEW_PHASE: {
pbuf += 2;
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefresh();
break;
}
case MSG_MOVE: {
int pc = pbuf[4];
int pl = pbuf[5];
/*int ps = pbuf[6];*/
/*int pp = pbuf[7];*/
int cc = pbuf[8];
int cl = pbuf[9];
int cs = pbuf[10];
/*int cp = pbuf[11];*/
pbuf += 16;
DuelClient::ClientAnalyze(offset, pbuf - offset);
if(cl && !(cl & 0x80) && (pl != cl || pc != cc))
SinglePlayRefreshSingle(cc, cl, cs);
break;
}
case MSG_POS_CHANGE: {
pbuf += 9;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SET: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SWAP: {
pbuf += 16;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_FIELD_DISABLED: {
pbuf += 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SUMMONING: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SUMMONED: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefresh();
break;
}
case MSG_SPSUMMONING: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SPSUMMONED: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefresh();
break;
}
case MSG_FLIPSUMMONING: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_FLIPSUMMONED: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefresh();
break;
}
case MSG_CHAINING: {
pbuf += 16;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CHAINED: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefresh();
break;
}
case MSG_CHAIN_SOLVING: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CHAIN_SOLVED: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefresh();
break;
}
case MSG_CHAIN_END: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefresh();
SinglePlayRefreshDeck(0);
SinglePlayRefreshDeck(1);
break;
}
case MSG_CHAIN_NEGATED: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CHAIN_DISABLED: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CARD_SELECTED:
case MSG_RANDOM_SELECTED: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_BECOME_TARGET: {
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_DRAW: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_DAMAGE: {
pbuf += 5;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_RECOVER: {
pbuf += 5;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_EQUIP: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_LPUPDATE: {
pbuf += 5;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_UNEQUIP: {
pbuf += 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CARD_TARGET: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CANCEL_TARGET: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_PAY_LPCOST: {
pbuf += 5;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_ADD_COUNTER: {
pbuf += 7;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_REMOVE_COUNTER: {
pbuf += 7;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_ATTACK: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_BATTLE: {
pbuf += 26;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_ATTACK_DISABLED: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_DAMAGE_STEP_START: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefresh();
break;
}
case MSG_DAMAGE_STEP_END: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefresh();
break;
}
case MSG_MISSED_EFFECT: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_TOSS_COIN: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_TOSS_DICE: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_ROCK_PAPER_SCISSORS: {
player = BufferIO::ReadInt8(pbuf);
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_HAND_RES: {
pbuf += 1;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_ANNOUNCE_RACE: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 5;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_ANNOUNCE_ATTRIB: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 5;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_ANNOUNCE_CARD: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_ANNOUNCE_NUMBER:
case MSG_ANNOUNCE_CARD_FILTER: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += 4 * count;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_CARD_HINT: {
pbuf += 9;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_PLAYER_HINT: {
pbuf += 6;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_TAG_SWAP: {
player = pbuf[0];
pbuf += pbuf[2] * 4 + pbuf[4] * 4 + 9;
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefreshDeck(player);
SinglePlayRefreshExtra(player);
break;
}
case MSG_MATCH_KILL: {
pbuf += 4;
break;
}
case MSG_RELOAD_FIELD: {
mainGame->gMutex.Lock();
mainGame->dField.Clear();
mainGame->dInfo.duel_rule = BufferIO::ReadInt8(pbuf);
// reset master rule 4 phase button position
if (mainGame->dInfo.duel_rule >= 4) {
mainGame->btnSP->setRelativePosition(mainGame->Resize(0, 0, 50, 20));
mainGame->btnM1->setRelativePosition(mainGame->Resize(160, 0, 210, 20));
mainGame->btnBP->setRelativePosition(mainGame->Resize(160, 0, 210, 20));
mainGame->btnM2->setRelativePosition(mainGame->Resize(160, 0, 210, 20));
} else {
mainGame->btnSP->setRelativePosition(mainGame->Resize(65, 0, 115, 20));
mainGame->btnM1->setRelativePosition(mainGame->Resize(130, 0, 180, 20));
mainGame->btnBP->setRelativePosition(mainGame->Resize(195, 0, 245, 20));
mainGame->btnM2->setRelativePosition(mainGame->Resize(260, 0, 310, 20));
}
int val = 0;
for(int p = 0; p < 2; ++p) {
mainGame->dInfo.lp[p] = BufferIO::ReadInt32(pbuf);
myswprintf(mainGame->dInfo.strLP[p], L"%d", mainGame->dInfo.lp[p]);
for(int seq = 0; seq < 7; ++seq) {
val = BufferIO::ReadInt8(pbuf);
if(val) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_MZONE, seq);
ccard->position = BufferIO::ReadInt8(pbuf);
val = BufferIO::ReadInt8(pbuf);
if(val) {
for(int xyz = 0; xyz < val; ++xyz) {
ClientCard* xcard = new ClientCard;
ccard->overlayed.push_back(xcard);
mainGame->dField.overlay_cards.insert(xcard);
xcard->overlayTarget = ccard;
xcard->location = 0x80;
xcard->sequence = ccard->overlayed.size() - 1;
}
}
}
}
for(int seq = 0; seq < 8; ++seq) {
val = BufferIO::ReadInt8(pbuf);
if(val) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_SZONE, seq);
ccard->position = BufferIO::ReadInt8(pbuf);
}
}
val = BufferIO::ReadInt8(pbuf);
for(int seq = 0; seq < val; ++seq) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_DECK, seq);
}
val = BufferIO::ReadInt8(pbuf);
for(int seq = 0; seq < val; ++seq) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_HAND, seq);
}
val = BufferIO::ReadInt8(pbuf);
for(int seq = 0; seq < val; ++seq) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_GRAVE, seq);
}
val = BufferIO::ReadInt8(pbuf);
for(int seq = 0; seq < val; ++seq) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_REMOVED, seq);
}
val = BufferIO::ReadInt8(pbuf);
for(int seq = 0; seq < val; ++seq) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_EXTRA, seq);
}
val = BufferIO::ReadInt8(pbuf);
mainGame->dField.extra_p_count[p] = val;
}
BufferIO::ReadInt8(pbuf); //chain count, always 0
SinglePlayReload();
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
break;
}
case MSG_AI_NAME: {
char namebuf[128];
wchar_t wname[128];
int len = BufferIO::ReadInt16(pbuf);
char* begin = pbuf;
pbuf += len + 1;
memcpy(namebuf, begin, len + 1);
BufferIO::DecodeUTF8(namebuf, wname);
BufferIO::CopyWStr(wname, mainGame->dInfo.clientname, 20);
break;
}
case MSG_SHOW_HINT: {
char msgbuf[1024];
wchar_t msg[1024];
int len = BufferIO::ReadInt16(pbuf);
char* begin = pbuf;
pbuf += len + 1;
memcpy(msgbuf, begin, len + 1);
BufferIO::DecodeUTF8(msgbuf, msg);
mainGame->gMutex.Lock();
mainGame->SetStaticText(mainGame->stMessage, 310, mainGame->textFont, msg);
mainGame->PopupElement(mainGame->wMessage);
mainGame->gMutex.Unlock();
mainGame->actionSignal.Reset();
mainGame->actionSignal.Wait();
break;
}
}
}
return is_continuing;
}
void SingleMode::SinglePlayRefresh(int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_field_card(pduel, 0, LOCATION_MZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_MZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_MZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_MZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_SZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_SZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_SZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_SZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_HAND, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_HAND, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_HAND, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_HAND, (char*)queryBuffer);
}
void SingleMode::SinglePlayRefreshHand(int player, int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_field_card(pduel, player, LOCATION_HAND, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(player), LOCATION_HAND, (char*)queryBuffer);
}
void SingleMode::SinglePlayRefreshGrave(int player, int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_field_card(pduel, player, LOCATION_GRAVE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(player), LOCATION_GRAVE, (char*)queryBuffer);
}
void SingleMode::SinglePlayRefreshDeck(int player, int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_field_card(pduel, player, LOCATION_DECK, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(player), LOCATION_DECK, (char*)queryBuffer);
}
void SingleMode::SinglePlayRefreshExtra(int player, int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_field_card(pduel, player, LOCATION_EXTRA, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(player), LOCATION_EXTRA, (char*)queryBuffer);
}
void SingleMode::SinglePlayRefreshSingle(int player, int location, int sequence, int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_card(pduel, player, location, sequence, flag, queryBuffer, 0);
mainGame->dField.UpdateCard(mainGame->LocalPlayer(player), location, sequence, (char*)queryBuffer);
}
void SingleMode::SinglePlayReload() {
unsigned char queryBuffer[0x2000];
unsigned int flag = 0xffdfff;
/*int len = */query_field_card(pduel, 0, LOCATION_MZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_MZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_MZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_MZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_SZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_SZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_SZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_SZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_HAND, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_HAND, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_HAND, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_HAND, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_DECK, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_DECK, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_DECK, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_DECK, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_EXTRA, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_EXTRA, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_EXTRA, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_EXTRA, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_GRAVE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_GRAVE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_GRAVE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_GRAVE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_REMOVED, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_REMOVED, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_REMOVED, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_REMOVED, (char*)queryBuffer);
}
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;
fseek(fp, 0, SEEK_END);
unsigned int len = ftell(fp);
if(len > sizeof(buffer)) {
fclose(fp);
return 0;
}
fseek(fp, 0, SEEK_SET);
fread(buffer, len, 1, fp);
fclose(fp);
*slen = len;
return buffer;
}
int SingleMode::MessageHandler(long fduel, int type) {
if(!enable_log)
return 0;
char msgbuf[1024];
get_log_message(fduel, (byte*)msgbuf);
mainGame->AddDebugMsg(msgbuf);
return 0;
}
}
#include "single_mode.h"
#include "duelclient.h"
#include "game.h"
#include "../ocgcore/duel.h"
#include "../ocgcore/field.h"
#include "../ocgcore/mtrandom.h"
namespace ygo {
long SingleMode::pduel = 0;
bool SingleMode::is_closing = false;
bool SingleMode::is_continuing = false;
static byte buffer[0x20000];
bool SingleMode::StartPlay() {
Thread::NewThread(SinglePlayThread, 0);
return true;
}
void SingleMode::StopPlay(bool is_exiting) {
is_closing = is_exiting;
is_continuing = false;
mainGame->actionSignal.Set();
mainGame->singleSignal.Set();
}
void SingleMode::SetResponse(unsigned char* resp) {
if(!pduel)
return;
set_responseb(pduel, resp);
}
int SingleMode::SinglePlayThread(void* param) {
char fname2[256];
size_t slen;
if(open_file) {
slen = BufferIO::EncodeUTF8(open_file_name, fname2);
open_file = false;
} else {
const wchar_t* name = mainGame->lstSinglePlayList->getListItem(mainGame->lstSinglePlayList->getSelected());
wchar_t fname[256];
myswprintf(fname, L"./single/%ls", name);
slen = BufferIO::EncodeUTF8(fname, fname2);
}
mtrandom rnd;
time_t seed = time(0);
rnd.reset(seed);
set_script_reader((script_reader)ScriptReader);
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)MessageHandler);
pduel = create_duel(rnd.rand());
set_player_info(pduel, 0, 8000, 5, 1);
set_player_info(pduel, 1, 8000, 5, 1);
mainGame->dInfo.lp[0] = 8000;
mainGame->dInfo.lp[1] = 8000;
mainGame->dInfo.startlp = 8000;
myswprintf(mainGame->dInfo.strLP[0], L"%d", mainGame->dInfo.lp[0]);
myswprintf(mainGame->dInfo.strLP[1], L"%d", mainGame->dInfo.lp[1]);
BufferIO::CopyWStr(mainGame->ebNickName->getText(), mainGame->dInfo.hostname, 20);
mainGame->dInfo.clientname[0] = 0;
mainGame->dInfo.turn = 0;
if(!preload_script(pduel, fname2, slen)) {
wchar_t fname[256];
myswprintf(fname, L"./single/%ls", open_file_name);
slen = BufferIO::EncodeUTF8(fname, fname2);
if(!preload_script(pduel, fname2, slen)) {
end_duel(pduel);
return 0;
}
}
mainGame->gMutex.Lock();
mainGame->HideElement(mainGame->wSinglePlay);
mainGame->wCardImg->setVisible(true);
mainGame->wInfos->setVisible(true);
mainGame->btnLeaveGame->setVisible(true);
mainGame->btnLeaveGame->setText(dataManager.GetSysString(1210));
mainGame->stName->setText(L"");
mainGame->stInfo->setText(L"");
mainGame->stDataInfo->setText(L"");
mainGame->stSetName->setText(L"");
mainGame->stText->setText(L"");
mainGame->scrCardText->setVisible(false);
mainGame->wPhase->setVisible(true);
mainGame->dField.panel = 0;
mainGame->dField.hovered_card = 0;
mainGame->dField.clicked_card = 0;
mainGame->dField.Clear();
mainGame->dInfo.isFirst = true;
mainGame->dInfo.isStarted = true;
mainGame->dInfo.isSingleMode = true;
mainGame->device->setEventReceiver(&mainGame->dField);
mainGame->gMutex.Unlock();
start_duel(pduel, 0);
char engineBuffer[0x1000];
is_closing = false;
is_continuing = true;
int len = 0;
while (is_continuing) {
int result = process(pduel);
len = result & 0xffff;
/* int flag = result >> 16; */
if (len > 0) {
get_message(pduel, (byte*)engineBuffer);
is_continuing = SinglePlayAnalyze(engineBuffer, len);
}
}
end_duel(pduel);
if(!is_closing) {
mainGame->gMutex.Lock();
mainGame->dInfo.isStarted = false;
mainGame->dInfo.isSingleMode = false;
mainGame->gMutex.Unlock();
mainGame->closeDoneSignal.Reset();
mainGame->closeSignal.Set();
mainGame->closeDoneSignal.Wait();
mainGame->gMutex.Lock();
mainGame->ShowElement(mainGame->wSinglePlay);
mainGame->device->setEventReceiver(&mainGame->menuHandler);
mainGame->gMutex.Unlock();
if(exit_on_return)
mainGame->device->closeDevice();
}
return 0;
}
bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
char* offset, *pbuf = msg;
int player, count;
while (pbuf - msg < (int)len) {
if(is_closing || !is_continuing)
return false;
offset = pbuf;
mainGame->dInfo.curMsg = BufferIO::ReadUInt8(pbuf);
switch (mainGame->dInfo.curMsg) {
case MSG_RETRY: {
mainGame->gMutex.Lock();
mainGame->stMessage->setText(L"Error occurs.");
mainGame->PopupElement(mainGame->wMessage);
mainGame->gMutex.Unlock();
mainGame->actionSignal.Reset();
mainGame->actionSignal.Wait();
return false;
}
case MSG_HINT: {
/*int type = */BufferIO::ReadInt8(pbuf);
int player = BufferIO::ReadInt8(pbuf);
/*int data = */BufferIO::ReadInt32(pbuf);
if(player == 0)
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_WIN: {
pbuf += 2;
DuelClient::ClientAnalyze(offset, pbuf - offset);
return false;
}
case MSG_SELECT_BATTLECMD: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 11;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8 + 2;
SinglePlayRefresh();
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_IDLECMD: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 11 + 3;
SinglePlayRefresh();
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_EFFECTYN: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_YESNO: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_OPTION: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_CARD:
case MSG_SELECT_TRIBUTE: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 3;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_UNSELECT_CARD: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_CHAIN: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += 10 + count * 13;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_PLACE:
case MSG_SELECT_DISFIELD: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 5;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_POSITION: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 5;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_COUNTER: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 9;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SELECT_SUM: {
pbuf++;
player = BufferIO::ReadInt8(pbuf);
pbuf += 6;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 11;
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 11;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_SORT_CARD:
case MSG_SORT_CHAIN: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_CONFIRM_DECKTOP: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CONFIRM_CARDS: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SHUFFLE_DECK: {
player = BufferIO::ReadInt8(pbuf);
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefreshDeck(player);
break;
}
case MSG_SHUFFLE_HAND: {
/*int oplayer = */BufferIO::ReadInt8(pbuf);
int count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_REFRESH_DECK: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SWAP_GRAVE_DECK: {
player = BufferIO::ReadInt8(pbuf);
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefreshGrave(player);
break;
}
case MSG_REVERSE_DECK: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefreshDeck(0);
SinglePlayRefreshDeck(1);
break;
}
case MSG_DECK_TOP: {
pbuf += 6;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SHUFFLE_SET_CARD: {
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_NEW_TURN: {
player = BufferIO::ReadInt8(pbuf);
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_NEW_PHASE: {
pbuf += 2;
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefresh();
break;
}
case MSG_MOVE: {
int pc = pbuf[4];
int pl = pbuf[5];
/*int ps = pbuf[6];*/
/*int pp = pbuf[7];*/
int cc = pbuf[8];
int cl = pbuf[9];
int cs = pbuf[10];
/*int cp = pbuf[11];*/
pbuf += 16;
DuelClient::ClientAnalyze(offset, pbuf - offset);
if(cl && !(cl & 0x80) && (pl != cl || pc != cc))
SinglePlayRefreshSingle(cc, cl, cs);
break;
}
case MSG_POS_CHANGE: {
pbuf += 9;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SET: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SWAP: {
pbuf += 16;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_FIELD_DISABLED: {
pbuf += 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SUMMONING: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SUMMONED: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefresh();
break;
}
case MSG_SPSUMMONING: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_SPSUMMONED: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefresh();
break;
}
case MSG_FLIPSUMMONING: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_FLIPSUMMONED: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefresh();
break;
}
case MSG_CHAINING: {
pbuf += 16;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CHAINED: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefresh();
break;
}
case MSG_CHAIN_SOLVING: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CHAIN_SOLVED: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefresh();
break;
}
case MSG_CHAIN_END: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefresh();
SinglePlayRefreshDeck(0);
SinglePlayRefreshDeck(1);
break;
}
case MSG_CHAIN_NEGATED: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CHAIN_DISABLED: {
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CARD_SELECTED:
case MSG_RANDOM_SELECTED: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_BECOME_TARGET: {
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_DRAW: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_DAMAGE: {
pbuf += 5;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_RECOVER: {
pbuf += 5;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_EQUIP: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_LPUPDATE: {
pbuf += 5;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_UNEQUIP: {
pbuf += 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CARD_TARGET: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CANCEL_TARGET: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_PAY_LPCOST: {
pbuf += 5;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_ADD_COUNTER: {
pbuf += 7;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_REMOVE_COUNTER: {
pbuf += 7;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_ATTACK: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_BATTLE: {
pbuf += 26;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_ATTACK_DISABLED: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_DAMAGE_STEP_START: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefresh();
break;
}
case MSG_DAMAGE_STEP_END: {
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefresh();
break;
}
case MSG_MISSED_EFFECT: {
pbuf += 8;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_TOSS_COIN: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_TOSS_DICE: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_ROCK_PAPER_SCISSORS: {
player = BufferIO::ReadInt8(pbuf);
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_HAND_RES: {
pbuf += 1;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_ANNOUNCE_RACE: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 5;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_ANNOUNCE_ATTRIB: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 5;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_ANNOUNCE_CARD: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_ANNOUNCE_NUMBER:
case MSG_ANNOUNCE_CARD_FILTER: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += 4 * count;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_CARD_HINT: {
pbuf += 9;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_PLAYER_HINT: {
pbuf += 6;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_TAG_SWAP: {
player = pbuf[0];
pbuf += pbuf[2] * 4 + pbuf[4] * 4 + 9;
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayRefreshDeck(player);
SinglePlayRefreshExtra(player);
break;
}
case MSG_MATCH_KILL: {
pbuf += 4;
break;
}
case MSG_RELOAD_FIELD: {
mainGame->gMutex.Lock();
mainGame->dField.Clear();
mainGame->dInfo.duel_rule = BufferIO::ReadInt8(pbuf);
int val = 0;
for(int p = 0; p < 2; ++p) {
mainGame->dInfo.lp[p] = BufferIO::ReadInt32(pbuf);
myswprintf(mainGame->dInfo.strLP[p], L"%d", mainGame->dInfo.lp[p]);
for(int seq = 0; seq < 7; ++seq) {
val = BufferIO::ReadInt8(pbuf);
if(val) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_MZONE, seq);
ccard->position = BufferIO::ReadInt8(pbuf);
val = BufferIO::ReadInt8(pbuf);
if(val) {
for(int xyz = 0; xyz < val; ++xyz) {
ClientCard* xcard = new ClientCard;
ccard->overlayed.push_back(xcard);
mainGame->dField.overlay_cards.insert(xcard);
xcard->overlayTarget = ccard;
xcard->location = 0x80;
xcard->sequence = ccard->overlayed.size() - 1;
}
}
}
}
for(int seq = 0; seq < 8; ++seq) {
val = BufferIO::ReadInt8(pbuf);
if(val) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_SZONE, seq);
ccard->position = BufferIO::ReadInt8(pbuf);
}
}
val = BufferIO::ReadInt8(pbuf);
for(int seq = 0; seq < val; ++seq) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_DECK, seq);
}
val = BufferIO::ReadInt8(pbuf);
for(int seq = 0; seq < val; ++seq) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_HAND, seq);
}
val = BufferIO::ReadInt8(pbuf);
for(int seq = 0; seq < val; ++seq) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_GRAVE, seq);
}
val = BufferIO::ReadInt8(pbuf);
for(int seq = 0; seq < val; ++seq) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_REMOVED, seq);
}
val = BufferIO::ReadInt8(pbuf);
for(int seq = 0; seq < val; ++seq) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_EXTRA, seq);
}
val = BufferIO::ReadInt8(pbuf);
mainGame->dField.extra_p_count[p] = val;
}
BufferIO::ReadInt8(pbuf); //chain count, always 0
SinglePlayReload();
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
break;
}
case MSG_AI_NAME: {
char namebuf[128];
wchar_t wname[128];
int len = BufferIO::ReadInt16(pbuf);
char* begin = pbuf;
pbuf += len + 1;
memcpy(namebuf, begin, len + 1);
BufferIO::DecodeUTF8(namebuf, wname);
BufferIO::CopyWStr(wname, mainGame->dInfo.clientname, 20);
break;
}
case MSG_SHOW_HINT: {
char msgbuf[1024];
wchar_t msg[1024];
int len = BufferIO::ReadInt16(pbuf);
char* begin = pbuf;
pbuf += len + 1;
memcpy(msgbuf, begin, len + 1);
BufferIO::DecodeUTF8(msgbuf, msg);
mainGame->gMutex.Lock();
mainGame->SetStaticText(mainGame->stMessage, 310, mainGame->textFont, msg);
mainGame->PopupElement(mainGame->wMessage);
mainGame->gMutex.Unlock();
mainGame->actionSignal.Reset();
mainGame->actionSignal.Wait();
break;
}
}
}
return is_continuing;
}
void SingleMode::SinglePlayRefresh(int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_field_card(pduel, 0, LOCATION_MZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_MZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_MZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_MZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_SZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_SZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_SZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_SZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_HAND, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_HAND, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_HAND, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_HAND, (char*)queryBuffer);
}
void SingleMode::SinglePlayRefreshHand(int player, int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_field_card(pduel, player, LOCATION_HAND, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(player), LOCATION_HAND, (char*)queryBuffer);
}
void SingleMode::SinglePlayRefreshGrave(int player, int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_field_card(pduel, player, LOCATION_GRAVE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(player), LOCATION_GRAVE, (char*)queryBuffer);
}
void SingleMode::SinglePlayRefreshDeck(int player, int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_field_card(pduel, player, LOCATION_DECK, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(player), LOCATION_DECK, (char*)queryBuffer);
}
void SingleMode::SinglePlayRefreshExtra(int player, int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_field_card(pduel, player, LOCATION_EXTRA, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(player), LOCATION_EXTRA, (char*)queryBuffer);
}
void SingleMode::SinglePlayRefreshSingle(int player, int location, int sequence, int flag) {
unsigned char queryBuffer[0x2000];
/*int len = */query_card(pduel, player, location, sequence, flag, queryBuffer, 0);
mainGame->dField.UpdateCard(mainGame->LocalPlayer(player), location, sequence, (char*)queryBuffer);
}
void SingleMode::SinglePlayReload() {
unsigned char queryBuffer[0x2000];
unsigned int flag = 0xffdfff;
/*int len = */query_field_card(pduel, 0, LOCATION_MZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_MZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_MZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_MZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_SZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_SZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_SZONE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_SZONE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_HAND, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_HAND, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_HAND, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_HAND, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_DECK, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_DECK, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_DECK, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_DECK, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_EXTRA, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_EXTRA, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_EXTRA, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_EXTRA, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_GRAVE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_GRAVE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_GRAVE, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_GRAVE, (char*)queryBuffer);
/*len = */query_field_card(pduel, 0, LOCATION_REMOVED, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(0), LOCATION_REMOVED, (char*)queryBuffer);
/*len = */query_field_card(pduel, 1, LOCATION_REMOVED, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_REMOVED, (char*)queryBuffer);
}
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;
fseek(fp, 0, SEEK_END);
unsigned int len = ftell(fp);
if(len > sizeof(buffer)) {
fclose(fp);
return 0;
}
fseek(fp, 0, SEEK_SET);
fread(buffer, len, 1, fp);
fclose(fp);
*slen = len;
return buffer;
}
int SingleMode::MessageHandler(long fduel, int type) {
if(!enable_log)
return 0;
char msgbuf[1024];
get_log_message(fduel, (byte*)msgbuf);
mainGame->AddDebugMsg(msgbuf);
return 0;
}
}
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