Commit 8fe09d34 authored by nanahira's avatar nanahira

Merge branch 'master' into inf_time

parents 9b11c2c1 e85398f4
......@@ -59,6 +59,7 @@
/sound/BGM
/update
/update*
/locales
# ygopro main program
/ygopro
......
......@@ -3,7 +3,7 @@ os:
- linux
- osx
sudo: required
dist: trusty
dist: xenial
osx_image: xcode8
addons:
ssh_known_hosts:
......@@ -16,17 +16,18 @@ addons:
- libirrlicht-dev
- libgl1-mesa-dev
- libglu-dev
- p7zip-full
env:
- USE_IRRKLANG=1
before_install:
- git submodule update --init --recursive
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
brew update > /dev/null;
brew install freetype libevent sqlite dylibbundler > /dev/null;
brew install freetype libevent sqlite p7zip dylibbundler > /dev/null;
fi
- curl --location --retry 5 http://www.lua.org/ftp/lua-5.3.4.tar.gz | tar zfx -
- cd lua-5.3.4
- curl --location --retry 5 http://www.lua.org/ftp/lua-5.3.5.tar.gz | tar zfx -
- cd lua-5.3.5
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
sudo make macosx test install > /dev/null;
fi
......@@ -48,10 +49,10 @@ before_install:
- mv -f irrklang/plugins/ikpmp3 .
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
sudo cp -rf irrklang/bin/macosx-gcc/libirrKlang.dylib /usr/local/lib/;
sudo cp -rf irrklang/bin/macosx-gcc/libirrklang.dylib /usr/local/lib/;
fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
cp -rf irrklang/bin/linux-gcc-64/libirrKlang.so .;
cp -rf irrklang/bin/linux-gcc-64/libIrrKlang.so .;
fi
script:
......@@ -81,41 +82,42 @@ script:
before_deploy:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
zip -q -r KoishiPro-$TRAVIS_OS_NAME-$TRAVIS_TAG.zip ygopro libirrKlang.so;
7z a -mx9 -xr!.git* KoishiPro-$TRAVIS_OS_NAME-$TRAVIS_TAG.zip ygopro libIrrKlang.so;
fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
zip -q -r KoishiPro-$TRAVIS_OS_NAME-$TRAVIS_TAG.zip ygopro.app;
7z a -mx9 -xr!.git* KoishiPro-$TRAVIS_OS_NAME-$TRAVIS_TAG.zip ygopro.app;
fi
- curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://github.com/HuangYuNan/ygopro222-images/archive/master.zip
- unzip -q ygopro222-images-master.zip
- 7z x -y ygopro222-images-master.zip > /dev/null
- mv -f ygopro222-images-master pics
- curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://github.com/moecube/ygopro-starter-pack/archive/master.zip
- unzip -q ygopro-starter-pack-master.zip
- 7z x -y ygopro-starter-pack-master.zip > /dev/null
- cp -rf ygopro-starter-pack-master/* .
- curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://github.com/purerosefallen/ygopro-222DIY-data/archive/master.zip
- rm -rf sound
- unzip -q ygopro-222DIY-data-master.zip
- mv -f ygopro-222DIY-data-master/sound .
- rm -rf sound/custom sound/BGM/custom
- rm -rf pics/thumbnail pics/*.db
- mkdir replay
- mkdir screenshots
- git clone --depth=1 https://$NANAHIRA@github.com/purerosefallen/fonts
- curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://github.com/purerosefallen/windbot/releases/download/latest/WindBot.7z
- 7z x -y WindBot.7z > /dev/null
- mv -f WindBot windbot
- curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://github.com/purerosefallen/windbot/raw/master/BotWrapper/BotWrapper.sh
- mv -f BotWrapper.sh bot
- cd sound
- bash -c "grep '.wav' files.txt | xargs -I {} curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://github.com/purerosefallen/ygopro-222DIY-data/raw/master/sound/{} ; exit 0"
- cd ..
- git clone --depth=1 https://github.com/purerosefallen/ygopro-database
- mv -f ygopro-database/locales .
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
sed -i "s/c:\/windows/./g" ./system.conf;
zip -q -r KoishiPro-$TRAVIS_OS_NAME-full-$TRAVIS_TAG.zip ygopro libirrKlang.so LICENSE README.md lflist.conf strings.conf system.conf cards.cdb script textures fonts skin deck single pics replay screenshots;
zip -q -r KoishiPro-$TRAVIS_OS_NAME-full-with-sound-$TRAVIS_TAG.zip ygopro libirrKlang.so LICENSE README.md lflist.conf strings.conf system.conf cards.cdb script textures fonts skin deck single pics replay sound screenshots;
7z a -mx9 -xr!.git* KoishiPro-$TRAVIS_OS_NAME-full-$TRAVIS_TAG.zip ygopro libIrrKlang.so LICENSE README.md lflist.conf strings.conf system.conf cards.cdb script textures fonts skin deck single pics sound windbot locales bot.conf bot > /dev/null;
fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
sed -i "" "s/c:\/windows/./g" ./system.conf;
zip -q -r KoishiPro-$TRAVIS_OS_NAME-full-$TRAVIS_TAG.zip ygopro.app LICENSE README.md lflist.conf strings.conf system.conf cards.cdb script textures fonts skin deck single pics replay screenshots;
zip -q -r KoishiPro-$TRAVIS_OS_NAME-full-with-sound-$TRAVIS_TAG.zip ygopro.app LICENSE README.md lflist.conf strings.conf system.conf cards.cdb script textures fonts skin deck single pics replay screenshots sound;
7z a -mx9 -xr!.git* KoishiPro-$TRAVIS_OS_NAME-full-$TRAVIS_TAG.zip ygopro.app LICENSE README.md lflist.conf strings.conf system.conf cards.cdb script textures fonts skin deck single pics sound windbot locales bot.conf bot > /dev/null;
fi
deploy:
......@@ -123,7 +125,6 @@ deploy:
file:
- KoishiPro-$TRAVIS_OS_NAME-$TRAVIS_TAG.zip
- KoishiPro-$TRAVIS_OS_NAME-full-$TRAVIS_TAG.zip
- KoishiPro-$TRAVIS_OS_NAME-full-with-sound-$TRAVIS_TAG.zip
skip_cleanup: true
overwrite: true
on:
......
......@@ -10,30 +10,30 @@ install:
# environment and system dependency
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://github.com/premake/premake-core/releases/download/v5.0.0-alpha12/premake-5.0.0-alpha12-windows.zip ; exit 0"
- 7z x premake-5.0.0-alpha12-windows.zip
- 7z x -y premake-5.0.0-alpha12-windows.zip
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://github.com/libevent/libevent/releases/download/release-2.0.22-stable/libevent-2.0.22-stable.tar.gz ; exit 0"
- tar xf libevent-2.0.22-stable.tar.gz
- move libevent-2.0.22-stable event
- xcopy /E event\WIN32-Code event\include
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name http://downloads.sourceforge.net/freetype/freetype-2.8.1.tar.bz2 ; exit 0"
- tar xf freetype-2.8.1.tar.bz2
- move freetype-2.8.1 freetype
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name http://downloads.sourceforge.net/freetype/freetype-2.9.1.tar.bz2 ; exit 0"
- tar xf freetype-2.9.1.tar.bz2
- move freetype-2.9.1 freetype
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name http://downloads.sourceforge.net/irrlicht/irrlicht-1.8.4.zip ; exit 0"
- 7z x irrlicht-1.8.4.zip
- 7z x -y irrlicht-1.8.4.zip
- md irrlicht
- move irrlicht-1.8.4\source\Irrlicht irrlicht\src
- move irrlicht-1.8.4\include irrlicht\include
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://www.lua.org/ftp/lua-5.3.4.tar.gz ; exit 0"
- tar xf lua-5.3.4.tar.gz
- move lua-5.3.4\src lua
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://www.lua.org/ftp/lua-5.3.5.tar.gz ; exit 0"
- tar xf lua-5.3.5.tar.gz
- move lua-5.3.5\src lua
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://www.sqlite.org/2017/sqlite-amalgamation-3210000.zip ; exit 0"
- 7z x sqlite-amalgamation-3210000.zip
- move sqlite-amalgamation-3210000 sqlite3
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://www.sqlite.org/2018/sqlite-amalgamation-3240000.zip ; exit 0"
- 7z x -y sqlite-amalgamation-3240000.zip
- move sqlite-amalgamation-3240000 sqlite3
- git clone --depth=1 https://%access_token%@github.com/purerosefallen/irrklang
- mv -f irrklang/plugins/ikpmp3 .
......@@ -56,41 +56,33 @@ build:
after_build:
- mv -f bin/release/ygopro.exe .
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://github.com/purerosefallen/windbot/archive/master.zip ; exit 0"
- 7z x windbot-master.zip
- cd windbot-master
- msbuild /property:Configuration=Release /property:Platform=x86
- rm -rf bin/Release/WindBot.exe.config
- mv -f bin/Release ../WindBot
- mv -f BotWrapper/bin/Release/Bot.exe ./..
- mv -f BotWrapper/bin/Release/Bot.conf ./..
- cd ..
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://github.com/purerosefallen/windbot/releases/download/latest/WindBot.7z ; exit 0"
- 7z x -y WindBot.7z
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://github.com/HuangYuNan/ygopro222-images/archive/master.zip ; exit 0"
- 7z x ygopro222-images-master.zip
- 7z x -y ygopro222-images-master.zip
- mv -f ygopro222-images-master pics
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://github.com/purerosefallen/update-koishipro/archive/master.zip ; exit 0"
- 7z x update-koishipro-master.zip
- 7z x -y update-koishipro-master.zip
- mv -f update-koishipro-master update-koishipro
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://github.com/moecube/ygopro-starter-pack/archive/master.zip ; exit 0"
- 7z x ygopro-starter-pack-master.zip
- 7z x -y ygopro-starter-pack-master.zip
- cp -rf ygopro-starter-pack-master/* .
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://github.com/purerosefallen/ygopro-222DIY-data/archive/master.zip ; exit 0"
- 7z x -y ygopro-222DIY-data-master.zip
- rm -rf sound
- mv -f ygopro-222DIY-data-master/sound .
- rm -rf sound/custom sound/BGM/custom
- cd sound
- bash -c "grep '.wav' files.txt | xargs -I {} curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://github.com/purerosefallen/ygopro-222DIY-data/raw/master/sound/{} ; exit 0"
- cd ..
- rm -rf pics/thumbnail pics/*.db
- mkdir replay
- mkdir screenshots
- 7z a -mx9 -xr!.git* KoishiPro-%APPVEYOR_REPO_TAG_NAME%.7z ygopro.exe LICENSE README.md lflist.conf strings.conf system.conf cards.cdb script textures skin deck single pics update-koishipro replay screenshots WindBot Bot.exe bot.conf
- cp -rf KoishiPro-%APPVEYOR_REPO_TAG_NAME%.7z KoishiPro-with-sound-%APPVEYOR_REPO_TAG_NAME%.7z
- 7z a -mx9 -xr!.git* KoishiPro-with-sound-%APPVEYOR_REPO_TAG_NAME%.7z sound
- git clone --depth=1 https://github.com/purerosefallen/ygopro-database
- mv -f ygopro-database/locales .
- git clone --depth=1 https://%access_token%@github.com/purerosefallen/fonts
- 7z a -mx9 -xr!.git* KoishiPro-%APPVEYOR_REPO_TAG_NAME%.7z ygopro.exe LICENSE README.md lflist.conf strings.conf system.conf cards.cdb script textures skin deck single pics sound update-koishipro locales fonts WindBot Bot.exe bot.conf
test: off
......@@ -107,13 +99,11 @@ artifacts:
name: ygopro client
- path: KoishiPro-$(APPVEYOR_REPO_TAG_NAME).7z
name: ygopro full repack
- path: KoishiPro-with-sound-$(APPVEYOR_REPO_TAG_NAME).7z
name: ygopro full repack with sound
cache:
- premake-5.0.0-alpha12-windows.zip
- libevent-2.0.22-stable.tar.gz
- freetype-2.8.1.tar.bz2
- freetype-2.9.1.tar.bz2
- irrlicht-1.8.4.zip
- lua-5.3.4.tar.gz
- sqlite-amalgamation-3210000.zip
- lua-5.3.5.tar.gz
- sqlite-amalgamation-3240000.zip
No preview for this file type
......@@ -60,7 +60,7 @@ public:
*pstr = 0;
return l;
}
// UCS-2 to UTF-8
// UTF-16/UTF-32 to UTF-8
static int EncodeUTF8(const wchar_t * wsrc, char * str) {
char* pstr = str;
while(*wsrc != 0) {
......@@ -71,18 +71,35 @@ public:
str[0] = ((*wsrc >> 6) & 0x1f) | 0xc0;
str[1] = ((*wsrc) & 0x3f) | 0x80;
str += 2;
} else {
} else if(*wsrc < 0x10000 && (*wsrc < 0xd800 || *wsrc > 0xdfff)) {
str[0] = ((*wsrc >> 12) & 0xf) | 0xe0;
str[1] = ((*wsrc >> 6) & 0x3f) | 0x80;
str[2] = ((*wsrc) & 0x3f) | 0x80;
str += 3;
} else {
#ifdef _WIN32
unsigned unicode = 0;
unicode |= (*wsrc++ & 0x3ff) << 10;
unicode |= *wsrc & 0x3ff;
unicode += 0x10000;
str[0] = ((unicode >> 18) & 0x7) | 0xf0;
str[1] = ((unicode >> 12) & 0x3f) | 0x80;
str[2] = ((unicode >> 6) & 0x3f) | 0x80;
str[3] = ((unicode) & 0x3f) | 0x80;
#else
str[0] = ((*wsrc >> 18) & 0x7) | 0xf0;
str[1] = ((*wsrc >> 12) & 0x3f) | 0x80;
str[2] = ((*wsrc >> 6) & 0x3f) | 0x80;
str[3] = ((*wsrc) & 0x3f) | 0x80;
#endif // _WIN32
str += 4;
}
wsrc++;
}
*str = 0;
return str - pstr;
}
// UTF-8 to UCS-2
// UTF-8 to UTF-16/UTF-32
static int DecodeUTF8(const char * src, wchar_t * wstr) {
const char* p = src;
wchar_t* wp = wstr;
......@@ -97,7 +114,14 @@ public:
*wp = (((unsigned)p[0] & 0xf) << 12) | (((unsigned)p[1] & 0x3f) << 6) | ((unsigned)p[2] & 0x3f);
p += 3;
} else if((*p & 0xf8) == 0xf0) {
#ifdef _WIN32
unsigned unicode = (((unsigned)p[0] & 0x7) << 18) | (((unsigned)p[1] & 0x3f) << 12) | (((unsigned)p[2] & 0x3f) << 6) | ((unsigned)p[3] & 0x3f);
unicode -= 0x10000;
*wp++ = (unicode >> 10) | 0xd800;
*wp = (unicode & 0x3ff) | 0xdc00;
#else
*wp = (((unsigned)p[0] & 0x7) << 18) | (((unsigned)p[1] & 0x3f) << 12) | (((unsigned)p[2] & 0x3f) << 6) | ((unsigned)p[3] & 0x3f);
#endif // _WIN32
p += 4;
} else
p++;
......
......@@ -38,6 +38,7 @@ ClientCard::ClientCard() {
lscale = 0;
rscale = 0;
link_marker = 0;
position = 0;
cHint = 0;
chValue = 0;
atkstring[0] = 0;
......@@ -70,8 +71,12 @@ void ClientCard::UpdateInfo(char* buf) {
code = pdata;
}
if(flag & QUERY_POSITION) {
pdata = BufferIO::ReadInt32(buf);
position = (pdata >> 24) & 0xff;
pdata = (BufferIO::ReadInt32(buf) >> 24) & 0xff;
if((location & (LOCATION_EXTRA | LOCATION_REMOVED)) && (u8)pdata != position) {
position = pdata;
mainGame->dField.MoveCard(this, 1);
} else
position = pdata;
}
if(flag & QUERY_ALIAS)
alias = BufferIO::ReadInt32(buf);
......
......@@ -4,6 +4,7 @@
#include "config.h"
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
namespace ygo {
......
......@@ -6,7 +6,7 @@
#include "image_manager.h"
#include "game.h"
#include "materials.h"
#include "../ocgcore/field.h"
#include "../ocgcore/common.h"
namespace ygo {
......@@ -383,6 +383,7 @@ void ClientField::ClearChainSelect() {
(*cit)->is_selected = false;
}
conti_cards.clear();
deck_act = false;
grave_act = false;
remove_act = false;
extra_act = false;
......@@ -407,7 +408,7 @@ void ClientField::ShowSelectCard(bool buttonok, bool chain) {
else if(conti_selecting)
mainGame->imageLoading.insert(std::make_pair(mainGame->btnCardSelect[i], selectable_cards[i]->chain_code));
else
mainGame->btnCardSelect[i]->setImage(imageManager.tCover[0]);
mainGame->btnCardSelect[i]->setImage(imageManager.tCover[selectable_cards[i]->controler + 2], rect<s32>(0, 0, CARD_IMG_WIDTH, CARD_IMG_HEIGHT));
mainGame->btnCardSelect[i]->setRelativePosition(rect<s32>(startpos + i * 125, 55, startpos + 120 + i * 125, 225));
mainGame->btnCardSelect[i]->setPressed(false);
mainGame->btnCardSelect[i]->setVisible(true);
......@@ -493,7 +494,7 @@ void ClientField::ShowChainCard() {
if(selectable_cards[i]->code)
mainGame->imageLoading.insert(std::make_pair(mainGame->btnCardSelect[i], selectable_cards[i]->code));
else
mainGame->btnCardSelect[i]->setImage(imageManager.tCover[0]);
mainGame->btnCardSelect[i]->setImage(imageManager.tCover[selectable_cards[i]->controler + 2], rect<s32>(0, 0, CARD_IMG_WIDTH, CARD_IMG_HEIGHT));
mainGame->btnCardSelect[i]->setRelativePosition(rect<s32>(startpos + i * 125, 55, startpos + 120 + i * 125, 225));
mainGame->btnCardSelect[i]->setPressed(false);
mainGame->btnCardSelect[i]->setVisible(true);
......@@ -548,7 +549,7 @@ void ClientField::ShowLocationCard() {
if(display_cards[i]->code)
mainGame->imageLoading.insert(std::make_pair(mainGame->btnCardDisplay[i], display_cards[i]->code));
else
mainGame->btnCardDisplay[i]->setImage(imageManager.tCover[0]);
mainGame->btnCardDisplay[i]->setImage(imageManager.tCover[display_cards[i]->controler + 2], rect<s32>(0, 0, CARD_IMG_WIDTH, CARD_IMG_HEIGHT));
mainGame->btnCardDisplay[i]->setRelativePosition(rect<s32>(startpos + i * 125, 55, startpos + 120 + i * 125, 225));
mainGame->btnCardDisplay[i]->setPressed(false);
mainGame->btnCardDisplay[i]->setVisible(true);
......@@ -600,6 +601,55 @@ void ClientField::ShowLocationCard() {
mainGame->btnDisplayOK->setVisible(true);
mainGame->PopupElement(mainGame->wCardDisplay);
}
void ClientField::ShowSelectOption(int select_hint) {
selected_option = 0;
wchar_t textBuffer[256];
int count = select_options.size();
bool quickmode = (count <= 5);
mainGame->gMutex.Lock();
for(int i = 0; (i < count) && quickmode; i++) {
const wchar_t* option = dataManager.GetDesc(select_options[i]);
irr::core::dimension2d<unsigned int> dtxt = mainGame->guiFont->getDimension(option);
if(dtxt.Width > 310) {
quickmode = false;
break;
}
mainGame->btnOption[i]->setText(option);
}
if(quickmode) {
mainGame->stOptions->setVisible(false);
mainGame->btnOptionp->setVisible(false);
mainGame->btnOptionn->setVisible(false);
mainGame->btnOptionOK->setVisible(false);
for(int i = 0; i < 5; i++)
mainGame->btnOption[i]->setVisible(i < count);
recti pos = mainGame->wOptions->getRelativePosition();
int newheight = 30 + 40 * count;
int oldheight = pos.LowerRightCorner.Y - pos.UpperLeftCorner.Y;
pos.UpperLeftCorner.Y = pos.UpperLeftCorner.Y + (oldheight - newheight) / 2;
pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + newheight;
mainGame->wOptions->setRelativePosition(pos);
} else {
mainGame->SetStaticText(mainGame->stOptions, 310, mainGame->guiFont,
(wchar_t*)dataManager.GetDesc(select_options[0]));
mainGame->stOptions->setVisible(true);
mainGame->btnOptionp->setVisible(false);
mainGame->btnOptionn->setVisible(count > 1);
mainGame->btnOptionOK->setVisible(true);
for(int i = 0; i < 5; i++)
mainGame->btnOption[i]->setVisible(false);
recti pos = mainGame->wOptions->getRelativePosition();
pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + 140;
mainGame->wOptions->setRelativePosition(pos);
}
if(select_hint)
myswprintf(textBuffer, L"%ls", dataManager.GetDesc(select_hint));
else
myswprintf(textBuffer, dataManager.GetSysString(555));
mainGame->wOptions->setText(textBuffer);
mainGame->PopupElement(mainGame->wOptions);
mainGame->gMutex.Unlock();
}
void ClientField::ReplaySwap() {
std::swap(deck[0], deck[1]);
std::swap(hand[0], hand[1]);
......@@ -1407,10 +1457,25 @@ void ClientField::UpdateDeclarableCodeType(bool enter) {
ancard.push_back(trycode);
return;
}
if((pname[0] == 0 || pname[1] == 0) && !enter)
bool try_cache = false;
if(pname[0] == 0 || pname[1] == 0) {
if(!enter)
return;
try_cache = true;
}
mainGame->lstANCard->clear();
ancard.clear();
if(try_cache && mainGame->dInfo.announce_cache.size()) {
for(int i = 0; i < mainGame->dInfo.announce_cache.size(); ++i) {
unsigned int cache_code = mainGame->dInfo.announce_cache[i];
if(dataManager.GetString(cache_code, &cstr) && dataManager.GetData(cache_code, &cd) && is_declarable(cd, declarable_type)) {
mainGame->lstANCard->addItem(cstr.name.c_str());
ancard.push_back(cache_code);
}
}
if(ancard.size())
return;
}
for(auto cit = dataManager._strings.begin(); cit != dataManager._strings.end(); ++cit) {
if(cit->second.name.find(pname) != std::wstring::npos) {
auto cp = dataManager.GetCodePointer(cit->first); //verified by _strings
......@@ -1439,10 +1504,25 @@ void ClientField::UpdateDeclarableCodeOpcode(bool enter) {
ancard.push_back(trycode);
return;
}
if((pname[0] == 0 || pname[1] == 0) && !enter)
bool try_cache = false;
if(pname[0] == 0 || pname[1] == 0) {
if(!enter)
return;
try_cache = true;
}
mainGame->lstANCard->clear();
ancard.clear();
if(try_cache && mainGame->dInfo.announce_cache.size()) {
for(int i = 0; i < mainGame->dInfo.announce_cache.size(); ++i) {
unsigned int cache_code = mainGame->dInfo.announce_cache[i];
if(dataManager.GetString(cache_code, &cstr) && dataManager.GetData(cache_code, &cd) && is_declarable(cd, opcode)) {
mainGame->lstANCard->addItem(cstr.name.c_str());
ancard.push_back(cache_code);
}
}
if(ancard.size())
return;
}
for(auto cit = dataManager._strings.begin(); cit != dataManager._strings.end(); ++cit) {
if(cit->second.name.find(pname) != std::wstring::npos) {
auto cp = dataManager.GetCodePointer(cit->first); //verified by _strings
......
......@@ -4,6 +4,7 @@
#include "config.h"
#include <vector>
#include <set>
#include <map>
namespace ygo {
......@@ -97,6 +98,7 @@ public:
void ShowSelectCard(bool buttonok = false, bool chain = false);
void ShowChainCard();
void ShowLocationCard();
void ShowSelectOption(int select_hint = 0);
void ReplaySwap();
void RefreshAllCards();
......@@ -140,6 +142,7 @@ public:
void ShowCancelOrFinishButton(int buttonOp);
void SetShowMark(ClientCard* pcard, bool enable);
void SetResponseSelectedCards() const;
void SetResponseSelectedOption() const;
void CancelOrFinish();
};
......
......@@ -12,11 +12,9 @@
#include <ws2tcpip.h>
#ifdef _MSC_VER
#define myswprintf _swprintf
#define mywcsncasecmp _wcsnicmp
#define mystrncasecmp _strnicmp
#else
#define myswprintf swprintf
#define mywcsncasecmp wcsncasecmp
#define mystrncasecmp strncasecmp
#endif
......@@ -44,7 +42,6 @@
#define SOCKET_ERRNO() (errno)
#include <wchar.h>
#define myswprintf(buf, fmt, ...) swprintf(buf, 4096, fmt, ##__VA_ARGS__)
#define mywcsncasecmp wcsncasecmp
#define mystrncasecmp strncasecmp
inline int _wtoi(const wchar_t * s) {
......@@ -53,6 +50,11 @@ inline int _wtoi(const wchar_t * s) {
}
#endif
template<size_t N, typename... TR>
inline int myswprintf(wchar_t(&buf)[N], const wchar_t* fmt, TR... args) {
return swprintf(buf, N, fmt, args...);
}
#include <irrlicht.h>
#ifdef __APPLE__
#include <OpenGL/gl.h>
......@@ -73,7 +75,7 @@ inline int _wtoi(const wchar_t * s) {
#include "mysignal.h"
#include "mythread.h"
#include "../ocgcore/ocgapi.h"
#include "../ocgcore/card.h"
#include "../ocgcore/common.h"
using namespace irr;
using namespace core;
......
......@@ -62,6 +62,7 @@ static bool check_set_code(const CardDataC& data, int set_code) {
void DeckBuilder::Initialize() {
mainGame->is_building = true;
mainGame->is_siding = false;
mainGame->ClearCardInfo();
mainGame->wInfos->setVisible(true);
mainGame->wCardImg->setVisible(true);
mainGame->wDeckEdit->setVisible(true);
......@@ -91,6 +92,7 @@ void DeckBuilder::Initialize() {
}
void DeckBuilder::Terminate() {
mainGame->is_building = false;
mainGame->ClearCardInfo();
mainGame->wDeckEdit->setVisible(false);
mainGame->wCategories->setVisible(false);
mainGame->wFilter->setVisible(false);
......@@ -275,8 +277,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
mainGame->env->addMessageBox(L"", dataManager.GetSysString(1410));
break;
}
mainGame->imgCard->setImage(imageManager.tCover[0]);
mainGame->showingcode = 0;
mainGame->ClearCardInfo();
char deckbuf[1024];
char* pdeck = deckbuf;
BufferIO::WriteInt32(pdeck, deckManager.current_deck.main.size() + deckManager.current_deck.extra.size());
......@@ -817,15 +818,6 @@ void DeckBuilder::StartFilter() {
void DeckBuilder::FilterCards() {
results.clear();
const wchar_t* pstr = mainGame->ebCardName->getText();
int trycode = BufferIO::GetVal(pstr);
if(dataManager.GetData(trycode, 0)) {
auto ptr = dataManager.GetCodePointer(trycode); // verified by GetData()
results.push_back(ptr);
mainGame->scrFilter->setVisible(false);
mainGame->scrFilter->setPos(0);
myswprintf(result_string, L"%d", results.size());
return;
}
std::wstring str = std::wstring(pstr);
std::vector<std::wstring> query_elements;
std::vector<std::vector<std::wstring>::iterator> query_elements_track;
......@@ -854,6 +846,13 @@ void DeckBuilder::FilterCards() {
}
for(auto elements_track_iterator = query_elements_track.begin(); elements_track_iterator != query_elements_track.end(); elements_track_iterator++)
query_elements.erase(*elements_track_iterator);
unsigned int set_code = 0;
if(pstr[0] == L'@')
set_code = dataManager.GetSetCode(&pstr[1]);
else
set_code = dataManager.GetSetCode(&pstr[0]);
if(pstr[0] == 0 || (pstr[0] == L'$' && pstr[1] == 0) || (pstr[0] == L'@' && pstr[1] == 0))
pstr = 0;
auto strpointer = dataManager._strings.begin();
for(code_pointer ptr = dataManager._datas.begin(); ptr != dataManager._datas.end(); ++ptr, ++strpointer) {
const CardDataC& data = ptr->second;
......@@ -942,11 +941,18 @@ void DeckBuilder::FilterCards() {
break;
}
} else {
if(!CardNameContains(text.name.c_str(), elements_iterator->c_str()) && text.text.find(elements_iterator->c_str()) == std::wstring::npos
int trycode = BufferIO::GetVal(elements_iterator->c_str());
bool tryresult = dataManager.GetData(trycode, 0);
if(!tryresult && !CardNameContains(text.name.c_str(), elements_iterator->c_str()) && text.text.find(elements_iterator->c_str()) == std::wstring::npos
&& (!set_code_map[*elements_iterator] || !check_set_code(data, set_code_map[*elements_iterator]))) {
is_target = false;
break;
}
if(tryresult && data.code != trycode
&& !(data.alias == trycode && (data.alias - data.code < CARD_ARTWORK_VERSIONS_OFFSET || data.code - data.alias < CARD_ARTWORK_VERSIONS_OFFSET))) {
is_target = false;
break;
}
}
}
if(is_target)
......
This diff is collapsed.
......@@ -4,11 +4,11 @@
#include "image_manager.h"
#include "sound_manager.h"
#include "single_mode.h"
#include "../ocgcore/field.h"
#include "../ocgcore/duel.h"
#include "../ocgcore/common.h"
#include "game.h"
#include "replay.h"
#include "replay_mode.h"
#include <algorithm>
namespace ygo {
......@@ -390,6 +390,7 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->wDeckEdit->setVisible(false);
mainGame->wFilter->setVisible(false);
mainGame->wSort->setVisible(false);
mainGame->stTip->setVisible(false);
mainGame->btnSideOK->setVisible(true);
mainGame->btnSideShuffle->setVisible(true);
mainGame->btnSideSort->setVisible(true);
......@@ -600,6 +601,7 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->RefreshTimeDisplay();
mainGame->dInfo.time_player = 2;
mainGame->dInfo.isReplaySwapped = false;
mainGame->dInfo.announce_cache.clear();
mainGame->is_building = false;
mainGame->wCardImg->setVisible(true);
mainGame->wInfos->setVisible(true);
......@@ -677,6 +679,7 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->gMutex.Lock();
mainGame->dInfo.isStarted = false;
mainGame->dInfo.isFinished = true;
mainGame->dInfo.announce_cache.clear();
mainGame->is_building = false;
mainGame->wDeckEdit->setVisible(false);
mainGame->btnCreateHost->setEnabled(true);
......@@ -1027,7 +1030,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
break;
}
//playing custom bgm
case HINT_MUSIC: {
case 11: { //HINT_MUSIC
char BGMName[1024];
if (data) {
myswprintf(textBuffer, L"./sound/BGM/custom/%ls.mp3", dataManager.GetDesc(data));
......@@ -1039,7 +1042,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
break;
}
//playing custom sound effect
case HINT_SOUND: {
case 12: { //HINT_SOUND
char SoundName[1024];
if (data) {
myswprintf(textBuffer, L"./sound/custom/%ls.wav", dataManager.GetDesc(data));
......@@ -1051,7 +1054,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
break;
}
//playing custom bgm in ogg format
case HINT_MUSIC_OGG: {
case 13: { //HINT_MUSIC_OGG
char BGMName[1024];
if (data) {
myswprintf(textBuffer, L"./sound/BGM/custom/%ls.ogg", dataManager.GetDesc(data));
......@@ -1399,21 +1402,8 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
mainGame->dField.select_options.clear();
for (int i = 0; i < count; ++i)
mainGame->dField.select_options.push_back(BufferIO::ReadInt32(pbuf));
mainGame->gMutex.Lock();
mainGame->SetStaticText(mainGame->stOptions, 310, mainGame->textFont,
(wchar_t*)dataManager.GetDesc(mainGame->dField.select_options[0]));
mainGame->btnOptionp->setVisible(false);
if(count > 1)
mainGame->btnOptionn->setVisible(true);
else mainGame->btnOptionn->setVisible(false);
mainGame->dField.selected_option = 0;
if(select_hint)
myswprintf(textBuffer, L"%ls", dataManager.GetDesc(select_hint));
else myswprintf(textBuffer, dataManager.GetSysString(555));
mainGame->dField.ShowSelectOption(select_hint);
select_hint = 0;
mainGame->wOptions->setText(textBuffer);
mainGame->PopupElement(mainGame->wOptions);
mainGame->gMutex.Unlock();
return false;
}
case MSG_SELECT_CARD: {
......@@ -1578,6 +1568,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
ClientCard* pcard;
bool panelmode = false;
bool conti_exist = false;
bool select_trigger = (specount == 0x7f);
mainGame->dField.chain_forced = (forced != 0);
mainGame->dField.activatable_cards.clear();
mainGame->dField.activatable_descs.clear();
......@@ -1605,7 +1596,10 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
pcard->cmdFlag |= COMMAND_RESET;
else
pcard->cmdFlag |= COMMAND_ACTIVATE;
if(l == LOCATION_GRAVE)
if(pcard->location == LOCATION_DECK) {
pcard->SetCode(code);
mainGame->dField.deck_act = true;
} else if(l == LOCATION_GRAVE)
mainGame->dField.grave_act = true;
else if(l == LOCATION_REMOVED)
mainGame->dField.remove_act = true;
......@@ -1615,7 +1609,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
panelmode = true;
}
}
if(!forced && (mainGame->ignore_chain || ((count == 0 || specount == 0) && !mainGame->always_chain)) && (count == 0 || !mainGame->chain_when_avail)) {
if(!select_trigger && !forced && (mainGame->ignore_chain || ((count == 0 || specount == 0) && !mainGame->always_chain)) && (count == 0 || !mainGame->chain_when_avail)) {
SetResponseI(-1);
mainGame->dField.ClearChainSelect();
if(mainGame->chkWaitChain->isChecked() && !mainGame->ignore_chain) {
......@@ -2356,11 +2350,9 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
mainGame->dInfo.is_swapped = !mainGame->dInfo.is_swapped;
return true;
}
if(!mainGame->dInfo.isTag && !mainGame->dInfo.isReplay && mainGame->dInfo.player_type < 7) {
if(!mainGame->dInfo.isReplay && mainGame->dInfo.player_type < 7) {
mainGame->btnLeaveGame->setText(dataManager.GetSysString(1351));
mainGame->btnLeaveGame->setVisible(true);
}
if(!mainGame->dInfo.isReplay && mainGame->dInfo.player_type < 7) {
if(mainGame->gameConf.control_mode == 0) {
mainGame->btnChainIgnore->setVisible(true);
mainGame->btnChainAlways->setVisible(true);
......@@ -2894,6 +2886,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
case MSG_CHAIN_DISABLED: {
int ct = BufferIO::ReadInt8(pbuf);
if(!mainGame->dInfo.isReplaySkiping) {
soundManager.PlaySoundEffect(SOUND_NEGATE);
mainGame->showcardcode = mainGame->dField.chains[ct - 1].code;
mainGame->showcarddif = 0;
mainGame->showcard = 3;
......@@ -3716,7 +3709,6 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_MZONE, seq);
ccard->position = BufferIO::ReadInt8(pbuf);
mainGame->dField.GetCardLocation(ccard, &ccard->curPos, &ccard->curRot, true);
val = BufferIO::ReadInt8(pbuf);
if(val) {
for(int xyz = 0; xyz < val; ++xyz) {
......@@ -3726,7 +3718,8 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
xcard->overlayTarget = ccard;
xcard->location = 0x80;
xcard->sequence = ccard->overlayed.size() - 1;
mainGame->dField.GetCardLocation(xcard, &xcard->curPos, &xcard->curRot, true);
xcard->owner = p;
xcard->controler = p;
}
}
}
......@@ -3737,49 +3730,39 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_SZONE, seq);
ccard->position = BufferIO::ReadInt8(pbuf);
mainGame->dField.GetCardLocation(ccard, &ccard->curPos, &ccard->curRot, true);
}
}
val = BufferIO::ReadInt8(pbuf);
for(int seq = 0; seq < val; ++seq) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_DECK, seq);
mainGame->dField.GetCardLocation(ccard, &ccard->curPos, &ccard->curRot, true);
}
val = BufferIO::ReadInt8(pbuf);
for(int seq = 0; seq < val; ++seq) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_HAND, seq);
}
// Use another loop to refresh the hand locations to prevent incorrect positioning
for (int seq = 0; seq < val; ++seq) {
ClientCard* ccard = mainGame->dField.hand[p][seq];
mainGame->dField.GetCardLocation(ccard, &ccard->curPos, &ccard->curRot, true);
}
val = BufferIO::ReadInt8(pbuf);
for(int seq = 0; seq < val; ++seq) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_GRAVE, seq);
mainGame->dField.GetCardLocation(ccard, &ccard->curPos, &ccard->curRot, true);
}
val = BufferIO::ReadInt8(pbuf);
for(int seq = 0; seq < val; ++seq) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_REMOVED, seq);
mainGame->dField.GetCardLocation(ccard, &ccard->curPos, &ccard->curRot, true);
}
val = BufferIO::ReadInt8(pbuf);
for(int seq = 0; seq < val; ++seq) {
ClientCard* ccard = new ClientCard;
mainGame->dField.AddCard(ccard, p, LOCATION_EXTRA, seq);
mainGame->dField.GetCardLocation(ccard, &ccard->curPos, &ccard->curRot, true);
}
val = BufferIO::ReadInt8(pbuf);
mainGame->dField.extra_p_count[p] = val;
}
val = BufferIO::ReadInt8(pbuf); //chains
mainGame->dField.RefreshAllCards();
val = BufferIO::ReadInt8(pbuf); //chains, always 0 in single mode
if(!mainGame->dInfo.isSingleMode) {
for(int i = 0; i < val; ++i) {
unsigned int code = (unsigned int)BufferIO::ReadInt32(pbuf);
int pcc = mainGame->LocalPlayer(BufferIO::ReadInt8(pbuf));
......@@ -3801,11 +3784,11 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
mainGame->dField.current_chain.solved = false;
int chc = 0;
for(auto chit = mainGame->dField.chains.begin(); chit != mainGame->dField.chains.end(); ++chit) {
if (cl == 0x10 || cl == 0x20) {
if (chit->controler == cc && chit->location == cl)
if(cl == 0x10 || cl == 0x20) {
if(chit->controler == cc && chit->location == cl)
chc++;
} else {
if (chit->controler == cc && chit->location == cl && chit->sequence == cs)
if(chit->controler == cc && chit->location == cl && chit->sequence == cs)
chc++;
}
}
......@@ -3819,6 +3802,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
myswprintf(event_string, dataManager.GetSysString(1609), dataManager.GetName(mainGame->dField.current_chain.code));
mainGame->dField.last_chain = true;
}
}
mainGame->gMutex.Unlock();
break;
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -26,6 +26,7 @@ struct Config {
wchar_t textfont[256];
wchar_t numfont[256];
wchar_t roompass[20];
wchar_t locale[64];
//settings
int chkMAutoPos;
int chkSTAutoPos;
......@@ -43,6 +44,7 @@ struct Config {
int chkIgnoreDeckChanges;
int defaultOT;
int enable_bot_mode;
int quick_animation;
bool window_maximized;
int window_width;
int window_height;
......@@ -88,6 +90,7 @@ struct DuelInfo {
wchar_t str_card_count[2][16];
video::SColor card_count_color[2];
bool isReplaySwapped;
std::vector<unsigned int> announce_cache;
};
struct BotInfo {
......@@ -124,10 +127,12 @@ public:
void RefreshReplay();
void RefreshSingleplay();
void RefreshBot();
void RefreshLocales();
void DrawSelectionLine(irr::video::S3DVertex* vec, bool strip, int width, float* cv);
void DrawSelectionLine(irr::gui::IGUIElement* element, int width, irr::video::SColor color);
void DrawBackGround();
void DrawLinkedZones(ClientCard* pcard);
void DrawSpellLinkedZones(ClientCard* pcard);
void CheckMutual(ClientCard* pcard, int mark);
void DrawCards();
void DrawCard(ClientCard* pcard);
......@@ -146,6 +151,7 @@ public:
void LoadConfig();
void SaveConfig();
void ShowCardInfo(int code, bool resize = false);
void ClearCardInfo(int player = 0);
void AddChatMsg(wchar_t* msg, int player);
void ClearChatMsg();
void AddDebugMsg(char* msgbuf);
......@@ -156,6 +162,7 @@ public:
int LocalPlayer(int player);
const wchar_t* LocalName(int local_player);
const char* GetLocaleDir(const char* dir);
bool HasFocus(EGUI_ELEMENT_TYPE type) const {
irr::gui::IGUIElement* focus = env->getFocus();
......@@ -177,6 +184,7 @@ public:
recti ResizeFit(s32 x, s32 y, s32 x2, s32 y2);
void SetWindowsIcon();
void SetWindowsScale(float scale);
void FlashWindow();
void takeScreenshot();
void SetCursor(ECURSOR_ICON icon);
......@@ -234,6 +242,7 @@ public:
float yScale;
CGUISkinSystem *skinSystem;
char locale_buf_utf8[256];
ClientField dField;
DeckBuilder deckBuilder;
......@@ -277,6 +286,7 @@ public:
irr::gui::IGUICheckBox* chkRandomPos;
irr::gui::IGUICheckBox* chkAutoChain;
irr::gui::IGUICheckBox* chkWaitChain;
irr::gui::IGUICheckBox* chkQuickAnimation;
irr::gui::IGUICheckBox* chkHideSetname;
irr::gui::IGUICheckBox* chkHideHintButton;
irr::gui::IGUICheckBox* chkIgnoreDeckChanges;
......@@ -286,7 +296,12 @@ public:
irr::gui::IGUIScrollBar* scrSoundVolume;
irr::gui::IGUIScrollBar* scrMusicVolume;
irr::gui::IGUICheckBox* chkMusicMode;
irr::gui::IGUIButton* btnWinResizeS;
irr::gui::IGUIButton* btnWinResizeM;
irr::gui::IGUIButton* btnWinResizeL;
irr::gui::IGUIButton* btnWinResizeXL;
irr::gui::IGUICheckBox* chkEnablePScale;
irr::gui::IGUIComboBox* cbLocale;
//main menu
irr::gui::IGUIWindow* wMainMenu;
irr::gui::IGUIButton* btnLanMode;
......@@ -344,6 +359,7 @@ public:
irr::gui::IGUIButton* btnDeleteReplay;
irr::gui::IGUIButton* btnRenameReplay;
irr::gui::IGUIButton* btnReplayCancel;
irr::gui::IGUIButton* btnExportDeck;
irr::gui::IGUIEditBox* ebRepStartTurn;
//single play
irr::gui::IGUIWindow* wSinglePlay;
......@@ -384,6 +400,7 @@ public:
irr::gui::IGUIButton* btnOptionp;
irr::gui::IGUIButton* btnOptionn;
irr::gui::IGUIButton* btnOptionOK;
irr::gui::IGUIButton* btnOption[5];
//pos selection
irr::gui::IGUIWindow* wPosSelect;
irr::gui::CGUIImageButton* btnPSAU;
......@@ -576,6 +593,7 @@ extern Game* mainGame;
#define BUTTON_CANCEL_REPLAY 132
#define BUTTON_DELETE_REPLAY 133
#define BUTTON_RENAME_REPLAY 134
#define BUTTON_EXPORT_DECK 135
#define EDITBOX_CHAT 140
#define BUTTON_MSG_OK 200
#define BUTTON_YES 201
......@@ -592,6 +610,11 @@ extern Game* mainGame;
#define BUTTON_OPTION_PREV 220
#define BUTTON_OPTION_NEXT 221
#define BUTTON_OPTION_OK 222
#define BUTTON_OPTION_0 223
#define BUTTON_OPTION_1 224
#define BUTTON_OPTION_2 225
#define BUTTON_OPTION_3 226
#define BUTTON_OPTION_4 227
#define BUTTON_CARD_0 230
#define BUTTON_CARD_1 231
#define BUTTON_CARD_2 232
......@@ -673,9 +696,15 @@ extern Game* mainGame;
#define CHECKBOX_ENABLE_MUSIC 362
#define SCROLL_VOLUME 363
#define CHECKBOX_DISABLE_CHAT 364
#define BUTTON_WINDOW_RESIZE_S 365
#define BUTTON_WINDOW_RESIZE_M 366
#define BUTTON_WINDOW_RESIZE_L 367
#define BUTTON_WINDOW_RESIZE_XL 368
#define CHECKBOX_QUICK_ANIMATION 369
#define COMBOBOX_SORTTYPE 370
#define COMBOBOX_LIMIT 371
#define COMBOBOX_LOCALE 372
#define BUTTON_MARKS_FILTER 380
#define BUTTON_MARKERS_OK 381
......@@ -693,4 +722,6 @@ extern Game* mainGame;
#define TEXTURE_ACTIVATE 6
#define DEFAULT_DUEL_RULE 4
#define CARD_ARTWORK_VERSIONS_OFFSET 10
#endif // GAME_H
......@@ -2,6 +2,7 @@
#include "game.h"
#include "data_manager.h"
#include <event2/thread.h>
#include <memory>
#ifdef __APPLE__
#import <CoreFoundation/CoreFoundation.h>
#endif
......@@ -12,22 +13,6 @@ bool open_file = false;
wchar_t open_file_name[256] = L"";
bool bot_mode = false;
void GetParameter(char* param, const char* arg) {
#ifdef _WIN32
wchar_t arg1[260];
MultiByteToWideChar(CP_ACP, 0, arg, -1, arg1, 260);
BufferIO::EncodeUTF8(arg1, param);
#else
strcpy(param, arg);
#endif
}
void GetParameterW(wchar_t* param, const char* arg) {
#ifdef _WIN32
MultiByteToWideChar(CP_ACP, 0, arg, -1, param, 260);
#else
BufferIO::DecodeUTF8(arg, param);
#endif
}
void ClickButton(irr::gui::IGUIElement* btn) {
irr::SEvent event;
event.EventType = irr::EET_GUI_EVENT;
......@@ -51,11 +36,15 @@ int main(int argc, char* argv[]) {
#endif //__APPLE__
#ifdef _WIN32
#ifndef _DEBUG
char* pstrext;
if(argc == 2 && (pstrext = strrchr(argv[1], '.'))
&& (!mystrncasecmp(pstrext, ".ydk", 4) || !mystrncasecmp(pstrext, ".yrp", 4))) {
wchar_t exepath[MAX_PATH];
GetModuleFileNameW(NULL, exepath, MAX_PATH);
wchar_t* p = wcsrchr(exepath, '\\');
*p = '\0';
SetCurrentDirectoryW(exepath);
}
#endif //_DEBUG
#endif //_WIN32
#ifdef _WIN32
......@@ -72,103 +61,116 @@ int main(int argc, char* argv[]) {
if(!ygo::mainGame->Initialize())
return 0;
#ifdef _WIN32
int wargc;
std::unique_ptr<wchar_t*[], void(*)(wchar_t**)> wargv(CommandLineToArgvW(GetCommandLineW(), &wargc), [](wchar_t** wargv) {
LocalFree(wargv);
});
#else
int wargc = argc;
auto wargv = std::make_unique<wchar_t[][256]>(wargc);
for(int i = 0; i < argc; ++i) {
BufferIO::DecodeUTF8(argv[i], wargv[i]);
}
#endif //_WIN32
bool keep_on_return = false;
for(int i = 1; i < argc; ++i) {
if(argv[i][0] == '-' && argv[i][1] == 'e') {
for(int i = 1; i < wargc; ++i) {
if(wargv[i][0] == L'-' && wargv[i][1] == L'e' && wargv[i][2] != L'\0') {
char param[128];
GetParameter(param, &argv[i][2]);
BufferIO::EncodeUTF8(&wargv[i][2], param);
ygo::dataManager.LoadDB(param);
continue;
}
if(!strcmp(argv[i], "-e")) { // extra database
if(!wcscmp(wargv[i], L"-e")) { // extra database
++i;
if(i < wargc) {
char param[128];
GetParameter(param, &argv[i][0]);
BufferIO::EncodeUTF8(wargv[i], param);
ygo::dataManager.LoadDB(param);
}
continue;
} else if(!strcmp(argv[i], "-n")) { // nickName
} else if(!wcscmp(wargv[i], L"-n")) { // nickName
++i;
wchar_t param[128];
GetParameterW(param, &argv[i][0]);
ygo::mainGame->ebNickName->setText(param);
if(i < wargc)
ygo::mainGame->ebNickName->setText(wargv[i]);
continue;
} else if(!strcmp(argv[i], "-h")) { // Host address
} else if(!wcscmp(wargv[i], L"-h")) { // Host address
++i;
wchar_t param[128];
GetParameterW(param, &argv[i][0]);
ygo::mainGame->ebJoinHost->setText(param);
if(i < wargc)
ygo::mainGame->ebJoinHost->setText(wargv[i]);
continue;
} else if(!strcmp(argv[i], "-p")) { // host Port
} else if(!wcscmp(wargv[i], L"-p")) { // host Port
++i;
wchar_t param[128];
GetParameterW(param, &argv[i][0]);
ygo::mainGame->ebJoinPort->setText(param);
if(i < wargc)
ygo::mainGame->ebJoinPort->setText(wargv[i]);
continue;
} else if(!strcmp(argv[i], "-w")) { // host passWord
} else if(!wcscmp(wargv[i], L"-w")) { // host passWord
++i;
wchar_t param[128];
GetParameterW(param, &argv[i][0]);
ygo::mainGame->ebJoinPass->setText(param);
if(i < wargc)
ygo::mainGame->ebJoinPass->setText(wargv[i]);
continue;
} else if(!strcmp(argv[i], "-k")) { // Keep on return
} else if(!wcscmp(wargv[i], L"-k")) { // Keep on return
exit_on_return = false;
keep_on_return = true;
} else if(!strcmp(argv[i], "-d")) { // Deck
if(i + 2 < argc) { // select deck
} else if(!wcscmp(wargv[i], L"-d")) { // Deck
++i;
GetParameterW(ygo::mainGame->gameConf.lastdeck, &argv[i][0]);
if(i + 1 < wargc) { // select deck
wcscpy(ygo::mainGame->gameConf.lastdeck, wargv[i]);
continue;
} else { // open deck
exit_on_return = !keep_on_return;
if(i < argc) {
if(i < wargc) {
open_file = true;
GetParameterW(open_file_name, &argv[i + 1][0]);
wcscpy(open_file_name, wargv[i]);
}
ClickButton(ygo::mainGame->btnDeckEdit);
break;
}
} else if(!strcmp(argv[i], "-c")) { // Create host
} else if(!wcscmp(wargv[i], L"-c")) { // Create host
exit_on_return = !keep_on_return;
ygo::mainGame->HideElement(ygo::mainGame->wMainMenu);
ClickButton(ygo::mainGame->btnHostConfirm);
break;
} else if(!strcmp(argv[i], "-j")) { // Join host
} else if(!wcscmp(wargv[i], L"-j")) { // Join host
exit_on_return = !keep_on_return;
ClickButton(ygo::mainGame->btnLanMode);
ygo::mainGame->HideElement(ygo::mainGame->wMainMenu);
ClickButton(ygo::mainGame->btnJoinHost);
break;
} else if(!strcmp(argv[i], "-r")) { // Replay
} else if(!wcscmp(wargv[i], L"-r")) { // Replay
exit_on_return = !keep_on_return;
if(i < argc) {
++i;
if(i < wargc) {
open_file = true;
GetParameterW(open_file_name, &argv[i + 1][0]);
wcscpy(open_file_name, wargv[i]);
}
ClickButton(ygo::mainGame->btnReplayMode);
if(open_file)
ClickButton(ygo::mainGame->btnLoadReplay);
break;
} else if(!strcmp(argv[i], "-s")) { // Single
} else if(!wcscmp(wargv[i], L"-s")) { // Single
exit_on_return = !keep_on_return;
if(i < argc) {
++i;
if(i < wargc) {
open_file = true;
GetParameterW(open_file_name, &argv[i + 1][0]);
wcscpy(open_file_name, wargv[i]);
}
ClickButton(ygo::mainGame->btnSingleMode);
if(open_file)
ClickButton(ygo::mainGame->btnLoadSinglePlay);
break;
} else if(argc == 2 && strlen(argv[1]) >= 4) {
char* pstrext = argv[1] + strlen(argv[1]) - 4;
if(!mystrncasecmp(pstrext, ".ydk", 4)) {
} else if(wargc == 2 && wcslen(wargv[1]) >= 4) {
wchar_t* pstrext = wargv[1] + wcslen(wargv[1]) - 4;
if(!mywcsncasecmp(pstrext, L".ydk", 4)) {
open_file = true;
GetParameterW(open_file_name, &argv[1][0]);
wcscpy(open_file_name, wargv[i]);
exit_on_return = !keep_on_return;
ClickButton(ygo::mainGame->btnDeckEdit);
break;
}
if(!mystrncasecmp(pstrext, ".yrp", 4)) {
if(!mywcsncasecmp(pstrext, L".yrp", 4)) {
open_file = true;
GetParameterW(open_file_name, &argv[1][0]);
wcscpy(open_file_name, wargv[i]);
exit_on_return = !keep_on_return;
ClickButton(ygo::mainGame->btnReplayMode);
ClickButton(ygo::mainGame->btnLoadReplay);
......
This diff is collapsed.
......@@ -10,15 +10,19 @@ namespace ygo {
class ImageManager {
public:
std::vector<std::wstring> ImageList[7];
int saved_image_id[7];
bool Initial();
//random image
irr::video::ITexture* GetRandomImage(int image_type);
irr::video::ITexture* GetRandomImage(int image_type, s32 width, s32 height);
void RefreshRandomImageList();
void RefreshImageDir(std::wstring path, int image_type);
void SetDevice(irr::IrrlichtDevice* dev);
void ClearTexture();
void RemoveTexture(int code);
void ResizeTexture();
irr::video::ITexture* GetTextureFromFile(char* file, s32 width, s32 height);
irr::video::ITexture* GetTextureUnknown(s32 width, s32 height, int index);
irr::video::ITexture* GetTexture(int code, bool fit = false);
irr::video::ITexture* GetTextureThumb(int code);
irr::video::ITexture* GetTextureField(int code);
......@@ -28,8 +32,8 @@ public:
std::unordered_map<int, irr::video::ITexture*> tFields;
irr::IrrlichtDevice* device;
irr::video::IVideoDriver* driver;
irr::video::ITexture* tCover[2];
irr::video::ITexture* tUnknown;
irr::video::ITexture* tCover[4];
irr::video::ITexture* tUnknown[3];
irr::video::ITexture* tAct;
irr::video::ITexture* tAttack;
irr::video::ITexture* tNegated;
......@@ -47,6 +51,7 @@ public:
irr::video::ITexture* tBackGround;
irr::video::ITexture* tBackGround_menu;
irr::video::ITexture* tBackGround_deck;
irr::video::ITexture* tCardType;
irr::video::ITexture* tField[2];
irr::video::ITexture* tFieldTransparent[2];
irr::video::ITexture* tRScale[14];
......
......@@ -222,17 +222,10 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
if(!ReplayMode::cur_replay.OpenReplay(mainGame->lstReplayList->getListItem(mainGame->lstReplayList->getSelected())))
break;
}
mainGame->imgCard->setImage(imageManager.tCover[0]);
mainGame->showingcode = 0;
mainGame->ClearCardInfo();
mainGame->wCardImg->setVisible(true);
mainGame->wInfos->setVisible(true);
mainGame->wReplay->setVisible(true);
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->wReplayControl->setVisible(true);
mainGame->btnReplayStart->setVisible(false);
mainGame->btnReplayPause->setVisible(true);
......@@ -280,6 +273,42 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
mainGame->ShowElement(mainGame->wMainMenu);
break;
}
case BUTTON_EXPORT_DECK: {
if(mainGame->lstReplayList->getSelected() == -1)
break;
Replay replay;
wchar_t ex_filename[256];
wchar_t namebuf[4][20];
wchar_t filename[256];
myswprintf(ex_filename, L"%ls", mainGame->lstReplayList->getListItem(mainGame->lstReplayList->getSelected()));
if(!replay.OpenReplay(ex_filename))
break;
const ReplayHeader& rh = replay.pheader;
if(rh.flag & REPLAY_SINGLE_MODE)
break;
int max = (rh.flag & REPLAY_TAG) ? 4 : 2;
//player name
for(int i = 0; i < max; ++i)
replay.ReadName(namebuf[i]);
//skip pre infos
for(int i = 0; i < 4; ++i)
replay.ReadInt32();
//deck
for(int i = 0; i < max; ++i) {
int main = replay.ReadInt32();
Deck tmp_deck;
for(int j = 0; j < main; ++j)
tmp_deck.main.push_back(dataManager.GetCodePointer(replay.ReadInt32()));
int extra = replay.ReadInt32();
for(int j = 0; j < extra; ++j)
tmp_deck.extra.push_back(dataManager.GetCodePointer(replay.ReadInt32()));
myswprintf(filename, L"%ls %ls", ex_filename, namebuf[i]);
deckManager.SaveDeck(tmp_deck, filename);
}
mainGame->stACMessage->setText(dataManager.GetSysString(1335));
mainGame->PopupElement(mainGame->wACMessage, 20);
break;
}
case BUTTON_BOT_START: {
int sel = mainGame->lstBotList->getSelected();
if(sel == -1)
......
......@@ -9,7 +9,7 @@ project "ygopro"
links { "ocgcore", "clzma", "Irrlicht", "freetype", "sqlite3", "lua" , "event" }
if USE_IRRKLANG then
defines { "YGOPRO_USE_IRRKLANG" }
links { "irrKlang", "ikpmp3" }
links { "ikpmp3" }
includedirs { "../irrklang/include" }
if IRRKLANG_PRO then
defines { "IRRKLANG_STATIC" }
......@@ -24,19 +24,26 @@ project "ygopro"
excludes "CGUIButton.cpp"
includedirs { "../irrlicht/include", "../freetype/include", "../event/include", "../sqlite3" }
if USE_IRRKLANG then
links { "irrKlang" }
libdirs { "../irrklang/lib/Win32-visualStudio" }
end
links { "opengl32", "ws2_32", "winmm", "gdi32", "kernel32", "user32", "imm32" }
configuration {"windows", "not vs*"}
includedirs { "/mingw/include/irrlicht", "/mingw/include/freetype2" }
configuration "not vs*"
buildoptions { "-std=gnu++0x", "-fno-rtti" }
buildoptions { "-std=c++14", "-fno-rtti" }
configuration "not windows"
includedirs { "/usr/include/lua", "/usr/include/lua5.3", "/usr/include/lua/5.3", "/usr/include/irrlicht", "/usr/include/freetype2" }
excludes { "COSOperator.*" }
links { "event_pthreads", "GL", "dl", "pthread" }
configuration "linux"
if USE_IRRKLANG then
links { "IrrKlang" }
linkoptions{ "-Wl,-rpath=./" }
libdirs { "../irrklang/bin/linux-gcc-64" }
end
configuration "macosx"
if USE_IRRKLANG then
links { "irrklang" }
libdirs { "../irrklang/bin/macosx-gcc" }
end
#include "replay.h"
#include "../ocgcore/ocgapi.h"
#include "../ocgcore/card.h"
#include "../ocgcore/common.h"
#include <algorithm>
#include "lzma/LzmaLib.h"
......@@ -159,7 +159,10 @@ bool Replay::OpenReplay(const wchar_t* name) {
}
if(!fp)
return false;
fread(&pheader, sizeof(pheader), 1, fp);
if(fread(&pheader, sizeof(pheader), 1, fp) < 1) {
fclose(fp);
return false;
}
if(pheader.flag & REPLAY_COMPRESSED) {
comp_size = fread(comp_data, 1, 0x1000, fp);
fclose(fp);
......@@ -188,9 +191,9 @@ bool Replay::CheckReplay(const wchar_t* name) {
if(!rfp)
return false;
ReplayHeader rheader;
fread(&rheader, sizeof(ReplayHeader), 1, rfp);
size_t count = fread(&rheader, sizeof(ReplayHeader), 1, rfp);
fclose(rfp);
return rheader.id == 0x31707279 && rheader.version >= 0x12d0;
return count == 1 && rheader.id == 0x31707279 && rheader.version >= 0x12d0;
}
bool Replay::DeleteReplay(const wchar_t* name) {
wchar_t fname[256];
......
......@@ -2,8 +2,7 @@
#include "duelclient.h"
#include "game.h"
#include "single_mode.h"
#include "../ocgcore/duel.h"
#include "../ocgcore/field.h"
#include "../ocgcore/common.h"
#include "../ocgcore/mtrandom.h"
namespace ygo {
......@@ -65,11 +64,11 @@ int ReplayMode::ReplayThread(void* param) {
mainGame->dInfo.tag_player[0] = false;
mainGame->dInfo.tag_player[1] = false;
if(mainGame->dInfo.isSingleMode) {
set_script_reader((script_reader)SingleMode::ScriptReader);
set_script_reader((script_reader)SingleMode::ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)MessageHandler);
} else {
set_script_reader(default_script_reader);
set_script_reader((script_reader)ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)MessageHandler);
}
......@@ -106,6 +105,7 @@ int ReplayMode::ReplayThread(void* param) {
get_message(pduel, (byte*)engineBuffer);
is_continuing = ReplayAnalyze(engineBuffer, len);
if(is_restarting) {
mainGame->gMutex.Lock();
is_restarting = false;
int step = current_step - 1;
if(step < 0)
......@@ -156,6 +156,8 @@ bool ReplayMode::StartDuel() {
cur_replay.ReadName(mainGame->dInfo.clientname);
}
pduel = create_duel(rnd.rand());
preload_script(pduel, "./script/special.lua", 0);
preload_script(pduel, "./script/init.lua", 0);
int start_lp = cur_replay.ReadInt32();
int start_hand = cur_replay.ReadInt32();
int draw_count = cur_replay.ReadInt32();
......@@ -220,7 +222,7 @@ bool ReplayMode::StartDuel() {
size_t slen = cur_replay.ReadInt16();
cur_replay.ReadData(filename, slen);
filename[slen] = 0;
if(!preload_script(pduel, filename, slen)) {
if(!preload_script(pduel, filename, 0)) {
return false;
}
}
......@@ -282,7 +284,6 @@ void ReplayMode::Undo() {
return;
mainGame->dInfo.isReplaySkiping = true;
Restart(false);
mainGame->gMutex.Lock();
Pause(false, false);
}
bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
......@@ -938,6 +939,25 @@ void ReplayMode::ReplayReload() {
/*len = */query_field_card(pduel, 1, LOCATION_REMOVED, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_REMOVED, (char*)queryBuffer);
}
byte* ReplayMode::ScriptReaderEx(const char* script_name, int* slen) {
char sname[256] = "./specials";
strcat(sname, script_name + 8);//default script name: ./script/c%d.lua
byte* buffer = default_script_reader(sname, slen);
if(!buffer) {
char sname[256] = "./expansions";
strcat(sname, script_name + 1);
buffer = default_script_reader(sname, slen);
}
if(!buffer) {
char sname[256] = "./beta";
strcat(sname, script_name + 1);
buffer = default_script_reader(sname, slen);
}
if(buffer)
return buffer;
else
return default_script_reader(script_name, slen);
}
int ReplayMode::MessageHandler(long fduel, int type) {
if(!enable_log)
return 0;
......
......@@ -47,6 +47,7 @@ public:
static void ReplayRefreshSingle(int player, int location, int sequence, int flag = 0xf81fff);
static void ReplayReload();
static byte* ScriptReaderEx(const char* script_name, int* slen);
static int MessageHandler(long fduel, int type);
};
......
......@@ -2,9 +2,7 @@
#include "netserver.h"
#include "game.h"
#include "../ocgcore/ocgapi.h"
#include "../ocgcore/card.h"
#include "../ocgcore/duel.h"
#include "../ocgcore/field.h"
#include "../ocgcore/common.h"
#include "../ocgcore/mtrandom.h"
namespace ygo {
......@@ -410,11 +408,13 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
}
time_limit[0] = host_info.time_limit;
time_limit[1] = host_info.time_limit;
set_script_reader(default_script_reader);
set_script_reader((script_reader)ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)SingleDuel::MessageHandler);
rnd.reset(seed);
pduel = create_duel(rnd.rand());
preload_script(pduel, "./script/special.lua", 0);
preload_script(pduel, "./script/init.lua", 0);
set_player_info(pduel, 0, host_info.start_lp, host_info.start_hand, host_info.draw_count);
set_player_info(pduel, 1, host_info.start_lp, host_info.start_hand, host_info.draw_count);
int opt = (int)host_info.duel_rule << 16;
......@@ -1552,6 +1552,25 @@ void SingleDuel::RefreshSingle(int player, int location, int sequence, int flag)
NetServer::ReSendToPlayer(*pit);
}
}
byte* SingleDuel::ScriptReaderEx(const char* script_name, int* slen) {
char sname[256] = "./specials";
strcat(sname, script_name + 8);//default script name: ./script/c%d.lua
byte* buffer = default_script_reader(sname, slen);
if(!buffer) {
char sname[256] = "./expansions";
strcat(sname, script_name + 1);
buffer = default_script_reader(sname, slen);
}
if(!buffer) {
char sname[256] = "./beta";
strcat(sname, script_name + 1);
buffer = default_script_reader(sname, slen);
}
if(buffer)
return buffer;
else
return default_script_reader(script_name, slen);
}
int SingleDuel::MessageHandler(long fduel, int type) {
if(!enable_log)
return 0;
......
......@@ -32,12 +32,13 @@ public:
void DuelEndProc();
void WaitforResponse(int playerid);
void RefreshMzone(int player, int flag = 0x881fff, int use_cache = 1);
void RefreshSzone(int player, int flag = 0x681fff, int use_cache = 1);
void RefreshSzone(int player, int flag = 0xe81fff, int use_cache = 1);
void RefreshHand(int player, int flag = 0x781fff, int use_cache = 1);
void RefreshGrave(int player, int flag = 0x81fff, int use_cache = 1);
void RefreshExtra(int player, int flag = 0x81fff, int use_cache = 1);
void RefreshSingle(int player, int location, int sequence, int flag = 0xf81fff);
static byte* ScriptReaderEx(const char* script_name, int* slen);
static int MessageHandler(long fduel, int type);
static void SingleTimer(evutil_socket_t fd, short events, void* arg);
......
#include "single_mode.h"
#include "duelclient.h"
#include "game.h"
#include "../ocgcore/duel.h"
#include "../ocgcore/field.h"
#include "../ocgcore/common.h"
#include "../ocgcore/mtrandom.h"
namespace ygo {
......@@ -39,10 +38,12 @@ int SingleMode::SinglePlayThread(void* param) {
mtrandom rnd;
time_t seed = time(0);
rnd.reset(seed);
set_script_reader((script_reader)ScriptReader);
set_script_reader((script_reader)ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)MessageHandler);
pduel = create_duel(rnd.rand());
preload_script(pduel, "./script/special.lua", 0);
preload_script(pduel, "./script/init.lua", 0);
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;
......@@ -53,17 +54,19 @@ int SingleMode::SinglePlayThread(void* param) {
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.player_type = 0;
mainGame->dInfo.turn = 0;
mainGame->dInfo.announce_cache.clear();
char filename[256];
size_t slen = 0;
if(open_file) {
open_file = false;
slen = BufferIO::EncodeUTF8(open_file_name, filename);
if(!preload_script(pduel, filename, slen)) {
if(!preload_script(pduel, filename, 0)) {
wchar_t fname[256];
myswprintf(fname, L"./single/%ls", open_file_name);
slen = BufferIO::EncodeUTF8(fname, filename);
if(!preload_script(pduel, filename, slen))
if(!preload_script(pduel, filename, 0))
slen = 0;
}
} else {
......@@ -71,7 +74,7 @@ int SingleMode::SinglePlayThread(void* param) {
wchar_t fname[256];
myswprintf(fname, L"./single/%ls", name);
slen = BufferIO::EncodeUTF8(fname, filename);
if(!preload_script(pduel, filename, slen))
if(!preload_script(pduel, filename, 0))
slen = 0;
}
if(slen == 0) {
......@@ -85,16 +88,11 @@ int SingleMode::SinglePlayThread(void* param) {
rh.seed = seed;
mainGame->gMutex.Lock();
mainGame->HideElement(mainGame->wSinglePlay);
mainGame->ClearCardInfo();
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.Clear();
mainGame->dInfo.isFirst = true;
......@@ -726,70 +724,25 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
break;
}
case MSG_RELOAD_FIELD: {
mainGame->gMutex.Lock();
mainGame->dField.Clear();
mainGame->dInfo.duel_rule = BufferIO::ReadInt8(pbuf);
int val = 0;
pbuf++;
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]);
pbuf += 4;
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;
}
int val = BufferIO::ReadInt8(pbuf);
if(val)
pbuf += 2;
}
for(int seq = 0; seq < 8; ++seq) {
int val = BufferIO::ReadInt8(pbuf);
if(val)
pbuf++;
}
pbuf += 6;
}
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
pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset);
SinglePlayReload();
mainGame->gMutex.Lock();
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
break;
......@@ -897,6 +850,25 @@ void SingleMode::SinglePlayReload() {
/*len = */query_field_card(pduel, 1, LOCATION_REMOVED, flag, queryBuffer, 0);
mainGame->dField.UpdateFieldCard(mainGame->LocalPlayer(1), LOCATION_REMOVED, (char*)queryBuffer);
}
byte* SingleMode::ScriptReaderEx(const char* script_name, int* slen) {
char sname[256] = "./specials";
strcat(sname, script_name + 8);//default script name: ./script/c%d.lua
byte* buffer = ScriptReader(sname, slen);
if(!buffer) {
char sname[256] = "./expansions";
strcat(sname, script_name + 1);
buffer = ScriptReader(sname, slen);
}
if(!buffer) {
char sname[256] = "./beta";
strcat(sname, script_name + 1);
buffer = ScriptReader(sname, slen);
}
if(buffer)
return buffer;
else
return ScriptReader(script_name, slen);
}
byte* SingleMode::ScriptReader(const char* script_name, int* slen) {
FILE *fp;
#ifdef _WIN32
......
......@@ -26,6 +26,7 @@ public:
static void SinglePlayRefreshSingle(int player, int location, int sequence, int flag = 0xf81fff);
static void SinglePlayReload();
static byte* ScriptReaderEx(const char* script_name, int* slen);
static byte* ScriptReader(const char* script_name, int* slen);
static int MessageHandler(long fduel, int type);
......
......@@ -126,6 +126,10 @@ void SoundManager::PlaySoundEffect(int sound) {
engineSound->play2D("./sound/token.wav");
break;
}
case SOUND_NEGATE: {
engineSound->play2D("./sound/negate.wav");
break;
}
case SOUND_ATTACK: {
engineSound->play2D("./sound/attack.wav");
break;
......
......@@ -48,6 +48,7 @@ extern SoundManager soundManager;
#define SOUND_DESTROYED 108
#define SOUND_BANISHED 109
#define SOUND_TOKEN 110
#define SOUND_NEGATE 111
#define SOUND_ATTACK 201
#define SOUND_DIRECT_ATTACK 202
......
......@@ -2,9 +2,7 @@
#include "netserver.h"
#include "game.h"
#include "../ocgcore/ocgapi.h"
#include "../ocgcore/card.h"
#include "../ocgcore/duel.h"
#include "../ocgcore/field.h"
#include "../ocgcore/common.h"
#include "../ocgcore/mtrandom.h"
namespace ygo {
......@@ -385,11 +383,13 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
}
time_limit[0] = host_info.time_limit;
time_limit[1] = host_info.time_limit;
set_script_reader(default_script_reader);
set_script_reader((script_reader)ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)TagDuel::MessageHandler);
rnd.reset(seed);
pduel = create_duel(rnd.rand());
preload_script(pduel, "./script/special.lua", 0);
preload_script(pduel, "./script/init.lua", 0);
set_player_info(pduel, 0, host_info.start_lp, host_info.start_hand, host_info.draw_count);
set_player_info(pduel, 1, host_info.start_lp, host_info.start_hand, host_info.draw_count);
int opt = (int)host_info.duel_rule << 16;
......@@ -498,7 +498,22 @@ void TagDuel::DuelEndProc() {
NetServer::StopServer();
}
void TagDuel::Surrender(DuelPlayer* dp) {
if(dp->type > 3 || !pduel)
return;
unsigned char wbuf[3];
uint32 player = (dp->type < 2) ? 0 : 1;
wbuf[0] = MSG_WIN;
wbuf[1] = 1 - player;
wbuf[2] = 0;
NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, wbuf, 3);
NetServer::ReSendToPlayer(players[1]);
NetServer::ReSendToPlayer(players[2]);
NetServer::ReSendToPlayer(players[3]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
EndDuel();
DuelEndProc();
event_del(etimer);
}
int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
char* offset, *pbufw, *pbuf = msgbuffer;
......@@ -1541,7 +1556,7 @@ void TagDuel::TimeConfirm(DuelPlayer* dp) {
event_add(etimer, &timeout);
}
void TagDuel::RefreshMzone(int player, int flag, int use_cache) {
char query_buffer[0x2000];
char query_buffer[0x4000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
......@@ -1567,7 +1582,7 @@ void TagDuel::RefreshMzone(int player, int flag, int use_cache) {
NetServer::ReSendToPlayer(*pit);
}
void TagDuel::RefreshSzone(int player, int flag, int use_cache) {
char query_buffer[0x2000];
char query_buffer[0x4000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
......@@ -1593,7 +1608,7 @@ void TagDuel::RefreshSzone(int player, int flag, int use_cache) {
NetServer::ReSendToPlayer(*pit);
}
void TagDuel::RefreshHand(int player, int flag, int use_cache) {
char query_buffer[0x2000];
char query_buffer[0x4000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
......@@ -1621,7 +1636,7 @@ void TagDuel::RefreshHand(int player, int flag, int use_cache) {
NetServer::ReSendToPlayer(*pit);
}
void TagDuel::RefreshGrave(int player, int flag, int use_cache) {
char query_buffer[0x2000];
char query_buffer[0x4000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
......@@ -1635,7 +1650,7 @@ void TagDuel::RefreshGrave(int player, int flag, int use_cache) {
NetServer::ReSendToPlayer(*pit);
}
void TagDuel::RefreshExtra(int player, int flag, int use_cache) {
char query_buffer[0x2000];
char query_buffer[0x4000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
......@@ -1644,7 +1659,7 @@ void TagDuel::RefreshExtra(int player, int flag, int use_cache) {
NetServer::SendBufferToPlayer(cur_player[player], STOC_GAME_MSG, query_buffer, len + 3);
}
void TagDuel::RefreshSingle(int player, int location, int sequence, int flag) {
char query_buffer[0x2000];
char query_buffer[0x4000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_CARD);
BufferIO::WriteInt8(qbuf, player);
......@@ -1677,6 +1692,25 @@ void TagDuel::RefreshSingle(int player, int location, int sequence, int flag) {
}
}
}
byte* TagDuel::ScriptReaderEx(const char* script_name, int* slen) {
char sname[256] = "./specials";
strcat(sname, script_name + 8);//default script name: ./script/c%d.lua
byte* buffer = default_script_reader(sname, slen);
if(!buffer) {
char sname[256] = "./expansions";
strcat(sname, script_name + 1);
buffer = default_script_reader(sname, slen);
}
if(!buffer) {
char sname[256] = "./beta";
strcat(sname, script_name + 1);
buffer = default_script_reader(sname, slen);
}
if(buffer)
return buffer;
else
return default_script_reader(script_name, slen);
}
int TagDuel::MessageHandler(long fduel, int type) {
if(!enable_log)
return 0;
......
......@@ -32,12 +32,13 @@ public:
void DuelEndProc();
void WaitforResponse(int playerid);
void RefreshMzone(int player, int flag = 0x881fff, int use_cache = 1);
void RefreshSzone(int player, int flag = 0x681fff, int use_cache = 1);
void RefreshSzone(int player, int flag = 0xe81fff, int use_cache = 1);
void RefreshHand(int player, int flag = 0x781fff, int use_cache = 1);
void RefreshGrave(int player, int flag = 0x81fff, int use_cache = 1);
void RefreshExtra(int player, int flag = 0x81fff, int use_cache = 1);
void RefreshSingle(int player, int location, int sequence, int flag = 0xf81fff);
static byte* ScriptReaderEx(const char* script_name, int* slen);
static int MessageHandler(long fduel, int type);
static void TagTimer(evutil_socket_t fd, short events, void* arg);
......
This diff is collapsed.
Subproject commit 18afda69b47580b7ec3ae5470f2eb3272e9817db
Subproject commit 4021b88fece56ace8d56ba0ec000b9939e561adc
......@@ -4,16 +4,44 @@ project "freetype"
includedirs { "include" }
defines { "FT2_BUILD_LIBRARY" }
files { "src/autofit/autofit.c", "src/bdf/bdf.c", "src/cff/cff.c", "src/base/ftbase.c",
"src/base/ftbitmap.c", "src/cache/ftcache.c", "src/base/ftfstype.c", "src/base/ftgasp.c",
"src/base/ftglyph.c", "src/gzip/ftgzip.c", "src/base/ftinit.c", "src/lzw/ftlzw.c",
"src/base/ftstroke.c", "src/base/ftsystem.c", "src/smooth/smooth.c", "src/base/ftbbox.c",
"src/base/ftfntfmt.c", "src/base/ftmm.c", "src/base/ftpfr.c", "src/base/ftsynth.c",
"src/base/fttype1.c", "src/base/ftwinfnt.c", "src/base/ftlcdfil.c", "src/base/ftgxval.c",
"src/base/ftotval.c", "src/base/ftpatent.c", "src/pcf/pcf.c", "src/pfr/pfr.c",
"src/psaux/psaux.c", "src/pshinter/pshinter.c", "src/psnames/psmodule.c",
"src/raster/raster.c", "src/sfnt/sfnt.c", "src/truetype/truetype.c",
"src/type1/type1.c", "src/cid/type1cid.c", "src/type42/type42.c", "src/winfonts/winfnt.c" }
files { "src/autofit/autofit.c",
"src/base/ftbase.c",
"src/base/ftbbox.c",
"src/base/ftbdf.c",
"src/base/ftbitmap.c",
"src/base/ftcid.c",
"src/base/ftfstype.c",
"src/base/ftgasp.c",
"src/base/ftglyph.c",
"src/base/ftgxval.c",
"src/base/ftinit.c",
"src/base/ftmm.c",
"src/base/ftotval.c",
"src/base/ftpatent.c",
"src/base/ftpfr.c",
"src/base/ftstroke.c",
"src/base/ftsynth.c",
"src/base/ftsystem.c",
"src/base/fttype1.c",
"src/base/ftwinfnt.c",
"src/bdf/bdf.c",
"src/cache/ftcache.c",
"src/cff/cff.c",
"src/cid/type1cid.c",
"src/gzip/ftgzip.c",
"src/lzw/ftlzw.c",
"src/pcf/pcf.c",
"src/pfr/pfr.c",
"src/psaux/psaux.c",
"src/pshinter/pshinter.c",
"src/psnames/psmodule.c",
"src/raster/raster.c",
"src/sfnt/sfnt.c",
"src/smooth/smooth.c",
"src/truetype/truetype.c",
"src/type1/type1.c",
"src/type42/type42.c",
"src/winfonts/winfnt.c" }
configuration "windows"
files { "builds/windows/ftdebug.c" }
1 ICON "ygopro.ico"
1 VERSIONINFO
FILEVERSION 1, 0, 34, 4
PRODUCTVERSION 1, 0, 34, 4
FILEVERSION 1, 0, 34, 5
PRODUCTVERSION 1, 0, 34, 5
FILEOS 0x4
FILETYPE 0x1
......@@ -16,8 +16,8 @@ VALUE "InternalName", "KoishiPro"
VALUE "LegalCopyright", "Copyright (C) 2018 Nanahira"
VALUE "OriginalFilename", "ygopro.exe"
VALUE "ProductName", "KoishiPro"
VALUE "FileVersion", "1.034.4.Koishi"
VALUE "ProductVersion", "1.034.4.Koishi"
VALUE "FileVersion", "1.034.5.Koishi"
VALUE "ProductVersion", "1.034.5.Koishi"
END
END
BLOCK "VarFileInfo"
......
......@@ -25,7 +25,7 @@ solution "ygo"
configuration "vs*"
flags "EnableSSE2"
buildoptions { "-wd4996" }
buildoptions { "-wd4996", "/utf-8" }
defines { "_CRT_SECURE_NO_WARNINGS" }
configuration "not vs*"
......
Subproject commit 8d088a71476f5e627c308f294a61ab3eed431625
Subproject commit 2e9a5be7958610f4274944c6d19c221b4a2d2600
......@@ -8,6 +8,7 @@ equip.wav
destroyed.wav
banished.wav
token.wav
negate.wav
attack.wav
directattack.wav
draw.wav
......
......@@ -48,7 +48,7 @@
!system 94 是否现在使用这张卡的效果?
!system 95 是否使用[%ls]的效果?
!system 96 是否使用[%ls]的效果代替破坏?
!system 97 是否把[%ls]在魔法与陷阱区域放置
!system 97 是否把[%ls]在魔法与陷阱区域盖放
!system 98 是否要解放对方怪兽?
!system 100 先攻
!system 101 后攻
......@@ -95,7 +95,7 @@
!system 524 请选择里侧攻击表示的怪兽
!system 525 请选择里侧守备表示的怪兽
!system 526 请选择给对方确认的卡
!system 527 请选择要放置到场上的卡
!system 527 请选择要盖放到场上的卡
!system 528 请选择要改变表示形式的怪兽
!system 529 请选择自己的卡
!system 530 请选择对方的卡
......@@ -229,13 +229,13 @@
!system 1150 发动
!system 1151 召唤
!system 1152 特殊召唤
!system 1153 放置
!system 1153 盖放
!system 1154 反转召唤
!system 1155 守备表示
!system 1156 攻击表示
!system 1157 攻击
!system 1158 查看列表
!system 1159 当魔法卡放置
!system 1159 当魔法卡盖放
!system 1160 在灵摆区域发动
!system 1161 效果处理
!system 1162 效果重置
......@@ -243,6 +243,9 @@
!system 1164 同调召唤
!system 1165 超量召唤
!system 1166 连接召唤
!system 1190 加入手卡
!system 1191 送去墓地
!system 1192 除外
#menu
!system 1200 联机模式
!system 1201 单人模式
......@@ -308,7 +311,14 @@
!system 1279 开启音效
!system 1280 开启音乐
!system 1281 按场景切换音乐
!system 1282 数字灵摆图片
!system 1282 窗口大小
!system 1283
!system 1284
!system 1285
!system 1286 特大
!system 1287 数字灵摆图片
!system 1288 语言(重启后生效)
!system 1289 默认
!system 1290 忽略对方发言
!system 1291 忽略观战者发言
!system 1292 忽略时点
......@@ -318,6 +328,7 @@
!system 1296 完成选择
!system 1297 切洗手卡
!system 1298 辅助功能
!system 1299 加快动画效果
!system 1300 禁限卡表:
!system 1301 卡组列表:
!system 1302 保存
......@@ -384,6 +395,7 @@
!system 1366 重命名成功
!system 1367 重命名卡组
!system 1368 卡组文件:
!system 1369 提取卡组
!system 1370 星数↑
!system 1371 攻击↑
!system 1372 守备↑
......@@ -427,7 +439,7 @@
!system 1511 对方宣言了:[%ls]
!system 1512 对方选择了:[%d]
!system 1600 卡片改变了表示形式
!system 1601 放置了卡片
!system 1601 盖放了卡片
!system 1602 卡的控制权改变了
!system 1603 [%ls]召唤中
!system 1604 怪兽召唤成功
......@@ -542,6 +554,8 @@
!counter 0x46 指示物(刚鬼死斗)
!counter 0x47 指示物(限制代码)
!counter 0x48 指示物(连接死亡炮塔)
!counter 0x1049 警逻指示物
!counter 0x4a 运动员指示物
#setnames, using tab for comment
!setname 0x1 正义盟军 AOJ
!setname 0x2 次世代 ジェネクス
......@@ -904,3 +918,14 @@
!setname 0x1115 闪刀姬 閃刀姫
!setname 0x116 圣像骑士 パラディオン
!setname 0x117 魔神仪 魔神儀
!setname 0x118 电脑网 サイバネット
!setname 0x119 转生炎兽 サラマングレイト
!setname 0x11a 恐龙摔跤手 ダイナレスラー
!setname 0x11b 自奏圣乐 オルフェゴール
!setname 0x11c 雷龙 サンダー·ドラゴン
!setname 0x11d 禁忌的 禁じられた
!setname 0x11e 危险! Danger!
!setname 0x11f 奈芙提斯 ネフティス
!setname 0x120 调皮宝贝 プランキッズ
!setname 0x121 魔妖
!setname 0x122 女武神 Valkyrie
......@@ -2,14 +2,14 @@
#nickname & gamename should be less than 20 characters
use_d3d = 0
use_image_scale = 1
pro_version = 4931
pro_version = 4933
antialias = 2
errorlog = 3
nickname = Komeiji Koishi
gamename = Game
lastdeck = new
textfont = c:/windows/fonts/simhei.ttf 14
numfont = c:/windows/fonts/arial.ttf
textfont = ./fonts/simhei.ttf 14
numfont = ./fonts/arial.ttf
serverport = 7911
lasthost = 127.0.0.1
lastport = 7911
......@@ -21,7 +21,7 @@ waitchain = 0
mute_opponent = 0
mute_spectators = 0
hide_setname = 0
hide_hint_button = 1
hide_hint_button = 0
#control_mode = 0: Key A/S/D/R Chain Buttons. control_mode = 1: MouseLeft/MouseRight/NULL/F9 Without Chain Buttons
control_mode = 0
draw_field_spell = 1
......@@ -43,3 +43,4 @@ window_height = 640
resize_popup_menu = 0
enable_pendulum_scale = 1
skin_index = -1
locale = default
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