Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Y
YGOMobile
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
fallenstardust
YGOMobile
Commits
eb028f4b
Commit
eb028f4b
authored
Dec 06, 2025
by
fallenstardust
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sync ocgcore
添加注释game
parent
039c168a
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
456 additions
and
192 deletions
+456
-192
Classes/gframe/game.cpp
Classes/gframe/game.cpp
+271
-112
Classes/ocgcore/processor.cpp
Classes/ocgcore/processor.cpp
+185
-80
No files found.
Classes/gframe/game.cpp
View file @
eb028f4b
...
@@ -12,7 +12,7 @@
...
@@ -12,7 +12,7 @@
#include <thread>
#include <thread>
#include <string>
#include <string>
#include <regex>
#include <regex>
#ifdef _IRR_ANDROID_PLATFORM_
#include <android/CAndroidGUIEditBox.h>
#include <android/CAndroidGUIEditBox.h>
#include <android/CAndroidGUIComboBox.h>
#include <android/CAndroidGUIComboBox.h>
#include <android/CAndroidGUISkin.h>
#include <android/CAndroidGUISkin.h>
...
@@ -21,13 +21,22 @@
...
@@ -21,13 +21,22 @@
#include <COGLESExtensionHandler.h>
#include <COGLESExtensionHandler.h>
#include <COGLES2Driver.h>
#include <COGLES2Driver.h>
#include <COGLESDriver.h>
#include <COGLESDriver.h>
#endif
namespace
ygo
{
namespace
ygo
{
Game
*
mainGame
;
Game
*
mainGame
;
/**
* @brief 清空决斗信息结构体中的所有数据
*
* 该函数将DuelInfo结构体中的所有成员变量重置为初始状态,
* 包括决斗状态标志、玩家生命值、回合信息、时间限制等。
*
* @param this 指向DuelInfo对象的指针
* @return 无返回值
*/
void
DuelInfo
::
Clear
()
{
void
DuelInfo
::
Clear
()
{
// 重置决斗状态标志
isStarted
=
false
;
isStarted
=
false
;
isInDuel
=
false
;
isInDuel
=
false
;
isFinished
=
false
;
isFinished
=
false
;
...
@@ -40,18 +49,26 @@ void DuelInfo::Clear() {
...
@@ -40,18 +49,26 @@ void DuelInfo::Clear() {
tag_player
[
0
]
=
false
;
tag_player
[
0
]
=
false
;
tag_player
[
1
]
=
false
;
tag_player
[
1
]
=
false
;
isReplaySwapped
=
false
;
isReplaySwapped
=
false
;
// 重置生命值相关数据
lp
[
0
]
=
0
;
lp
[
0
]
=
0
;
lp
[
1
]
=
0
;
lp
[
1
]
=
0
;
start_lp
=
0
;
start_lp
=
0
;
// 重置决斗规则和回合信息
duel_rule
=
0
;
duel_rule
=
0
;
turn
=
0
;
turn
=
0
;
curMsg
=
0
;
curMsg
=
0
;
// 清空主机名和客户端名称
hostname
[
0
]
=
0
;
hostname
[
0
]
=
0
;
clientname
[
0
]
=
0
;
clientname
[
0
]
=
0
;
hostname_tag
[
0
]
=
0
;
hostname_tag
[
0
]
=
0
;
clientname_tag
[
0
]
=
0
;
clientname_tag
[
0
]
=
0
;
strLP
[
0
][
0
]
=
0
;
strLP
[
0
][
0
]
=
0
;
strLP
[
1
][
0
]
=
0
;
strLP
[
1
][
0
]
=
0
;
// 重置玩家类型和时间限制
player_type
=
0
;
player_type
=
0
;
time_player
=
0
;
time_player
=
0
;
time_limit
=
0
;
time_limit
=
0
;
...
@@ -59,10 +76,20 @@ void DuelInfo::Clear() {
...
@@ -59,10 +76,20 @@ void DuelInfo::Clear() {
time_left
[
1
]
=
0
;
time_left
[
1
]
=
0
;
}
}
/**
* @brief 处理游戏事件
* @param event 输入事件引用,包含鼠标或键盘等输入信息
*
* 该函数主要用于处理鼠标输入事件,对鼠标的坐标进行优化处理。
* 当事件类型为鼠标输入时,会获取当前鼠标坐标并调用optX和optY函数
* 对坐标进行转换或优化,然后更新鼠标输入事件中的坐标值。
*/
void
Game
::
process
(
irr
::
SEvent
&
event
)
{
void
Game
::
process
(
irr
::
SEvent
&
event
)
{
// 检查事件类型是否为鼠标输入事件
if
(
event
.
EventType
==
irr
::
EET_MOUSE_INPUT_EVENT
)
{
if
(
event
.
EventType
==
irr
::
EET_MOUSE_INPUT_EVENT
)
{
irr
::
s32
x
=
event
.
MouseInput
.
X
;
irr
::
s32
x
=
event
.
MouseInput
.
X
;
irr
::
s32
y
=
event
.
MouseInput
.
Y
;
irr
::
s32
y
=
event
.
MouseInput
.
Y
;
// 对鼠标坐标进行优化处理并更新事件中的坐标值
event
.
MouseInput
.
X
=
optX
(
x
);
event
.
MouseInput
.
X
=
optX
(
x
);
event
.
MouseInput
.
Y
=
optY
(
y
);
event
.
MouseInput
.
Y
=
optY
(
y
);
}
}
...
@@ -135,59 +162,85 @@ bool IsExtension(const char* filename, const char* extension) {
...
@@ -135,59 +162,85 @@ bool IsExtension(const char* filename, const char* extension) {
}
}
bool
Game
::
Initialize
(
ANDROID_APP
app
,
irr
::
android
::
InitOptions
*
options
)
{
bool
Game
::
Initialize
(
ANDROID_APP
app
,
irr
::
android
::
InitOptions
*
options
)
{
// 保存应用程序句柄
this
->
appMain
=
app
;
this
->
appMain
=
app
;
// 初始化随机数种子
srand
(
time
(
0
));
srand
(
time
(
0
));
// 创建Irrlicht引擎参数结构体
irr
::
SIrrlichtCreationParameters
params
{};
irr
::
SIrrlichtCreationParameters
params
{};
// 获取OpenGL版本设置
glversion
=
options
->
getOpenglVersion
();
glversion
=
options
->
getOpenglVersion
();
// 根据OpenGL版本选择渲染驱动类型
if
(
glversion
==
0
)
{
if
(
glversion
==
0
)
{
params
.
DriverType
=
irr
::
video
::
EDT_OGLES1
;
params
.
DriverType
=
irr
::
video
::
EDT_OGLES1
;
}
else
{
}
else
{
params
.
DriverType
=
irr
::
video
::
EDT_OGLES2
;
params
.
DriverType
=
irr
::
video
::
EDT_OGLES2
;
}
}
// 设置应用程序私有数据
params
.
PrivateData
=
app
;
params
.
PrivateData
=
app
;
// 设置颜色深度为24位
params
.
Bits
=
24
;
params
.
Bits
=
24
;
// 设置Z缓冲区深度为16位
params
.
ZBufferBits
=
16
;
params
.
ZBufferBits
=
16
;
params
.
AntiAlias
=
0
;
// 关闭抗锯齿
params
.
AntiAlias
=
1
;
// 设置窗口大小为自适应
params
.
WindowSize
=
irr
::
core
::
dimension2d
<
irr
::
u32
>
(
0
,
0
);
params
.
WindowSize
=
irr
::
core
::
dimension2d
<
irr
::
u32
>
(
0
,
0
);
// 创建Irrlicht设备实例
device
=
irr
::
createDeviceEx
(
params
);
device
=
irr
::
createDeviceEx
(
params
);
// 检查设备创建是否成功
if
(
!
device
)
{
if
(
!
device
)
{
ErrorLog
(
"Failed to create Irrlicht Engine device!"
);
ErrorLog
(
"Failed to create Irrlicht Engine device!"
);
return
false
;
return
false
;
}
}
// 执行Android平台特定的初始化技巧
if
(
!
irr
::
android
::
perfromTrick
(
app
))
{
if
(
!
irr
::
android
::
perfromTrick
(
app
))
{
return
false
;
return
false
;
}
}
// 初始化Java桥接并获取应用位置信息
irr
::
core
::
vector2di
appPosition
=
irr
::
android
::
initJavaBridge
(
app
,
device
);
irr
::
core
::
vector2di
appPosition
=
irr
::
android
::
initJavaBridge
(
app
,
device
);
// 设置位置修正参数
setPositionFix
(
appPosition
);
setPositionFix
(
appPosition
);
// 设置进程接收器
device
->
setProcessReceiver
(
this
);
device
->
setProcessReceiver
(
this
);
// 设置输入事件处理函数
app
->
onInputEvent
=
irr
::
android
::
handleInput
;
app
->
onInputEvent
=
irr
::
android
::
handleInput
;
// 获取日志记录器
irr
::
ILogger
*
logger
=
device
->
getLogger
();
irr
::
ILogger
*
logger
=
device
->
getLogger
();
// logger->setLogLevel(ELL_WARNING);
// logger->setLogLevel(ELL_WARNING);
// 检查是否启用钟摆刻度显示
isPSEnabled
=
options
->
isPendulumScaleEnabled
();
isPSEnabled
=
options
->
isPendulumScaleEnabled
();
// 获取文件系统并设置给数据管理器
dataManager
.
FileSystem
=
device
->
getFileSystem
();
dataManager
.
FileSystem
=
device
->
getFileSystem
();
// 设置应用命令回调函数
((
irr
::
CIrrDeviceAndroid
*
)
device
)
->
onAppCmd
=
onHandleAndroidCommand
;
((
irr
::
CIrrDeviceAndroid
*
)
device
)
->
onAppCmd
=
onHandleAndroidCommand
;
// 获取屏幕缩放比例
xScale
=
irr
::
android
::
getXScale
(
app
);
xScale
=
irr
::
android
::
getXScale
(
app
);
yScale
=
irr
::
android
::
getYScale
(
app
);
yScale
=
irr
::
android
::
getYScale
(
app
);
ALOGD
(
"cc game: xScale = %f, yScale = %f"
,
xScale
,
yScale
);
ALOGD
(
"cc game: xScale = %f, yScale = %f"
,
xScale
,
yScale
);
SetCardS3DVertex
();
//reset cardfront cardback S3DVertex size
// 重置卡片顶点数据大小
//io::path databaseDir = options->getDBDir();
SetCardS3DVertex
();
// 获取工作目录路径
irr
::
io
::
path
workingDir
=
options
->
getWorkDir
();
irr
::
io
::
path
workingDir
=
options
->
getWorkDir
();
ALOGD
(
"cc game: workingDir= %s"
,
workingDir
.
c_str
());
ALOGD
(
"cc game: workingDir= %s"
,
workingDir
.
c_str
());
// 更改工作目录
dataManager
.
FileSystem
->
changeWorkingDirectoryTo
(
workingDir
);
dataManager
.
FileSystem
->
changeWorkingDirectoryTo
(
workingDir
);
/* Your media must be somewhere inside the assets folder. The assets folder is the root for the file system.
/* Your media must be somewhere inside the assets folder. The assets folder is the root for the file system.
This example copies the media in the Android.mk makefile. */
This example copies the media in the Android.mk makefile. */
// 定义媒体资源路径
irr
::
core
::
stringc
mediaPath
=
"media/"
;
irr
::
core
::
stringc
mediaPath
=
"media/"
;
// The Android assets file-system does not know which sub-directories it has (blame google).
// The Android assets file-system does not know which sub-directories it has (blame google).
// So we have to add all sub-directories in assets manually. Otherwise we could still open the files,
// So we have to add all sub-directories in assets manually. Otherwise we could still open the files,
// but existFile checks will fail (which are for example needed by getFont).
// but existFile checks will fail (which are for example needed by getFont).
// 遍历文件档案,为Android资产文件系统添加目录列表
for
(
irr
::
u32
i
=
0
;
i
<
dataManager
.
FileSystem
->
getFileArchiveCount
();
++
i
)
for
(
irr
::
u32
i
=
0
;
i
<
dataManager
.
FileSystem
->
getFileArchiveCount
();
++
i
)
{
{
IFileArchive
*
archive
=
dataManager
.
FileSystem
->
getFileArchive
(
i
);
IFileArchive
*
archive
=
dataManager
.
FileSystem
->
getFileArchive
(
i
);
...
@@ -197,11 +250,12 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
...
@@ -197,11 +250,12 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
break
;
break
;
}
}
}
}
//
pics.zip, scripts.zip, ...zip
//
加载ZIP压缩包资源
irr
::
io
::
path
*
zips
=
options
->
getArchiveFiles
();
irr
::
io
::
path
*
zips
=
options
->
getArchiveFiles
();
int
len
=
options
->
getArchiveCount
();
int
len
=
options
->
getArchiveCount
();
for
(
int
i
=
0
;
i
<
len
;
i
++
){
for
(
int
i
=
0
;
i
<
len
;
i
++
){
irr
::
io
::
path
zip_path
=
zips
[
i
];
irr
::
io
::
path
zip_path
=
zips
[
i
];
// 添加文件档案
if
(
dataManager
.
FileSystem
->
addFileArchive
(
zip_path
.
c_str
(),
false
,
false
,
EFAT_ZIP
))
{
if
(
dataManager
.
FileSystem
->
addFileArchive
(
zip_path
.
c_str
(),
false
,
false
,
EFAT_ZIP
))
{
ALOGD
(
"cc game: add arrchive ok:%s"
,
zip_path
.
c_str
());
ALOGD
(
"cc game: add arrchive ok:%s"
,
zip_path
.
c_str
());
}
else
{
}
else
{
...
@@ -209,7 +263,9 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
...
@@ -209,7 +263,9 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
}
}
}
}
// 加载配置文件
LoadConfig
();
LoadConfig
();
// 初始化各种游戏状态变量
linePatternD3D
=
0
;
linePatternD3D
=
0
;
linePatternGL
=
0x0f0f
;
linePatternGL
=
0x0f0f
;
waitFrame
=
0
;
waitFrame
=
0
;
...
@@ -223,15 +279,19 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
...
@@ -223,15 +279,19 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
is_building
=
false
;
is_building
=
false
;
menuHandler
.
prev_operation
=
0
;
menuHandler
.
prev_operation
=
0
;
menuHandler
.
prev_sel
=
-
1
;
menuHandler
.
prev_sel
=
-
1
;
// 获取视频驱动和场景管理器
driver
=
device
->
getVideoDriver
();
driver
=
device
->
getVideoDriver
();
#ifdef _IRR_ANDROID_PLATFORM_
// 获取卡片质量设置
int
quality
=
options
->
getCardQualityOp
();
int
quality
=
options
->
getCardQualityOp
();
// 检查是否支持非2次幂纹理
if
(
driver
->
getDriverType
()
==
irr
::
video
::
EDT_OGLES2
)
{
if
(
driver
->
getDriverType
()
==
irr
::
video
::
EDT_OGLES2
)
{
isNPOTSupported
=
((
irr
::
video
::
COGLES2Driver
*
)
driver
)
->
queryOpenGLFeature
(
irr
::
video
::
COGLES2ExtensionHandler
::
IRR_OES_texture_npot
);
isNPOTSupported
=
((
irr
::
video
::
COGLES2Driver
*
)
driver
)
->
queryOpenGLFeature
(
irr
::
video
::
COGLES2ExtensionHandler
::
IRR_OES_texture_npot
);
}
else
{
}
else
{
isNPOTSupported
=
((
irr
::
video
::
COGLES1Driver
*
)
driver
)
->
queryOpenGLFeature
(
irr
::
video
::
COGLES1ExtensionHandler
::
IRR_OES_texture_npot
);
isNPOTSupported
=
((
irr
::
video
::
COGLES1Driver
*
)
driver
)
->
queryOpenGLFeature
(
irr
::
video
::
COGLES1ExtensionHandler
::
IRR_OES_texture_npot
);
}
}
ALOGD
(
"cc game: isNPOTSupported = %d"
,
isNPOTSupported
);
ALOGD
(
"cc game: isNPOTSupported = %d"
,
isNPOTSupported
);
// 根据纹理支持情况设置纹理创建标志
if
(
isNPOTSupported
)
{
if
(
isNPOTSupported
)
{
if
(
quality
==
1
)
{
if
(
quality
==
1
)
{
driver
->
setTextureCreationFlag
(
irr
::
video
::
ETCF_CREATE_MIP_MAPS
,
false
);
driver
->
setTextureCreationFlag
(
irr
::
video
::
ETCF_CREATE_MIP_MAPS
,
false
);
...
@@ -242,30 +302,33 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
...
@@ -242,30 +302,33 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
driver
->
setTextureCreationFlag
(
irr
::
video
::
ETCF_ALLOW_NON_POWER_2
,
true
);
driver
->
setTextureCreationFlag
(
irr
::
video
::
ETCF_ALLOW_NON_POWER_2
,
true
);
driver
->
setTextureCreationFlag
(
irr
::
video
::
ETCF_CREATE_MIP_MAPS
,
false
);
driver
->
setTextureCreationFlag
(
irr
::
video
::
ETCF_CREATE_MIP_MAPS
,
false
);
}
}
#endif
// 设置纹理优化质量标志
driver
->
setTextureCreationFlag
(
irr
::
video
::
ETCF_OPTIMIZED_FOR_QUALITY
,
true
);
driver
->
setTextureCreationFlag
(
irr
::
video
::
ETCF_OPTIMIZED_FOR_QUALITY
,
true
);
// 初始化图像管理器
imageManager
.
SetDevice
(
device
);
imageManager
.
SetDevice
(
device
);
imageManager
.
ClearTexture
();
imageManager
.
ClearTexture
();
// 初始化图像资源
if
(
!
imageManager
.
Initial
(
workingDir
))
{
if
(
!
imageManager
.
Initial
(
workingDir
))
{
ErrorLog
(
"Failed to load textures!"
);
ErrorLog
(
"Failed to load textures!"
);
return
false
;
return
false
;
}
}
//
LoadExpansions only load zips, the other cdb databases are still loaded by getDBFiles
//
加载数据库文件
irr
::
io
::
path
*
cdbs
=
options
->
getDBFiles
();
irr
::
io
::
path
*
cdbs
=
options
->
getDBFiles
();
len
=
options
->
getDbCount
();
len
=
options
->
getDbCount
();
//os::Printer::log("load cdbs count %d", len);
for
(
int
i
=
0
;
i
<
len
;
i
++
){
for
(
int
i
=
0
;
i
<
len
;
i
++
){
irr
::
io
::
path
cdb_path
=
cdbs
[
i
];
irr
::
io
::
path
cdb_path
=
cdbs
[
i
];
wchar_t
wpath
[
1024
];
wchar_t
wpath
[
1024
];
// 解码UTF8路径
BufferIO
::
DecodeUTF8
(
cdb_path
.
c_str
(),
wpath
);
BufferIO
::
DecodeUTF8
(
cdb_path
.
c_str
(),
wpath
);
// 加载数据库
if
(
dataManager
.
LoadDB
(
wpath
))
{
if
(
dataManager
.
LoadDB
(
wpath
))
{
ALOGD
(
"cc game: add cdb ok:%s"
,
cdb_path
.
c_str
());
ALOGD
(
"cc game: add cdb ok:%s"
,
cdb_path
.
c_str
());
}
else
{
}
else
{
ALOGW
(
"cc game: add cdb fail:%s"
,
cdb_path
.
c_str
());
ALOGW
(
"cc game: add cdb fail:%s"
,
cdb_path
.
c_str
());
}
}
}
}
//if(!dataManager.LoadDB(workingDir.append("/cards.cdb").c_str()))
// 加载字符串配置文件
// return false;
if
(
dataManager
.
LoadStrings
((
workingDir
+
path
(
"/expansions/strings.conf"
)).
c_str
())){
if
(
dataManager
.
LoadStrings
((
workingDir
+
path
(
"/expansions/strings.conf"
)).
c_str
())){
ALOGD
(
"cc game: loadStrings expansions/strings.conf"
);
ALOGD
(
"cc game: loadStrings expansions/strings.conf"
);
}
}
...
@@ -273,27 +336,38 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
...
@@ -273,27 +336,38 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
ErrorLog
(
"Failed to load strings!"
);
ErrorLog
(
"Failed to load strings!"
);
return
false
;
return
false
;
}
}
// 加载扩展卡包
LoadExpansions
();
LoadExpansions
();
// 加载禁限卡表
deckManager
.
LoadLFList
(
options
);
deckManager
.
LoadLFList
(
options
);
// 获取GUI环境
env
=
device
->
getGUIEnvironment
();
env
=
device
->
getGUIEnvironment
();
// 检查是否启用字体抗锯齿
bool
isAntialias
=
options
->
isFontAntiAliasEnabled
();
bool
isAntialias
=
options
->
isFontAntiAliasEnabled
();
// 创建各种字体
numFont
=
irr
::
gui
::
CGUITTFont
::
createTTFont
(
env
,
gameConf
.
numfont
,
18
*
yScale
,
isAntialias
,
false
);
numFont
=
irr
::
gui
::
CGUITTFont
::
createTTFont
(
env
,
gameConf
.
numfont
,
18
*
yScale
,
isAntialias
,
false
);
adFont
=
irr
::
gui
::
CGUITTFont
::
createTTFont
(
env
,
gameConf
.
numfont
,
12
*
yScale
,
isAntialias
,
false
);
adFont
=
irr
::
gui
::
CGUITTFont
::
createTTFont
(
env
,
gameConf
.
numfont
,
12
*
yScale
,
isAntialias
,
false
);
lpcFont
=
irr
::
gui
::
CGUITTFont
::
createTTFont
(
env
,
gameConf
.
numfont
,
48
*
yScale
,
isAntialias
,
true
);
lpcFont
=
irr
::
gui
::
CGUITTFont
::
createTTFont
(
env
,
gameConf
.
numfont
,
48
*
yScale
,
isAntialias
,
true
);
guiFont
=
irr
::
gui
::
CGUITTFont
::
createTTFont
(
env
,
gameConf
.
textfont
,
18
*
yScale
,
isAntialias
,
true
);
guiFont
=
irr
::
gui
::
CGUITTFont
::
createTTFont
(
env
,
gameConf
.
textfont
,
18
*
yScale
,
isAntialias
,
true
);
titleFont
=
irr
::
gui
::
CGUITTFont
::
createTTFont
(
env
,
gameConf
.
textfont
,
32
*
yScale
,
isAntialias
,
true
);
titleFont
=
irr
::
gui
::
CGUITTFont
::
createTTFont
(
env
,
gameConf
.
textfont
,
32
*
yScale
,
isAntialias
,
true
);
textFont
=
irr
::
gui
::
CGUITTFont
::
createTTFont
(
env
,
gameConf
.
textfont
,
(
int
)
gameConf
.
textfontsize
*
yScale
,
isAntialias
,
true
);
textFont
=
irr
::
gui
::
CGUITTFont
::
createTTFont
(
env
,
gameConf
.
textfont
,
(
int
)
gameConf
.
textfontsize
*
yScale
,
isAntialias
,
true
);
// 检查字体创建是否成功
if
(
!
numFont
||
!
guiFont
)
{
if
(
!
numFont
||
!
guiFont
)
{
ALOGW
(
"cc game: add font fail "
);
ALOGW
(
"cc game: add font fail "
);
}
}
// 获取场景管理器
smgr
=
device
->
getSceneManager
();
smgr
=
device
->
getSceneManager
();
// 设置窗口标题
device
->
setWindowCaption
(
L"[---]"
);
device
->
setWindowCaption
(
L"[---]"
);
// 禁止窗口大小调整
device
->
setResizable
(
false
);
device
->
setResizable
(
false
);
// 创建并设置新的GUI皮肤
irr
::
gui
::
IGUISkin
*
newskin
=
irr
::
gui
::
CAndroidGUISkin
::
createAndroidSkin
(
irr
::
gui
::
EGST_BURNING_SKIN
,
driver
,
env
,
xScale
,
yScale
);
irr
::
gui
::
IGUISkin
*
newskin
=
irr
::
gui
::
CAndroidGUISkin
::
createAndroidSkin
(
irr
::
gui
::
EGST_BURNING_SKIN
,
driver
,
env
,
xScale
,
yScale
);
newskin
->
setFont
(
guiFont
);
newskin
->
setFont
(
guiFont
);
env
->
setSkin
(
newskin
);
env
->
setSkin
(
newskin
);
// 释放皮肤资源
newskin
->
drop
();
newskin
->
drop
();
#ifdef _IRR_ANDROID_PLATFORM_
//main menu
//main menu
wMainMenu
=
env
->
addWindow
(
Resize
(
450
,
40
,
900
,
600
),
false
,
L""
);
wMainMenu
=
env
->
addWindow
(
Resize
(
450
,
40
,
900
,
600
),
false
,
L""
);
wMainMenu
->
getCloseButton
()
->
setVisible
(
false
);
wMainMenu
->
getCloseButton
()
->
setVisible
(
false
);
...
@@ -772,7 +846,7 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
...
@@ -772,7 +846,7 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
scrOption
->
setLargeStep
(
1
);
scrOption
->
setLargeStep
(
1
);
scrOption
->
setSmallStep
(
1
);
scrOption
->
setSmallStep
(
1
);
scrOption
->
setMin
(
0
);
scrOption
->
setMin
(
0
);
#endif
//pos select
//pos select
wPosSelect
=
env
->
addWindow
(
irr
::
core
::
recti
(
660
*
xScale
-
223
*
yScale
,
160
*
yScale
,
660
*
xScale
+
223
*
yScale
,
(
160
+
228
)
*
yScale
),
false
,
dataManager
.
GetSysString
(
561
));
wPosSelect
=
env
->
addWindow
(
irr
::
core
::
recti
(
660
*
xScale
-
223
*
yScale
,
160
*
yScale
,
660
*
xScale
+
223
*
yScale
,
(
160
+
228
)
*
yScale
),
false
,
dataManager
.
GetSysString
(
561
));
wPosSelect
->
getCloseButton
()
->
setVisible
(
false
);
wPosSelect
->
getCloseButton
()
->
setVisible
(
false
);
...
@@ -790,7 +864,7 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
...
@@ -790,7 +864,7 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
btnPSDD
->
setImageSize
(
irr
::
core
::
dimension2di
(
CARD_IMG_WIDTH
*
0.6
f
*
yScale
,
CARD_IMG_HEIGHT
*
0.6
f
*
yScale
));
btnPSDD
->
setImageSize
(
irr
::
core
::
dimension2di
(
CARD_IMG_WIDTH
*
0.6
f
*
yScale
,
CARD_IMG_HEIGHT
*
0.6
f
*
yScale
));
btnPSDD
->
setImageRotation
(
270
);
btnPSDD
->
setImageRotation
(
270
);
btnPSDD
->
setImage
(
imageManager
.
tCover
[
0
]);
//show cover of player1
btnPSDD
->
setImage
(
imageManager
.
tCover
[
0
]);
//show cover of player1
#ifdef _IRR_ANDROID_PLATFORM_
//card select
//card select
wCardSelect
=
env
->
addWindow
(
irr
::
core
::
recti
(
660
*
xScale
-
340
*
yScale
,
55
*
yScale
,
660
*
xScale
+
340
*
yScale
,
400
*
yScale
),
false
,
L""
);
wCardSelect
=
env
->
addWindow
(
irr
::
core
::
recti
(
660
*
xScale
-
340
*
yScale
,
55
*
yScale
,
660
*
xScale
+
340
*
yScale
,
400
*
yScale
),
false
,
L""
);
wCardSelect
->
getCloseButton
()
->
setVisible
(
false
);
wCardSelect
->
getCloseButton
()
->
setVisible
(
false
);
...
@@ -825,7 +899,7 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
...
@@ -825,7 +899,7 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
scrDisplayList
=
env
->
addScrollBar
(
true
,
Resize_Y
(
30
,
245
,
30
+
620
,
285
),
wCardDisplay
,
SCROLL_CARD_DISPLAY
);
scrDisplayList
=
env
->
addScrollBar
(
true
,
Resize_Y
(
30
,
245
,
30
+
620
,
285
),
wCardDisplay
,
SCROLL_CARD_DISPLAY
);
btnDisplayOK
=
env
->
addButton
(
Resize_Y
(
340
-
55
,
295
,
340
+
55
,
335
),
wCardDisplay
,
BUTTON_CARD_DISP_OK
,
dataManager
.
GetSysString
(
1211
));
btnDisplayOK
=
env
->
addButton
(
Resize_Y
(
340
-
55
,
295
,
340
+
55
,
335
),
wCardDisplay
,
BUTTON_CARD_DISP_OK
,
dataManager
.
GetSysString
(
1211
));
ChangeToIGUIImageButton
(
btnDisplayOK
,
imageManager
.
tButton_S
,
imageManager
.
tButton_S_pressed
);
ChangeToIGUIImageButton
(
btnDisplayOK
,
imageManager
.
tButton_S
,
imageManager
.
tButton_S_pressed
);
#endif
//announce number
//announce number
wANNumber
=
env
->
addWindow
(
Resize
(
500
,
50
,
800
,
470
),
false
,
L""
);
wANNumber
=
env
->
addWindow
(
Resize
(
500
,
50
,
800
,
470
),
false
,
L""
);
wANNumber
->
getCloseButton
()
->
setVisible
(
false
);
wANNumber
->
getCloseButton
()
->
setVisible
(
false
);
...
@@ -1012,7 +1086,7 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
...
@@ -1012,7 +1086,7 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
for
(
int
i
=
1370
;
i
<=
1373
;
i
++
)
for
(
int
i
=
1370
;
i
<=
1373
;
i
++
)
cbSortType
->
addItem
(
dataManager
.
GetSysString
(
i
));
cbSortType
->
addItem
(
dataManager
.
GetSysString
(
i
));
wSort
->
setVisible
(
false
);
wSort
->
setVisible
(
false
);
#ifdef _IRR_ANDROID_PLATFORM_
//filters
//filters
wFilter
=
env
->
addWindow
(
Resize
(
610
,
1
,
1020
,
130
),
false
,
L""
);
wFilter
=
env
->
addWindow
(
Resize
(
610
,
1
,
1020
,
130
),
false
,
L""
);
wFilter
->
getCloseButton
()
->
setVisible
(
false
);
wFilter
->
getCloseButton
()
->
setVisible
(
false
);
...
@@ -1089,9 +1163,7 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
...
@@ -1089,9 +1163,7 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
scrFilter
->
setLargeStep
(
10
);
scrFilter
->
setLargeStep
(
10
);
scrFilter
->
setSmallStep
(
1
);
scrFilter
->
setSmallStep
(
1
);
scrFilter
->
setVisible
(
false
);
scrFilter
->
setVisible
(
false
);
#endif
#ifdef _IRR_ANDROID_PLATFORM_
//LINK MARKER SEARCH
//LINK MARKER SEARCH
btnMarksFilter
=
env
->
addButton
(
Resize
(
60
,
80
+
125
/
6
,
190
,
100
+
125
/
6
),
wFilter
,
BUTTON_MARKS_FILTER
,
dataManager
.
GetSysString
(
1374
));
btnMarksFilter
=
env
->
addButton
(
Resize
(
60
,
80
+
125
/
6
,
190
,
100
+
125
/
6
),
wFilter
,
BUTTON_MARKS_FILTER
,
dataManager
.
GetSysString
(
1374
));
ChangeToIGUIImageButton
(
btnMarksFilter
,
imageManager
.
tButton_L
,
imageManager
.
tButton_L_pressed
);
ChangeToIGUIImageButton
(
btnMarksFilter
,
imageManager
.
tButton_L
,
imageManager
.
tButton_L_pressed
);
...
@@ -1283,7 +1355,7 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
...
@@ -1283,7 +1355,7 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
chkMusicMode
->
setEnabled
(
false
);
chkMusicMode
->
setEnabled
(
false
);
chkMusicMode
->
setVisible
(
false
);
chkMusicMode
->
setVisible
(
false
);
}
}
#endif
//big picture
//big picture
wBigCard
=
env
->
addWindow
(
Resize
(
0
,
0
,
0
,
0
),
false
,
L""
);
wBigCard
=
env
->
addWindow
(
Resize
(
0
,
0
,
0
,
0
),
false
,
L""
);
wBigCard
->
getCloseButton
()
->
setVisible
(
false
);
wBigCard
->
getCloseButton
()
->
setVisible
(
false
);
...
@@ -1325,112 +1397,167 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
...
@@ -1325,112 +1397,167 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
col
.
setAlpha
(
200
);
col
.
setAlpha
(
200
);
env
->
getSkin
()
->
setColor
((
irr
::
gui
::
EGUI_DEFAULT_COLOR
)
i
,
col
);
env
->
getSkin
()
->
setColor
((
irr
::
gui
::
EGUI_DEFAULT_COLOR
)
i
,
col
);
}
}
#ifdef _IRR_ANDROID_PLATFORM_
irr
::
gui
::
IGUIStaticText
*
text
=
env
->
addStaticText
(
L""
,
Resize
(
1
,
1
,
100
,
45
),
false
,
false
,
0
,
GUI_INFO_FPS
);
irr
::
gui
::
IGUIStaticText
*
text
=
env
->
addStaticText
(
L""
,
Resize
(
1
,
1
,
100
,
45
),
false
,
false
,
0
,
GUI_INFO_FPS
);
#endif
hideChat
=
false
;
hideChat
=
false
;
hideChatTimer
=
0
;
hideChatTimer
=
0
;
return
true
;
return
true
;
}
//bool Game::Initialize
}
//bool Game::Initialize
/**
* @brief 游戏主循环函数,负责渲染游戏画面、处理输入事件以及更新逻辑状态。
*
* 此函数初始化摄像机、设置投影矩阵与视图矩阵,并根据平台加载对应的着色器材质。
* 在主循环中进行场景绘制、界面刷新、音频播放等操作,并控制帧率和时间显示。
* 同时支持多线程同步机制(如互斥锁)以确保数据安全访问。
*/
void
Game
::
MainLoop
()
{
void
Game
::
MainLoop
()
{
wchar_t
cap
[
256
];
wchar_t
cap
[
256
];
// 字符缓冲区,用于临时存储宽字符文本
// 添加一个摄像机节点到场景管理器
camera
=
smgr
->
addCameraSceneNode
(
0
);
camera
=
smgr
->
addCameraSceneNode
(
0
);
// 构建并设置自定义的投影矩阵
irr
::
core
::
matrix4
mProjection
;
irr
::
core
::
matrix4
mProjection
;
BuildProjectionMatrix
(
mProjection
,
-
0.90
f
,
0.45
f
,
-
0.42
f
,
0.42
f
,
1.0
f
,
100.0
f
);
BuildProjectionMatrix
(
mProjection
,
-
0.90
f
,
0.45
f
,
-
0.42
f
,
0.42
f
,
1.0
f
,
100.0
f
);
camera
->
setProjectionMatrix
(
mProjection
);
camera
->
setProjectionMatrix
(
mProjection
);
mProjection
.
buildCameraLookAtMatrixLH
(
irr
::
core
::
vector3df
(
4.2
f
,
8.0
f
,
7.8
f
),
irr
::
core
::
vector3df
(
4.2
f
,
0
,
0
),
irr
::
core
::
vector3df
(
0
,
0
,
1
));
// 设置摄像机视角变换矩阵(LookAt)
mProjection
.
buildCameraLookAtMatrixLH
(
irr
::
core
::
vector3df
(
4.2
f
,
8.0
f
,
7.8
f
),
// 摄像机位置
irr
::
core
::
vector3df
(
4.2
f
,
0
,
0
),
// 观察目标点
irr
::
core
::
vector3df
(
0
,
0
,
1
)
// 上方向向量
);
camera
->
setViewMatrixAffector
(
mProjection
);
camera
->
setViewMatrixAffector
(
mProjection
);
// 设置环境光颜色为白色
smgr
->
setAmbientLight
(
irr
::
video
::
SColorf
(
1.0
f
,
1.0
f
,
1.0
f
));
smgr
->
setAmbientLight
(
irr
::
video
::
SColorf
(
1.0
f
,
1.0
f
,
1.0
f
));
float
atkframe
=
0.1
f
;
float
atkframe
=
0.1
f
;
// 动画帧计数器初始值
// 获取设备定时器并重置时间为0
irr
::
ITimer
*
timer
=
device
->
getTimer
();
irr
::
ITimer
*
timer
=
device
->
getTimer
();
timer
->
setTime
(
0
);
timer
->
setTime
(
0
);
// get FPS
irr
::
gui
::
IGUIElement
*
stat
=
device
->
getGUIEnvironment
()
->
getRootGUIElement
()
->
getElementFromId
(
GUI_INFO_FPS
);
// 获取GUI中的FPS信息控件
int
fps
=
0
;
irr
::
gui
::
IGUIElement
*
stat
=
device
->
getGUIEnvironment
()
->
getRootGUIElement
()
->
getElementFromId
(
GUI_INFO_FPS
);
int
cur_time
=
0
;
int
fps
=
0
;
// 当前秒内已渲染帧数
#if defined(_IRR_ANDROID_PLATFORM_)
int
cur_time
=
0
;
// 定时器当前时间戳
// 初始化OpenGL ES 2.0材质类型变量
ogles2Solid
=
0
;
ogles2Solid
=
0
;
ogles2TrasparentAlpha
=
0
;
ogles2TrasparentAlpha
=
0
;
ogles2BlendTexture
=
0
;
ogles2BlendTexture
=
0
;
// 根据GL版本选择是否使用内置或外部着色器文件
if
(
glversion
==
0
||
glversion
==
2
)
{
if
(
glversion
==
0
||
glversion
==
2
)
{
ogles2Solid
=
irr
::
video
::
EMT_SOLID
;
ogles2Solid
=
irr
::
video
::
EMT_SOLID
;
ogles2TrasparentAlpha
=
irr
::
video
::
EMT_TRANSPARENT_ALPHA_CHANNEL
;
ogles2TrasparentAlpha
=
irr
::
video
::
EMT_TRANSPARENT_ALPHA_CHANNEL
;
ogles2BlendTexture
=
irr
::
video
::
EMT_ONETEXTURE_BLEND
;
ogles2BlendTexture
=
irr
::
video
::
EMT_ONETEXTURE_BLEND
;
}
else
{
}
else
{
irr
::
io
::
path
solidvsFileName
=
"media/ogles2customsolid.frag"
;
// 着色器文件路径配置
irr
::
io
::
path
TACvsFileName
=
"media/ogles2customTAC.frag"
;
irr
::
io
::
path
solidvsFileName
=
"media/ogles2customsolid.frag"
;
irr
::
io
::
path
blendvsFileName
=
"media/ogles2customblend.frag"
;
irr
::
io
::
path
TACvsFileName
=
"media/ogles2customTAC.frag"
;
irr
::
io
::
path
psFileName
=
"media/ogles2custom.vert"
;
irr
::
io
::
path
blendvsFileName
=
"media/ogles2customblend.frag"
;
irr
::
io
::
path
psFileName
=
"media/ogles2custom.vert"
;
// 检查硬件是否支持像素着色器
if
(
!
driver
->
queryFeature
(
irr
::
video
::
EVDF_PIXEL_SHADER_1_1
)
&&
if
(
!
driver
->
queryFeature
(
irr
::
video
::
EVDF_PIXEL_SHADER_1_1
)
&&
!
driver
->
queryFeature
(
irr
::
video
::
EVDF_ARB_FRAGMENT_PROGRAM_1
))
!
driver
->
queryFeature
(
irr
::
video
::
EVDF_ARB_FRAGMENT_PROGRAM_1
))
{
{
ALOGD
(
"cc game: WARNING: Pixel shaders disabled because of missing driver/hardware support."
);
ALOGD
(
"cc game: WARNING: Pixel shaders disabled "
"because of missing driver/hardware support."
);
psFileName
=
""
;
psFileName
=
""
;
}
}
// 检查硬件是否支持顶点着色器
if
(
!
driver
->
queryFeature
(
irr
::
video
::
EVDF_VERTEX_SHADER_1_1
)
&&
if
(
!
driver
->
queryFeature
(
irr
::
video
::
EVDF_VERTEX_SHADER_1_1
)
&&
!
driver
->
queryFeature
(
irr
::
video
::
EVDF_ARB_VERTEX_PROGRAM_1
))
!
driver
->
queryFeature
(
irr
::
video
::
EVDF_ARB_VERTEX_PROGRAM_1
))
{
{
ALOGD
(
"cc game: WARNING: Vertex shaders disabled because of missing driver/hardware support."
);
ALOGD
(
"cc game: WARNING: Vertex shaders disabled "
"because of missing driver/hardware support."
);
solidvsFileName
=
""
;
solidvsFileName
=
""
;
TACvsFileName
=
""
;
TACvsFileName
=
""
;
blendvsFileName
=
""
;
blendvsFileName
=
""
;
}
}
irr
::
video
::
IGPUProgrammingServices
*
gpu
=
driver
->
getGPUProgrammingServices
();
// 加载高级着色器程序
irr
::
video
::
IGPUProgrammingServices
*
gpu
=
driver
->
getGPUProgrammingServices
();
if
(
gpu
)
{
if
(
gpu
)
{
const
irr
::
video
::
E_GPU_SHADING_LANGUAGE
shadingLanguage
=
irr
::
video
::
EGSL_DEFAULT
;
const
irr
::
video
::
E_GPU_SHADING_LANGUAGE
shadingLanguage
=
irr
::
video
::
EGSL_DEFAULT
;
ogles2Solid
=
gpu
->
addHighLevelShaderMaterialFromFiles
(
ogles2Solid
=
gpu
->
addHighLevelShaderMaterialFromFiles
(
psFileName
,
"vertexMain"
,
irr
::
video
::
EVST_VS_1_1
,
psFileName
,
"vertexMain"
,
irr
::
video
::
EVST_VS_1_1
,
solidvsFileName
,
"pixelMain"
,
irr
::
video
::
EPST_PS_1_1
,
solidvsFileName
,
"pixelMain"
,
irr
::
video
::
EPST_PS_1_1
,
&
customShadersCallback
,
irr
::
video
::
EMT_SOLID
,
0
,
shadingLanguage
);
&
customShadersCallback
,
irr
::
video
::
EMT_SOLID
,
0
,
shadingLanguage
);
ogles2TrasparentAlpha
=
gpu
->
addHighLevelShaderMaterialFromFiles
(
ogles2TrasparentAlpha
=
gpu
->
addHighLevelShaderMaterialFromFiles
(
psFileName
,
"vertexMain"
,
irr
::
video
::
EVST_VS_1_1
,
psFileName
,
"vertexMain"
,
irr
::
video
::
EVST_VS_1_1
,
TACvsFileName
,
"pixelMain"
,
irr
::
video
::
EPST_PS_1_1
,
TACvsFileName
,
"pixelMain"
,
irr
::
video
::
EPST_PS_1_1
,
&
customShadersCallback
,
irr
::
video
::
EMT_TRANSPARENT_ALPHA_CHANNEL
,
0
,
shadingLanguage
);
&
customShadersCallback
,
irr
::
video
::
EMT_TRANSPARENT_ALPHA_CHANNEL
,
0
,
shadingLanguage
);
ogles2BlendTexture
=
gpu
->
addHighLevelShaderMaterialFromFiles
(
ogles2BlendTexture
=
gpu
->
addHighLevelShaderMaterialFromFiles
(
psFileName
,
"vertexMain"
,
irr
::
video
::
EVST_VS_1_1
,
psFileName
,
"vertexMain"
,
irr
::
video
::
EVST_VS_1_1
,
blendvsFileName
,
"pixelMain"
,
irr
::
video
::
EPST_PS_1_1
,
blendvsFileName
,
"pixelMain"
,
irr
::
video
::
EPST_PS_1_1
,
&
customShadersCallback
,
irr
::
video
::
EMT_ONETEXTURE_BLEND
,
0
,
shadingLanguage
);
&
customShadersCallback
,
irr
::
video
::
EMT_ONETEXTURE_BLEND
,
0
,
shadingLanguage
);
ALOGD
(
"cc game:ogles2Sold = %d"
,
ogles2Solid
);
ALOGD
(
"cc game:ogles2Sold = %d"
,
ogles2Solid
);
ALOGD
(
"cc game:ogles2BlendTexture = %d"
,
ogles2BlendTexture
);
ALOGD
(
"cc game:ogles2BlendTexture = %d"
,
ogles2BlendTexture
);
ALOGD
(
"cc game:ogles2TrasparentAlpha = %d"
,
ogles2TrasparentAlpha
);
ALOGD
(
"cc game:ogles2TrasparentAlpha = %d"
,
ogles2TrasparentAlpha
);
}
}
}
}
matManager
.
mCard
.
MaterialType
=
(
irr
::
video
::
E_MATERIAL_TYPE
)
ogles2BlendTexture
;
matManager
.
mTexture
.
MaterialType
=
(
irr
::
video
::
E_MATERIAL_TYPE
)
ogles2TrasparentAlpha
;
// 将着色器材质应用至各个材质对象
matManager
.
mBackLine
.
MaterialType
=
(
irr
::
video
::
E_MATERIAL_TYPE
)
ogles2BlendTexture
;
// 设置卡片正面材质类型为混合纹理着色器
matManager
.
mSelField
.
MaterialType
=
(
irr
::
video
::
E_MATERIAL_TYPE
)
ogles2BlendTexture
;
matManager
.
mCard
.
MaterialType
=
(
irr
::
video
::
E_MATERIAL_TYPE
)
ogles2BlendTexture
;
matManager
.
mOutLine
.
MaterialType
=
(
irr
::
video
::
E_MATERIAL_TYPE
)
ogles2Solid
;
// 设置纹理材质类型为透明alpha通道着色器
matManager
.
mTRTexture
.
MaterialType
=
(
irr
::
video
::
E_MATERIAL_TYPE
)
ogles2TrasparentAlpha
;
matManager
.
mTexture
.
MaterialType
=
(
irr
::
video
::
E_MATERIAL_TYPE
)
ogles2TrasparentAlpha
;
matManager
.
mATK
.
MaterialType
=
(
irr
::
video
::
E_MATERIAL_TYPE
)
ogles2BlendTexture
;
// 设置背景线条材质类型为混合纹理着色器
matManager
.
mBackLine
.
MaterialType
=
(
irr
::
video
::
E_MATERIAL_TYPE
)
ogles2BlendTexture
;
// 设置选择区域材质类型为混合纹理着色器
matManager
.
mSelField
.
MaterialType
=
(
irr
::
video
::
E_MATERIAL_TYPE
)
ogles2BlendTexture
;
// 设置轮廓线材质类型为纯色着色器
matManager
.
mOutLine
.
MaterialType
=
(
irr
::
video
::
E_MATERIAL_TYPE
)
ogles2Solid
;
// 设置透明纹理材质类型为透明alpha通道着色器
matManager
.
mTRTexture
.
MaterialType
=
(
irr
::
video
::
E_MATERIAL_TYPE
)
ogles2TrasparentAlpha
;
// 设置攻击指示器材质类型为混合纹理着色器
matManager
.
mATK
.
MaterialType
=
(
irr
::
video
::
E_MATERIAL_TYPE
)
ogles2BlendTexture
;
// 若不支持非幂次纹理尺寸,则设置纹理环绕模式为边缘夹紧
if
(
!
isNPOTSupported
)
{
if
(
!
isNPOTSupported
)
{
matManager
.
mCard
.
TextureLayer
[
0
].
TextureWrapU
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
// 当不支持非2次幂纹理时,设置各个材质的纹理环绕模式为边缘夹紧(CLAMP_TO_EDGE)
matManager
.
mCard
.
TextureLayer
[
0
].
TextureWrapV
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
// 卡片正面材质的U轴和V轴纹理环绕模式设为边缘夹紧
matManager
.
mTexture
.
TextureLayer
[
0
].
TextureWrapU
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
matManager
.
mCard
.
TextureLayer
[
0
].
TextureWrapU
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
matManager
.
mTexture
.
TextureLayer
[
0
].
TextureWrapV
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
matManager
.
mCard
.
TextureLayer
[
0
].
TextureWrapV
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
matManager
.
mBackLine
.
TextureLayer
[
0
].
TextureWrapU
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
// 纹理材质的U轴和V轴纹理环绕模式设为边缘夹紧
matManager
.
mBackLine
.
TextureLayer
[
0
].
TextureWrapV
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
matManager
.
mTexture
.
TextureLayer
[
0
].
TextureWrapU
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
matManager
.
mSelField
.
TextureLayer
[
0
].
TextureWrapU
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
matManager
.
mTexture
.
TextureLayer
[
0
].
TextureWrapV
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
matManager
.
mSelField
.
TextureLayer
[
0
].
TextureWrapV
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
// 背景线条材质的U轴和V轴纹理环绕模式设为边缘夹紧
matManager
.
mOutLine
.
TextureLayer
[
0
].
TextureWrapU
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
matManager
.
mBackLine
.
TextureLayer
[
0
].
TextureWrapU
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
matManager
.
mOutLine
.
TextureLayer
[
0
].
TextureWrapV
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
matManager
.
mBackLine
.
TextureLayer
[
0
].
TextureWrapV
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
matManager
.
mTRTexture
.
TextureLayer
[
0
].
TextureWrapU
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
// 选择区域材质的U轴和V轴纹理环绕模式设为边缘夹紧
matManager
.
mTRTexture
.
TextureLayer
[
0
].
TextureWrapV
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
matManager
.
mSelField
.
TextureLayer
[
0
].
TextureWrapU
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
matManager
.
mATK
.
TextureLayer
[
0
].
TextureWrapU
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
matManager
.
mSelField
.
TextureLayer
[
0
].
TextureWrapV
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
matManager
.
mATK
.
TextureLayer
[
0
].
TextureWrapV
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
// 轮廓线材质的U轴和V轴纹理环绕模式设为边缘夹紧
matManager
.
mOutLine
.
TextureLayer
[
0
].
TextureWrapU
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
matManager
.
mOutLine
.
TextureLayer
[
0
].
TextureWrapV
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
// 透明纹理材质的U轴和V轴纹理环绕模式设为边缘夹紧
matManager
.
mTRTexture
.
TextureLayer
[
0
].
TextureWrapU
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
matManager
.
mTRTexture
.
TextureLayer
[
0
].
TextureWrapV
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
// 攻击指示器材质的U轴和V轴纹理环绕模式设为边缘夹紧
matManager
.
mATK
.
TextureLayer
[
0
].
TextureWrapU
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
matManager
.
mATK
.
TextureLayer
[
0
].
TextureWrapV
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
}
}
#endif
// 主循环开始:持续运行直到窗口关闭
while
(
device
->
run
())
{
while
(
device
->
run
())
{
//ALOGV("cc game draw frame");
linePatternD3D
=
(
linePatternD3D
+
1
)
%
30
;
// 更新线条图案索引(Direct3D风格)
linePatternD3D
=
(
linePatternD3D
+
1
)
%
30
;
linePatternGL
=
(
linePatternGL
<<
1
)
|
(
linePatternGL
>>
15
);
// 更新线条图案掩码(OpenGL风格)
linePatternGL
=
(
linePatternGL
<<
1
)
|
(
linePatternGL
>>
15
);
atkframe
+=
0.1
f
;
atkframe
+=
0.1
f
;
// 增加动画帧计数
atkdy
=
(
float
)
sin
(
atkframe
);
atkdy
=
(
float
)
sin
(
atkframe
);
// 计算攻击动作偏移量
// 开始渲染场景
driver
->
beginScene
(
true
,
true
,
irr
::
video
::
SColor
(
0
,
0
,
0
,
0
));
driver
->
beginScene
(
true
,
true
,
irr
::
video
::
SColor
(
0
,
0
,
0
,
0
));
#ifdef _IRR_ANDROID_PLATFORM_
// 设置2D材质并启用2D渲染
driver
->
getMaterial2D
().
MaterialType
=
(
irr
::
video
::
E_MATERIAL_TYPE
)
ogles2Solid
;
driver
->
getMaterial2D
().
MaterialType
=
(
irr
::
video
::
E_MATERIAL_TYPE
)
ogles2Solid
;
if
(
!
isNPOTSupported
)
{
if
(
!
isNPOTSupported
)
{
driver
->
getMaterial2D
().
TextureLayer
[
0
].
TextureWrapU
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
driver
->
getMaterial2D
().
TextureLayer
[
0
].
TextureWrapU
=
irr
::
video
::
ETC_CLAMP_TO_EDGE
;
...
@@ -1438,88 +1565,121 @@ void Game::MainLoop() {
...
@@ -1438,88 +1565,121 @@ void Game::MainLoop() {
}
}
driver
->
enableMaterial2D
(
true
);
driver
->
enableMaterial2D
(
true
);
driver
->
getMaterial2D
().
ZBuffer
=
irr
::
video
::
ECFN_NEVER
;
driver
->
getMaterial2D
().
ZBuffer
=
irr
::
video
::
ECFN_NEVER
;
// 绘制背景图像
if
(
imageManager
.
tBackGround
)
{
if
(
imageManager
.
tBackGround
)
{
driver
->
draw2DImage
(
imageManager
.
tBackGround
,
Resize
(
0
,
0
,
GAME_WIDTH
,
GAME_HEIGHT
),
irr
::
core
::
recti
(
0
,
0
,
imageManager
.
tBackGround
->
getOriginalSize
().
Width
,
imageManager
.
tBackGround
->
getOriginalSize
().
Height
));
driver
->
draw2DImage
(
imageManager
.
tBackGround
,
Resize
(
0
,
0
,
GAME_WIDTH
,
GAME_HEIGHT
),
irr
::
core
::
recti
(
0
,
0
,
imageManager
.
tBackGround
->
getOriginalSize
().
Width
,
imageManager
.
tBackGround
->
getOriginalSize
().
Height
));
}
}
if
(
imageManager
.
tBackGround_menu
)
{
if
(
imageManager
.
tBackGround_menu
)
{
driver
->
draw2DImage
(
imageManager
.
tBackGround_menu
,
Resize
(
0
,
0
,
GAME_WIDTH
,
GAME_HEIGHT
),
irr
::
core
::
recti
(
0
,
0
,
imageManager
.
tBackGround
->
getOriginalSize
().
Width
,
imageManager
.
tBackGround
->
getOriginalSize
().
Height
));
driver
->
draw2DImage
(
imageManager
.
tBackGround_menu
,
Resize
(
0
,
0
,
GAME_WIDTH
,
GAME_HEIGHT
),
irr
::
core
::
recti
(
0
,
0
,
imageManager
.
tBackGround
->
getOriginalSize
().
Width
,
imageManager
.
tBackGround
->
getOriginalSize
().
Height
));
}
}
if
(
imageManager
.
tBackGround_deck
)
{
if
(
imageManager
.
tBackGround_deck
)
{
driver
->
draw2DImage
(
imageManager
.
tBackGround_deck
,
Resize
(
0
,
0
,
GAME_WIDTH
,
GAME_HEIGHT
),
irr
::
core
::
recti
(
0
,
0
,
imageManager
.
tBackGround
->
getOriginalSize
().
Width
,
imageManager
.
tBackGround
->
getOriginalSize
().
Height
));
driver
->
draw2DImage
(
imageManager
.
tBackGround_deck
,
Resize
(
0
,
0
,
GAME_WIDTH
,
GAME_HEIGHT
),
irr
::
core
::
recti
(
0
,
0
,
imageManager
.
tBackGround
->
getOriginalSize
().
Width
,
imageManager
.
tBackGround
->
getOriginalSize
().
Height
));
}
}
driver
->
enableMaterial2D
(
false
);
driver
->
enableMaterial2D
(
false
);
// 多线程保护:锁定互斥锁防止并发修改共享资源
gMutex
.
lock
();
gMutex
.
lock
();
// 根据不同状态绘制对应内容
if
(
dInfo
.
isStarted
)
{
if
(
dInfo
.
isStarted
)
{
DrawBackImage
(
imageManager
.
tBackGround
);
DrawBackImage
(
imageManager
.
tBackGround
);
// 背景图片
DrawBackGround
();
DrawBackGround
();
// 场地背景
DrawCards
();
DrawCards
();
// 所有卡牌
DrawMisc
();
DrawMisc
();
// 其他元素
smgr
->
drawAll
();
smgr
->
drawAll
();
// 渲染所有3D场景节点
driver
->
setMaterial
(
irr
::
video
::
IdentityMaterial
);
driver
->
setMaterial
(
irr
::
video
::
IdentityMaterial
);
driver
->
clearZBuffer
();
driver
->
clearZBuffer
();
// 清除深度缓存
}
else
if
(
is_building
)
{
}
else
if
(
is_building
)
{
DrawBackImage
(
imageManager
.
tBackGround_deck
);
DrawBackImage
(
imageManager
.
tBackGround_deck
);
// 牌组编辑界面背景
driver
->
enableMaterial2D
(
true
);
driver
->
enableMaterial2D
(
true
);
DrawDeckBd
();
DrawDeckBd
();
// 绘制牌组边框
driver
->
enableMaterial2D
(
false
);
driver
->
enableMaterial2D
(
false
);
}
else
{
}
else
{
DrawBackImage
(
imageManager
.
tBackGround_menu
);
DrawBackImage
(
imageManager
.
tBackGround_menu
);
// 菜单界面背景
}
}
// 绘制用户界面及特殊效果
driver
->
enableMaterial2D
(
true
);
driver
->
enableMaterial2D
(
true
);
DrawGUI
();
DrawGUI
();
// UI组件
DrawSpec
();
DrawSpec
();
// 特效相关
driver
->
enableMaterial2D
(
false
);
driver
->
enableMaterial2D
(
false
);
gMutex
.
unlock
();
playBGM
();
gMutex
.
unlock
();
// 解锁互斥锁
playBGM
();
// 播放背景音乐
// 控制信号帧倒计时
if
(
signalFrame
>
0
)
{
if
(
signalFrame
>
0
)
{
signalFrame
--
;
signalFrame
--
;
if
(
!
signalFrame
)
if
(
!
signalFrame
)
frameSignal
.
Set
();
frameSignal
.
Set
();
// 发送信号通知其他线程
}
}
// 显示等待提示消息
if
(
waitFrame
>=
0
)
{
if
(
waitFrame
>=
0
)
{
waitFrame
++
;
waitFrame
++
;
if
(
waitFrame
%
90
==
0
)
{
if
(
waitFrame
%
90
==
0
)
{
stHintMsg
->
setText
(
dataManager
.
GetSysString
(
1390
));
stHintMsg
->
setText
(
dataManager
.
GetSysString
(
1390
));
// 提示文字1
}
else
if
(
waitFrame
%
90
==
30
)
{
}
else
if
(
waitFrame
%
90
==
30
)
{
stHintMsg
->
setText
(
dataManager
.
GetSysString
(
1391
));
stHintMsg
->
setText
(
dataManager
.
GetSysString
(
1391
));
// 提示文字2
}
else
if
(
waitFrame
%
90
==
60
)
{
}
else
if
(
waitFrame
%
90
==
60
)
{
stHintMsg
->
setText
(
dataManager
.
GetSysString
(
1392
));
stHintMsg
->
setText
(
dataManager
.
GetSysString
(
1392
));
// 提示文字3
}
}
}
}
driver
->
endScene
();
driver
->
endScene
();
// 结束渲染过程
// 检查是否需要退出对战窗口
if
(
closeSignal
.
Wait
(
1
))
if
(
closeSignal
.
Wait
(
1
))
CloseDuelWindow
();
CloseDuelWindow
();
fps
++
;
cur_time
=
timer
->
getTime
();
fps
++
;
// 帧计数增加
cur_time
=
timer
->
getTime
();
// 获取当前时间
// 控制帧率为约60FPS(每帧最大延迟20毫秒)
if
(
cur_time
<
fps
*
17
-
20
)
if
(
cur_time
<
fps
*
17
-
20
)
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
milliseconds
(
20
));
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
milliseconds
(
20
));
// 每秒钟更新一次FPS显示和剩余时间
if
(
cur_time
>=
1000
)
{
if
(
cur_time
>=
1000
)
{
if
(
stat
)
{
if
(
stat
)
{
irr
::
core
::
stringw
str
=
L"FPS: "
;
irr
::
core
::
stringw
str
=
L"FPS: "
;
str
+=
(
irr
::
s32
)
device
->
getVideoDriver
()
->
getFPS
();
str
+=
(
irr
::
s32
)
device
->
getVideoDriver
()
->
getFPS
();
stat
->
setText
(
str
.
c_str
()
);
stat
->
setText
(
str
.
c_str
()
);
}
}
fps
=
0
;
fps
=
0
;
cur_time
-=
1000
;
cur_time
-=
1000
;
timer
->
setTime
(
0
);
timer
->
setTime
(
0
);
// 更新玩家剩余时间
if
(
dInfo
.
time_player
==
0
||
dInfo
.
time_player
==
1
)
if
(
dInfo
.
time_player
==
0
||
dInfo
.
time_player
==
1
)
if
(
dInfo
.
time_left
[
dInfo
.
time_player
])
{
if
(
dInfo
.
time_left
[
dInfo
.
time_player
])
{
dInfo
.
time_left
[
dInfo
.
time_player
]
--
;
dInfo
.
time_left
[
dInfo
.
time_player
]
--
;
RefreshTimeDisplay
();
RefreshTimeDisplay
();
}
}
}
}
device
->
yield
();
// probably nicer to the battery
#endif
device
->
yield
();
// 礼让CPU,节省电池电量
}
}
// 游戏结束后的清理工作
DuelClient
::
StopClient
(
true
);
DuelClient
::
StopClient
(
true
);
if
(
dInfo
.
isSingleMode
)
if
(
dInfo
.
isSingleMode
)
SingleMode
::
StopPlay
(
true
);
SingleMode
::
StopPlay
(
true
);
usleep
(
500000
);
usleep
(
500000
);
// 等待半秒后保存配置
SaveConfig
();
SaveConfig
();
usleep
(
500000
);
usleep
(
500000
);
// 再等待半秒后释放设备资源
device
->
drop
();
device
->
drop
();
}
}
void
Game
::
RefreshTimeDisplay
()
{
void
Game
::
RefreshTimeDisplay
()
{
for
(
int
i
=
0
;
i
<
2
;
++
i
)
{
for
(
int
i
=
0
;
i
<
2
;
++
i
)
{
if
(
dInfo
.
time_left
[
i
]
&&
dInfo
.
time_limit
)
{
if
(
dInfo
.
time_left
[
i
]
&&
dInfo
.
time_limit
)
{
...
@@ -1611,7 +1771,6 @@ std::wstring Game::SetStaticText(irr::gui::IGUIStaticText* pControl, irr::u32 cW
...
@@ -1611,7 +1771,6 @@ std::wstring Game::SetStaticText(irr::gui::IGUIStaticText* pControl, irr::u32 cW
}
}
void
Game
::
LoadExpansions
()
{
void
Game
::
LoadExpansions
()
{
// TODO: get isUseExtraCards
// TODO: get isUseExtraCards
#ifdef _IRR_ANDROID_PLATFORM_
DIR
*
dir
;
DIR
*
dir
;
struct
dirent
*
dirp
;
struct
dirent
*
dirp
;
if
((
dir
=
opendir
(
"./expansions/"
))
==
NULL
)
if
((
dir
=
opendir
(
"./expansions/"
))
==
NULL
)
...
@@ -1625,7 +1784,7 @@ void Game::LoadExpansions() {
...
@@ -1625,7 +1784,7 @@ void Game::LoadExpansions() {
dataManager
.
FileSystem
->
addFileArchive
(
upath
,
true
,
false
,
EFAT_ZIP
);
dataManager
.
FileSystem
->
addFileArchive
(
upath
,
true
,
false
,
EFAT_ZIP
);
}
}
closedir
(
dir
);
closedir
(
dir
);
#endif
for
(
irr
::
u32
i
=
0
;
i
<
dataManager
.
FileSystem
->
getFileArchiveCount
();
++
i
)
{
for
(
irr
::
u32
i
=
0
;
i
<
dataManager
.
FileSystem
->
getFileArchiveCount
();
++
i
)
{
auto
archive
=
dataManager
.
FileSystem
->
getFileArchive
(
i
)
->
getFileList
();
auto
archive
=
dataManager
.
FileSystem
->
getFileArchive
(
i
)
->
getFileList
();
for
(
irr
::
u32
j
=
0
;
j
<
archive
->
getFileCount
();
++
j
)
{
for
(
irr
::
u32
j
=
0
;
j
<
archive
->
getFileCount
();
++
j
)
{
...
...
Classes/ocgcore/processor.cpp
View file @
eb028f4b
...
@@ -662,78 +662,77 @@ uint32_t field::process() {
...
@@ -662,78 +662,77 @@ uint32_t field::process() {
return
pduel
->
buffer_size
();
return
pduel
->
buffer_size
();
}
}
case
PROCESSOR_SORT_DECK
:
{
case
PROCESSOR_SORT_DECK
:
{
// 从参数中提取排序玩家、目标玩家和卡片数量
// 从参数中提取排序玩家、目标玩家和卡片数量
uint8_t
sort_player
=
it
->
arg1
&
0xffff
;
// 执行排序的玩家
uint8_t
sort_player
=
it
->
arg1
&
0xffff
;
// 执行排序的玩家
uint8_t
target_player
=
it
->
arg1
>>
16
;
// 被排序卡组的玩家
uint8_t
target_player
=
it
->
arg1
>>
16
;
// 被排序卡组的玩家
uint8_t
count
=
it
->
arg2
,
i
=
0
;
// 需要排序的卡片数量,循环变量初始化
uint8_t
count
=
it
->
arg2
,
i
=
0
;
// 需要排序的卡片数量,循环变量初始化
// 如果要求排序的数量超过目标玩家主卡组的实际数量,则调整为实际数量
// 如果要求排序的数量超过目标玩家主卡组的实际数量,则调整为实际数量
if
(
count
>
player
[
target_player
].
list_main
.
size
())
if
(
count
>
player
[
target_player
].
list_main
.
size
())
count
=
(
uint8_t
)
player
[
target_player
].
list_main
.
size
();
count
=
(
uint8_t
)
player
[
target_player
].
list_main
.
size
();
// 第一步:准备需要排序的卡片并启动排序处理器
// 第一步:准备需要排序的卡片并启动排序处理器
if
(
it
->
step
==
0
)
{
if
(
it
->
step
==
0
)
{
core
.
select_cards
.
clear
();
// 清空选择卡片列表
core
.
select_cards
.
clear
();
// 清空选择卡片列表
// 从目标玩家主卡组末尾开始,取count张卡片加入选择列表
// 从目标玩家主卡组末尾开始,取count张卡片加入选择列表
for
(
auto
clit
=
player
[
target_player
].
list_main
.
rbegin
();
i
<
count
;
++
i
,
++
clit
)
for
(
auto
clit
=
player
[
target_player
].
list_main
.
rbegin
();
i
<
count
;
++
i
,
++
clit
)
core
.
select_cards
.
push_back
(
*
clit
);
core
.
select_cards
.
push_back
(
*
clit
);
// 添加卡片排序处理器,让sort_player对这些卡片进行排序
// 添加卡片排序处理器,让sort_player对这些卡片进行排序
add_process
(
PROCESSOR_SORT_CARD
,
0
,
0
,
0
,
sort_player
,
0
);
add_process
(
PROCESSOR_SORT_CARD
,
0
,
0
,
0
,
sort_player
,
0
);
++
it
->
step
;
// 进入下一步
++
it
->
step
;
// 进入下一步
}
else
{
}
else
{
// 第二步:处理排序结果
// 第二步:处理排序结果
// 如果返回值不是0xff(表示排序未被取消)
// 如果返回值不是0xff(表示排序未被取消)
if
(
returns
.
bvalue
[
0
]
!=
0xff
)
{
if
(
returns
.
bvalue
[
0
]
!=
0xff
)
{
card
*
tc
[
256
];
// 临时卡片数组,用于存储重新排序后的卡片
card
*
tc
[
256
];
// 临时卡片数组,用于存储重新排序后的卡片
// 从目标玩家主卡组中移除之前取出的count张卡片
// 从目标玩家主卡组中移除之前取出的count张卡片
for
(
i
=
0
;
i
<
count
;
++
i
)
for
(
i
=
0
;
i
<
count
;
++
i
)
player
[
target_player
].
list_main
.
pop_back
();
player
[
target_player
].
list_main
.
pop_back
();
// 根据玩家的排序结果,将卡片放入临时数组的正确位置
// 根据玩家的排序结果,将卡片放入临时数组的正确位置
for
(
i
=
0
;
i
<
count
;
++
i
)
for
(
i
=
0
;
i
<
count
;
++
i
)
tc
[
returns
.
bvalue
[
i
]]
=
core
.
select_cards
[
i
];
tc
[
returns
.
bvalue
[
i
]]
=
core
.
select_cards
[
i
];
// 按照新的顺序将卡片重新放入目标玩家的主卡组
// 按照新的顺序将卡片重新放入目标玩家的主卡组
for
(
i
=
0
;
i
<
count
;
++
i
)
{
for
(
i
=
0
;
i
<
count
;
++
i
)
{
player
[
target_player
].
list_main
.
push_back
(
tc
[
count
-
1
-
i
]);
player
[
target_player
].
list_main
.
push_back
(
tc
[
count
-
1
-
i
]);
}
}
// 重置目标玩家主卡组中所有卡片的序列号
// 重置目标玩家主卡组中所有卡片的序列号
reset_sequence
(
target_player
,
LOCATION_DECK
);
reset_sequence
(
target_player
,
LOCATION_DECK
);
// 从卡组末尾开始遍历刚重新排序的卡片
// 从卡组末尾开始遍历刚重新排序的卡片
auto
clit
=
player
[
target_player
].
list_main
.
rbegin
();
auto
clit
=
player
[
target_player
].
list_main
.
rbegin
();
for
(
i
=
0
;
i
<
count
;
++
i
,
++
clit
)
{
for
(
i
=
0
;
i
<
count
;
++
i
,
++
clit
)
{
card
*
pcard
=
*
clit
;
card
*
pcard
=
*
clit
;
// 向客户端发送卡片移动消息(虽然位置未变,但用于同步排序结果)
// 向客户端发送卡片移动消息(虽然位置未变,但用于同步排序结果)
pduel
->
write_buffer8
(
MSG_MOVE
);
pduel
->
write_buffer8
(
MSG_MOVE
);
pduel
->
write_buffer32
(
0
);
// 原位置(这里用0表示无来源)
pduel
->
write_buffer32
(
0
);
// 原位置(这里用0表示无来源)
pduel
->
write_buffer32
(
pcard
->
get_info_location
());
// 当前位置
pduel
->
write_buffer32
(
pcard
->
get_info_location
());
// 当前位置
pduel
->
write_buffer32
(
pcard
->
get_info_location
());
// 目标位置
pduel
->
write_buffer32
(
pcard
->
get_info_location
());
// 目标位置
pduel
->
write_buffer32
(
REASON_EFFECT
);
// 移动原因
pduel
->
write_buffer32
(
REASON_EFFECT
);
// 移动原因
}
}
}
}
// 如果启用了卡组顶部检查的全局标志
// 如果启用了卡组顶部检查的全局标志
if
(
core
.
global_flag
&
GLOBALFLAG_DECK_REVERSE_CHECK
)
{
if
(
core
.
global_flag
&
GLOBALFLAG_DECK_REVERSE_CHECK
)
{
// 如果有卡片被排序
// 如果有卡片被排序
if
(
count
>
0
)
{
if
(
count
>
0
)
{
// 获取目标玩家主卡组最上面的卡片
// 获取目标玩家主卡组最上面的卡片
card
*
ptop
=
player
[
target_player
].
list_main
.
back
();
card
*
ptop
=
player
[
target_player
].
list_main
.
back
();
// 如果卡组是翻转状态或者最上面的卡片是表侧守备表示
// 如果卡组是翻转状态或者最上面的卡片是表侧守备表示
if
(
core
.
deck_reversed
||
(
ptop
->
current
.
position
==
POS_FACEUP_DEFENSE
))
{
if
(
core
.
deck_reversed
||
(
ptop
->
current
.
position
==
POS_FACEUP_DEFENSE
))
{
// 向客户端发送卡组顶部卡片信息
// 向客户端发送卡组顶部卡片信息
pduel
->
write_buffer8
(
MSG_DECK_TOP
);
pduel
->
write_buffer8
(
MSG_DECK_TOP
);
pduel
->
write_buffer8
(
target_player
);
// 玩家
pduel
->
write_buffer8
(
target_player
);
// 玩家
pduel
->
write_buffer8
(
0
);
// 序号(0表示最上面)
pduel
->
write_buffer8
(
0
);
// 序号(0表示最上面)
// 根据卡片位置发送卡片密码
// 根据卡片位置发送卡片密码
if
(
ptop
->
current
.
position
!=
POS_FACEUP_DEFENSE
)
if
(
ptop
->
current
.
position
!=
POS_FACEUP_DEFENSE
)
pduel
->
write_buffer32
(
ptop
->
data
.
code
);
// 里侧表示
pduel
->
write_buffer32
(
ptop
->
data
.
code
);
// 里侧表示
else
else
pduel
->
write_buffer32
(
ptop
->
data
.
code
|
0x80000000
);
// 表侧表示
pduel
->
write_buffer32
(
ptop
->
data
.
code
|
0x80000000
);
// 表侧表示
}
}
}
}
}
core
.
units
.
pop_front
();
// 移除当前处理单元
}
}
core
.
units
.
pop_front
();
// 移除当前处理单元
return
pduel
->
buffer_size
();
// 返回缓冲区大小
}
}
return
pduel
->
buffer_size
();
// 返回缓冲区大小
}
case
PROCESSOR_REMOVE_OVERLAY
:
{
case
PROCESSOR_REMOVE_OVERLAY
:
{
if
(
remove_overlay_card
(
it
->
step
,
it
->
arg3
,
(
card
*
)(
it
->
ptarget
),
it
->
arg1
>>
16
,
if
(
remove_overlay_card
(
it
->
step
,
it
->
arg3
,
(
card
*
)(
it
->
ptarget
),
it
->
arg1
>>
16
,
(
it
->
arg1
>>
8
)
&
0xff
,
it
->
arg1
&
0xff
,
it
->
arg2
&
0xffff
,
it
->
arg2
>>
16
))
{
(
it
->
arg1
>>
8
)
&
0xff
,
it
->
arg1
&
0xff
,
it
->
arg2
&
0xffff
,
it
->
arg2
>>
16
))
{
...
@@ -4017,34 +4016,58 @@ int32_t field::process_turn(uint16_t step, uint8_t turn_player) {
...
@@ -4017,34 +4016,58 @@ int32_t field::process_turn(uint16_t step, uint8_t turn_player) {
}
}
return
TRUE
;
return
TRUE
;
}
}
/**
* @brief 处理连锁的添加过程
*
* 该函数负责将新发动的效果添加到连锁中,包括处理发动cost、移动卡片、设置连锁状态等操作。
* 连锁添加过程分为多个步骤,每个步骤处理不同的阶段,如cost处理、位置调整、取对象选择等。
*
* @param step 当前处理步骤
* @return int32_t 处理结果,TRUE表示处理完成,FALSE表示需要继续处理
*/
int32_t
field
::
add_chain
(
uint16_t
step
)
{
int32_t
field
::
add_chain
(
uint16_t
step
)
{
switch
(
step
)
{
switch
(
step
)
{
case
0
:
{
case
0
:
{
// 如果没有新的连锁需要处理,则直接返回TRUE结束
if
(
!
core
.
new_chains
.
size
())
if
(
!
core
.
new_chains
.
size
())
return
TRUE
;
return
TRUE
;
// 获取第一个待处理的连锁
auto
&
clit
=
core
.
new_chains
.
front
();
auto
&
clit
=
core
.
new_chains
.
front
();
effect
*
peffect
=
clit
.
triggering_effect
;
effect
*
peffect
=
clit
.
triggering_effect
;
// 获取发动的效果
card
*
phandler
=
peffect
->
get_handler
();
card
*
phandler
=
peffect
->
get_handler
();
// 获取效果持有者卡片
// 处理发动cost(EFFECT_ACTIVATE_COST)
effect_set
eset
;
effect_set
eset
;
filter_player_effect
(
clit
.
triggering_player
,
EFFECT_ACTIVATE_COST
,
&
eset
);
filter_player_effect
(
clit
.
triggering_player
,
EFFECT_ACTIVATE_COST
,
&
eset
);
for
(
effect_set
::
size_type
i
=
0
;
i
<
eset
.
size
();
++
i
)
{
for
(
effect_set
::
size_type
i
=
0
;
i
<
eset
.
size
();
++
i
)
{
// 添加参数并检查条件
pduel
->
lua
->
add_param
(
eset
[
i
],
PARAM_TYPE_EFFECT
);
pduel
->
lua
->
add_param
(
eset
[
i
],
PARAM_TYPE_EFFECT
);
pduel
->
lua
->
add_param
(
clit
.
triggering_effect
,
PARAM_TYPE_EFFECT
);
pduel
->
lua
->
add_param
(
clit
.
triggering_effect
,
PARAM_TYPE_EFFECT
);
pduel
->
lua
->
add_param
(
clit
.
triggering_player
,
PARAM_TYPE_INT
);
pduel
->
lua
->
add_param
(
clit
.
triggering_player
,
PARAM_TYPE_INT
);
if
(
!
pduel
->
lua
->
check_condition
(
eset
[
i
]
->
target
,
3
))
if
(
!
pduel
->
lua
->
check_condition
(
eset
[
i
]
->
target
,
3
))
continue
;
continue
;
// 如果有条件且有操作,则执行操作
if
(
eset
[
i
]
->
operation
)
{
if
(
eset
[
i
]
->
operation
)
{
core
.
sub_solving_event
.
push_back
(
clit
.
evt
);
core
.
sub_solving_event
.
push_back
(
clit
.
evt
);
add_process
(
PROCESSOR_EXECUTE_OPERATION
,
0
,
eset
[
i
],
0
,
clit
.
triggering_player
,
0
);
add_process
(
PROCESSOR_EXECUTE_OPERATION
,
0
,
eset
[
i
],
0
,
clit
.
triggering_player
,
0
);
}
}
}
}
// 如果是卡的发动类型的效果
if
(
peffect
->
type
&
EFFECT_TYPE_ACTIVATE
)
{
if
(
peffect
->
type
&
EFFECT_TYPE_ACTIVATE
)
{
// 获取手牌或场地设置所需的效果
if
(
peffect
->
get_required_handorset_effects
(
&
clit
.
required_handorset_effects
,
clit
.
triggering_player
,
clit
.
evt
)
!=
2
)
{
if
(
peffect
->
get_required_handorset_effects
(
&
clit
.
required_handorset_effects
,
clit
.
triggering_player
,
clit
.
evt
)
!=
2
)
{
clit
.
required_handorset_effects
.
clear
();
clit
.
required_handorset_effects
.
clear
();
}
}
// 如果卡片在手牌中
if
(
phandler
->
current
.
location
==
LOCATION_HAND
)
{
if
(
phandler
->
current
.
location
==
LOCATION_HAND
)
{
uint32_t
zone
=
0xff
;
uint32_t
zone
=
0xff
;
// 默认可放置区域
// 如果不是场地卡或钟摆卡,且有限制区域标志
if
(
!
(
phandler
->
data
.
type
&
(
TYPE_FIELD
|
TYPE_PENDULUM
))
&&
peffect
->
is_flag
(
EFFECT_FLAG_LIMIT_ZONE
))
{
if
(
!
(
phandler
->
data
.
type
&
(
TYPE_FIELD
|
TYPE_PENDULUM
))
&&
peffect
->
is_flag
(
EFFECT_FLAG_LIMIT_ZONE
))
{
// 添加参数计算可用区域
pduel
->
lua
->
add_param
(
clit
.
triggering_player
,
PARAM_TYPE_INT
);
pduel
->
lua
->
add_param
(
clit
.
triggering_player
,
PARAM_TYPE_INT
);
pduel
->
lua
->
add_param
(
clit
.
evt
.
event_cards
,
PARAM_TYPE_GROUP
);
pduel
->
lua
->
add_param
(
clit
.
evt
.
event_cards
,
PARAM_TYPE_GROUP
);
pduel
->
lua
->
add_param
(
clit
.
evt
.
event_player
,
PARAM_TYPE_INT
);
pduel
->
lua
->
add_param
(
clit
.
evt
.
event_player
,
PARAM_TYPE_INT
);
...
@@ -4056,12 +4079,19 @@ int32_t field::add_chain(uint16_t step) {
...
@@ -4056,12 +4079,19 @@ int32_t field::add_chain(uint16_t step) {
if
(
!
zone
)
if
(
!
zone
)
zone
=
0xff
;
zone
=
0xff
;
}
}
// 禁用手牌效果,设置从手发动状态
phandler
->
enable_field_effect
(
false
);
phandler
->
enable_field_effect
(
false
);
phandler
->
set_status
(
STATUS_ACT_FROM_HAND
,
TRUE
);
phandler
->
set_status
(
STATUS_ACT_FROM_HAND
,
TRUE
);
// 场地卡只能放在特定区域
if
(
phandler
->
data
.
type
&
TYPE_FIELD
)
if
(
phandler
->
data
.
type
&
TYPE_FIELD
)
zone
=
0x1U
<<
5
;
zone
=
0x1U
<<
5
;
// 移动卡片到场上
move_to_field
(
phandler
,
phandler
->
current
.
controler
,
phandler
->
current
.
controler
,
LOCATION_SZONE
,
POS_FACEUP
,
FALSE
,
0
,
(
phandler
->
data
.
type
&
TYPE_PENDULUM
)
?
TRUE
:
FALSE
,
zone
);
move_to_field
(
phandler
,
phandler
->
current
.
controler
,
phandler
->
current
.
controler
,
LOCATION_SZONE
,
POS_FACEUP
,
FALSE
,
0
,
(
phandler
->
data
.
type
&
TYPE_PENDULUM
)
?
TRUE
:
FALSE
,
zone
);
}
else
{
}
else
{
// 如果不在手牌中,清除从手牌发动状态,并改为表侧表示
phandler
->
set_status
(
STATUS_ACT_FROM_HAND
,
FALSE
);
phandler
->
set_status
(
STATUS_ACT_FROM_HAND
,
FALSE
);
change_position
(
phandler
,
0
,
phandler
->
current
.
controler
,
POS_FACEUP
,
0
);
change_position
(
phandler
,
0
,
phandler
->
current
.
controler
,
POS_FACEUP
,
0
);
}
}
...
@@ -4069,32 +4099,47 @@ int32_t field::add_chain(uint16_t step) {
...
@@ -4069,32 +4099,47 @@ int32_t field::add_chain(uint16_t step) {
return
FALSE
;
return
FALSE
;
}
}
case
1
:
{
case
1
:
{
// 获取当前处理的连锁
auto
&
clit
=
core
.
new_chains
.
front
();
auto
&
clit
=
core
.
new_chains
.
front
();
effect
*
peffect
=
clit
.
triggering_effect
;
effect
*
peffect
=
clit
.
triggering_effect
;
card
*
phandler
=
peffect
->
get_handler
();
card
*
phandler
=
peffect
->
get_handler
();
// 刷新卡片的禁用状态
phandler
->
refresh_disable_status
();
phandler
->
refresh_disable_status
();
// 如果是卡的发动类型效果,更新发动状态
if
(
peffect
->
type
&
EFFECT_TYPE_ACTIVATE
)
{
if
(
peffect
->
type
&
EFFECT_TYPE_ACTIVATE
)
{
clit
.
set_triggering_state
(
phandler
);
clit
.
set_triggering_state
(
phandler
);
}
}
// 向客户端发送连锁消息
pduel
->
write_buffer8
(
MSG_CHAINING
);
pduel
->
write_buffer8
(
MSG_CHAINING
);
pduel
->
write_buffer32
(
phandler
->
data
.
code
);
pduel
->
write_buffer32
(
phandler
->
data
.
code
);
// 卡片密码
pduel
->
write_buffer32
(
phandler
->
get_info_location
());
pduel
->
write_buffer32
(
phandler
->
get_info_location
());
// 卡片位置
pduel
->
write_buffer8
(
clit
.
triggering_controler
);
pduel
->
write_buffer8
(
clit
.
triggering_controler
);
// 诱发的玩家
pduel
->
write_buffer8
((
uint8_t
)
clit
.
triggering_location
);
pduel
->
write_buffer8
((
uint8_t
)
clit
.
triggering_location
);
// 诱发位置
pduel
->
write_buffer8
(
clit
.
triggering_sequence
);
pduel
->
write_buffer8
(
clit
.
triggering_sequence
);
// 诱发序号
pduel
->
write_buffer32
(
peffect
->
description
);
pduel
->
write_buffer32
(
peffect
->
description
);
// 效果描述
pduel
->
write_buffer8
((
uint8_t
)
core
.
current_chain
.
size
()
+
1
);
pduel
->
write_buffer8
((
uint8_t
)
core
.
current_chain
.
size
()
+
1
);
// 连锁序号
// 清除连锁限制
for
(
auto
&
ch_lim
:
core
.
chain_limit
)
for
(
auto
&
ch_lim
:
core
.
chain_limit
)
luaL_unref
(
pduel
->
lua
->
lua_state
,
LUA_REGISTRYINDEX
,
ch_lim
.
function
);
luaL_unref
(
pduel
->
lua
->
lua_state
,
LUA_REGISTRYINDEX
,
ch_lim
.
function
);
core
.
chain_limit
.
clear
();
core
.
chain_limit
.
clear
();
// 设置效果类型
peffect
->
card_type
=
phandler
->
get_type
();
peffect
->
card_type
=
phandler
->
get_type
();
if
((
peffect
->
card_type
&
(
TYPE_TRAP
|
TYPE_MONSTER
))
==
(
TYPE_TRAP
|
TYPE_MONSTER
))
if
((
peffect
->
card_type
&
(
TYPE_TRAP
|
TYPE_MONSTER
))
==
(
TYPE_TRAP
|
TYPE_MONSTER
))
peffect
->
card_type
-=
TYPE_TRAP
;
peffect
->
card_type
-=
TYPE_TRAP
;
peffect
->
set_active_type
();
peffect
->
set_active_type
();
// 处理叠置素材效果
if
(
peffect
->
type
&
EFFECT_TYPE_XMATERIAL
)
{
if
(
peffect
->
type
&
EFFECT_TYPE_XMATERIAL
)
{
peffect
->
active_handler
=
peffect
->
handler
->
overlay_target
;
peffect
->
active_handler
=
peffect
->
handler
->
overlay_target
;
peffect
->
last_handler
=
peffect
->
handler
->
overlay_target
;
peffect
->
last_handler
=
peffect
->
handler
->
overlay_target
;
}
}
// 设置连锁属性
clit
.
chain_count
=
(
uint8_t
)
core
.
current_chain
.
size
()
+
1
;
clit
.
chain_count
=
(
uint8_t
)
core
.
current_chain
.
size
()
+
1
;
clit
.
target_cards
=
0
;
clit
.
target_cards
=
0
;
clit
.
target_player
=
PLAYER_NONE
;
clit
.
target_player
=
PLAYER_NONE
;
...
@@ -4102,18 +4147,28 @@ int32_t field::add_chain(uint16_t step) {
...
@@ -4102,18 +4147,28 @@ int32_t field::add_chain(uint16_t step) {
clit
.
disable_reason
=
0
;
clit
.
disable_reason
=
0
;
clit
.
disable_player
=
PLAYER_NONE
;
clit
.
disable_player
=
PLAYER_NONE
;
clit
.
replace_op
=
0
;
clit
.
replace_op
=
0
;
// 如果从手牌发动,设置相应标志
if
(
phandler
->
current
.
location
==
LOCATION_HAND
)
if
(
phandler
->
current
.
location
==
LOCATION_HAND
)
clit
.
flag
|=
CHAIN_HAND_EFFECT
;
clit
.
flag
|=
CHAIN_HAND_EFFECT
;
// 将连锁添加到当前连锁列表
core
.
current_chain
.
push_back
(
clit
);
core
.
current_chain
.
push_back
(
clit
);
core
.
is_target_ready
=
false
;
core
.
is_target_ready
=
false
;
// 检查连锁计数
check_chain_counter
(
peffect
,
clit
.
triggering_player
,
clit
.
chain_count
);
check_chain_counter
(
peffect
,
clit
.
triggering_player
,
clit
.
chain_count
);
// triggered events which are not caused by event create relation with the handler
if
(
!
peffect
->
is_flag
(
EFFECT_FLAG_FIELD_ONLY
)
// 为非事件诱发的效果创建关系
if
(
!
peffect
->
is_flag
(
EFFECT_FLAG_FIELD_ONLY
)
&&
(
!
(
peffect
->
type
&
(
EFFECT_TYPE_TRIGGER_F
|
EFFECT_TYPE_TRIGGER_O
))
||
peffect
->
get_code_type
()
==
CODE_PHASE
))
{
&&
(
!
(
peffect
->
type
&
(
EFFECT_TYPE_TRIGGER_F
|
EFFECT_TYPE_TRIGGER_O
))
||
peffect
->
get_code_type
()
==
CODE_PHASE
))
{
phandler
->
create_relation
(
clit
);
phandler
->
create_relation
(
clit
);
}
}
// 设置效果拥有者
peffect
->
effect_owner
=
clit
.
triggering_player
;
peffect
->
effect_owner
=
clit
.
triggering_player
;
// DISABLE_CHAIN should be check before cost
// 检查禁用效果
effect
*
deffect
;
effect
*
deffect
;
if
(
!
peffect
->
is_flag
(
EFFECT_FLAG_FIELD_ONLY
)
&&
phandler
->
is_has_relation
(
clit
)
&&
(
deffect
=
phandler
->
is_affected_by_effect
(
EFFECT_DISABLE_EFFECT
)))
{
if
(
!
peffect
->
is_flag
(
EFFECT_FLAG_FIELD_ONLY
)
&&
phandler
->
is_has_relation
(
clit
)
&&
(
deffect
=
phandler
->
is_affected_by_effect
(
EFFECT_DISABLE_EFFECT
)))
{
effect
*
negeff
=
pduel
->
new_effect
();
effect
*
negeff
=
pduel
->
new_effect
();
...
@@ -4124,32 +4179,42 @@ int32_t field::add_chain(uint16_t step) {
...
@@ -4124,32 +4179,42 @@ int32_t field::add_chain(uint16_t step) {
negeff
->
reset_flag
=
RESET_CHAIN
|
RESET_EVENT
|
deffect
->
get_value
();
negeff
->
reset_flag
=
RESET_CHAIN
|
RESET_EVENT
|
deffect
->
get_value
();
phandler
->
add_effect
(
negeff
);
phandler
->
add_effect
(
negeff
);
}
}
// 从新连锁列表中移除已处理的连锁
core
.
new_chains
.
pop_front
();
core
.
new_chains
.
pop_front
();
return
FALSE
;
return
FALSE
;
}
}
case
2
:
{
case
2
:
{
// 获取当前连锁
auto
&
clit
=
core
.
current_chain
.
back
();
auto
&
clit
=
core
.
current_chain
.
back
();
int32_t
playerid
=
clit
.
triggering_player
;
int32_t
playerid
=
clit
.
triggering_player
;
effect
*
peffect
=
clit
.
triggering_effect
;
effect
*
peffect
=
clit
.
triggering_effect
;
// 检查是否存在CEFFECT(手牌或场地区域设置效果)
if
(
get_cteffect
(
peffect
,
playerid
,
TRUE
))
{
if
(
get_cteffect
(
peffect
,
playerid
,
TRUE
))
{
// 检查是否在伤害步骤且效果不允许在伤害步骤使用
const
bool
damage_step
=
infos
.
phase
==
PHASE_DAMAGE
&&
!
peffect
->
is_flag
(
EFFECT_FLAG_DAMAGE_STEP
);
const
bool
damage_step
=
infos
.
phase
==
PHASE_DAMAGE
&&
!
peffect
->
is_flag
(
EFFECT_FLAG_DAMAGE_STEP
);
const
bool
damage_cal
=
infos
.
phase
==
PHASE_DAMAGE_CAL
&&
!
peffect
->
is_flag
(
EFFECT_FLAG_DAMAGE_CAL
);
const
bool
damage_cal
=
infos
.
phase
==
PHASE_DAMAGE_CAL
&&
!
peffect
->
is_flag
(
EFFECT_FLAG_DAMAGE_CAL
);
if
(
damage_step
||
damage_cal
)
{
if
(
damage_step
||
damage_cal
)
{
returns
.
ivalue
[
0
]
=
TRUE
;
returns
.
ivalue
[
0
]
=
TRUE
;
return
FALSE
;
return
FALSE
;
}
}
// 询问玩家是否使用CEFFECT
add_process
(
PROCESSOR_SELECT_EFFECTYN
,
0
,
0
,
(
group
*
)
peffect
->
get_handler
(),
playerid
,
94
);
add_process
(
PROCESSOR_SELECT_EFFECTYN
,
0
,
0
,
(
group
*
)
peffect
->
get_handler
(),
playerid
,
94
);
}
else
}
else
returns
.
ivalue
[
0
]
=
FALSE
;
returns
.
ivalue
[
0
]
=
FALSE
;
return
FALSE
;
return
FALSE
;
}
}
case
3
:
{
case
3
:
{
// 如果玩家选择不使用CEFFECT
if
(
!
returns
.
ivalue
[
0
])
{
if
(
!
returns
.
ivalue
[
0
])
{
core
.
select_chains
.
clear
();
core
.
select_chains
.
clear
();
core
.
select_options
.
clear
();
core
.
select_options
.
clear
();
core
.
units
.
begin
()
->
step
=
4
;
core
.
units
.
begin
()
->
step
=
4
;
return
FALSE
;
return
FALSE
;
}
}
// 如果有多个CEFFECT选项,让玩家选择
if
(
core
.
select_chains
.
size
()
>
1
)
{
if
(
core
.
select_chains
.
size
()
>
1
)
{
auto
&
clit
=
core
.
current_chain
.
back
();
auto
&
clit
=
core
.
current_chain
.
back
();
add_process
(
PROCESSOR_SELECT_OPTION
,
0
,
0
,
0
,
clit
.
triggering_player
,
0
);
add_process
(
PROCESSOR_SELECT_OPTION
,
0
,
0
,
0
,
clit
.
triggering_player
,
0
);
...
@@ -4158,25 +4223,37 @@ int32_t field::add_chain(uint16_t step) {
...
@@ -4158,25 +4223,37 @@ int32_t field::add_chain(uint16_t step) {
return
FALSE
;
return
FALSE
;
}
}
case
4
:
{
case
4
:
{
// 处理CEFFECT选择结果
auto
&
clit
=
core
.
current_chain
.
back
();
auto
&
clit
=
core
.
current_chain
.
back
();
chain
&
ch
=
core
.
select_chains
[
returns
.
ivalue
[
0
]];
chain
&
ch
=
core
.
select_chains
[
returns
.
ivalue
[
0
]];
int32_t
playerid
=
clit
.
triggering_player
;
int32_t
playerid
=
clit
.
triggering_player
;
effect
*
peffect
=
ch
.
triggering_effect
;
effect
*
peffect
=
ch
.
triggering_effect
;
card
*
phandler
=
peffect
->
get_handler
();
card
*
phandler
=
peffect
->
get_handler
();
// 发送选择提示消息
pduel
->
write_buffer8
(
MSG_HINT
);
pduel
->
write_buffer8
(
MSG_HINT
);
pduel
->
write_buffer8
(
HINT_OPSELECTED
);
pduel
->
write_buffer8
(
HINT_OPSELECTED
);
pduel
->
write_buffer8
(
playerid
);
pduel
->
write_buffer8
(
playerid
);
pduel
->
write_buffer32
(
core
.
select_options
.
size
()
>
1
?
core
.
select_options
[
returns
.
ivalue
[
0
]]
:
65
);
pduel
->
write_buffer32
(
core
.
select_options
.
size
()
>
1
?
core
.
select_options
[
returns
.
ivalue
[
0
]]
:
65
);
// 更新连锁效果和事件
clit
.
triggering_effect
=
peffect
;
clit
.
triggering_effect
=
peffect
;
clit
.
evt
=
ch
.
evt
;
clit
.
evt
=
ch
.
evt
;
phandler
->
create_relation
(
clit
);
phandler
->
create_relation
(
clit
);
peffect
->
set_active_type
();
peffect
->
dec_count
(
playerid
);
peffect
->
dec_count
(
playerid
);
// 如果不是卡的发动类型效果,添加发动标志
if
(
!
(
peffect
->
type
&
EFFECT_TYPE_ACTIVATE
))
{
if
(
!
(
peffect
->
type
&
EFFECT_TYPE_ACTIVATE
))
{
peffect
->
type
|=
EFFECT_TYPE_ACTIVATE
;
peffect
->
type
|=
EFFECT_TYPE_ACTIVATE
;
clit
.
flag
|=
CHAIN_ACTIVATING
;
clit
.
flag
|=
CHAIN_ACTIVATING
;
}
}
// 清理选择项
core
.
select_chains
.
clear
();
core
.
select_chains
.
clear
();
core
.
select_options
.
clear
();
core
.
select_options
.
clear
();
// 添加客户端提示效果
effect
*
deffect
=
pduel
->
new_effect
();
effect
*
deffect
=
pduel
->
new_effect
();
deffect
->
owner
=
phandler
;
deffect
->
owner
=
phandler
;
deffect
->
code
=
0
;
deffect
->
code
=
0
;
...
@@ -4188,16 +4265,19 @@ int32_t field::add_chain(uint16_t step) {
...
@@ -4188,16 +4265,19 @@ int32_t field::add_chain(uint16_t step) {
return
FALSE
;
return
FALSE
;
}
}
case
5
:
{
case
5
:
{
// 处理必需的手牌或场地设置效果
auto
&
clit
=
core
.
current_chain
.
back
();
auto
&
clit
=
core
.
current_chain
.
back
();
if
(
!
clit
.
required_handorset_effects
.
size
())
{
if
(
!
clit
.
required_handorset_effects
.
size
())
{
core
.
units
.
begin
()
->
step
=
6
;
core
.
units
.
begin
()
->
step
=
6
;
return
FALSE
;
return
FALSE
;
}
}
// 如果只有一个必需效果,直接使用
if
(
clit
.
required_handorset_effects
.
size
()
==
1
)
{
if
(
clit
.
required_handorset_effects
.
size
()
==
1
)
{
returns
.
ivalue
[
0
]
=
0
;
returns
.
ivalue
[
0
]
=
0
;
return
FALSE
;
return
FALSE
;
}
else
{
}
else
{
//
check if there's only one type of ceffects
//
检查是否所有效果都是同一种类型
auto
peffect
=
clit
.
triggering_effect
;
auto
peffect
=
clit
.
triggering_effect
;
auto
playerid
=
clit
.
triggering_player
;
auto
playerid
=
clit
.
triggering_player
;
int32_t
ceffect_unique_id
=
0
;
int32_t
ceffect_unique_id
=
0
;
...
@@ -4214,11 +4294,13 @@ int32_t field::add_chain(uint16_t step) {
...
@@ -4214,11 +4294,13 @@ int32_t field::add_chain(uint16_t step) {
}
}
}
}
if
(
ceffect_unique_id
)
{
if
(
ceffect_unique_id
)
{
//
all ceffects are the same type, so skip asking
//
所有效果相同,无需选择
returns
.
ivalue
[
0
]
=
0
;
returns
.
ivalue
[
0
]
=
0
;
return
FALSE
;
return
FALSE
;
}
}
}
}
// 让玩家选择必需效果
core
.
select_options
.
clear
();
core
.
select_options
.
clear
();
for
(
effect_set
::
size_type
i
=
0
;
i
<
clit
.
required_handorset_effects
.
size
();
++
i
)
{
for
(
effect_set
::
size_type
i
=
0
;
i
<
clit
.
required_handorset_effects
.
size
();
++
i
)
{
core
.
select_options
.
push_back
(
clit
.
required_handorset_effects
[
i
]
->
description
);
core
.
select_options
.
push_back
(
clit
.
required_handorset_effects
[
i
]
->
description
);
...
@@ -4227,15 +4309,20 @@ int32_t field::add_chain(uint16_t step) {
...
@@ -4227,15 +4309,20 @@ int32_t field::add_chain(uint16_t step) {
return
FALSE
;
return
FALSE
;
}
}
case
6
:
{
case
6
:
{
// 执行选择的必需效果
auto
&
clit
=
core
.
current_chain
.
back
();
auto
&
clit
=
core
.
current_chain
.
back
();
auto
ceffect
=
clit
.
required_handorset_effects
[
returns
.
ivalue
[
0
]];
auto
ceffect
=
clit
.
required_handorset_effects
[
returns
.
ivalue
[
0
]];
ceffect
->
dec_count
(
clit
.
triggering_player
);
ceffect
->
dec_count
(
clit
.
triggering_player
);
// 发送选择提示
if
(
ceffect
->
description
)
{
if
(
ceffect
->
description
)
{
pduel
->
write_buffer8
(
MSG_HINT
);
pduel
->
write_buffer8
(
MSG_HINT
);
pduel
->
write_buffer8
(
HINT_OPSELECTED
);
pduel
->
write_buffer8
(
HINT_OPSELECTED
);
pduel
->
write_buffer8
(
clit
.
triggering_player
);
pduel
->
write_buffer8
(
clit
.
triggering_player
);
pduel
->
write_buffer32
(
ceffect
->
description
);
pduel
->
write_buffer32
(
ceffect
->
description
);
}
}
// 执行支付cost步骤
if
(
ceffect
->
cost
)
{
if
(
ceffect
->
cost
)
{
pduel
->
lua
->
add_param
(
clit
.
triggering_effect
,
PARAM_TYPE_EFFECT
);
pduel
->
lua
->
add_param
(
clit
.
triggering_effect
,
PARAM_TYPE_EFFECT
);
core
.
sub_solving_event
.
push_back
(
clit
.
evt
);
core
.
sub_solving_event
.
push_back
(
clit
.
evt
);
...
@@ -4244,6 +4331,7 @@ int32_t field::add_chain(uint16_t step) {
...
@@ -4244,6 +4331,7 @@ int32_t field::add_chain(uint16_t step) {
return
FALSE
;
return
FALSE
;
}
}
case
7
:
{
case
7
:
{
// 支付主要效果的cost
auto
&
clit
=
core
.
current_chain
.
back
();
auto
&
clit
=
core
.
current_chain
.
back
();
effect
*
peffect
=
clit
.
triggering_effect
;
effect
*
peffect
=
clit
.
triggering_effect
;
peffect
->
cost_checked
=
TRUE
;
peffect
->
cost_checked
=
TRUE
;
...
@@ -4254,6 +4342,7 @@ int32_t field::add_chain(uint16_t step) {
...
@@ -4254,6 +4342,7 @@ int32_t field::add_chain(uint16_t step) {
return
FALSE
;
return
FALSE
;
}
}
case
8
:
{
case
8
:
{
// 执行选择主要效果的发动对象
auto
&
clit
=
core
.
current_chain
.
back
();
auto
&
clit
=
core
.
current_chain
.
back
();
effect
*
peffect
=
clit
.
triggering_effect
;
effect
*
peffect
=
clit
.
triggering_effect
;
if
(
peffect
->
target
)
{
if
(
peffect
->
target
)
{
...
@@ -4263,12 +4352,15 @@ int32_t field::add_chain(uint16_t step) {
...
@@ -4263,12 +4352,15 @@ int32_t field::add_chain(uint16_t step) {
return
FALSE
;
return
FALSE
;
}
}
case
9
:
{
case
9
:
{
// 连锁添加完成后的处理
break_effect
();
break_effect
();
core
.
is_target_ready
=
true
;
core
.
is_target_ready
=
true
;
auto
&
clit
=
core
.
current_chain
.
back
();
auto
&
clit
=
core
.
current_chain
.
back
();
effect
*
peffect
=
clit
.
triggering_effect
;
effect
*
peffect
=
clit
.
triggering_effect
;
peffect
->
cost_checked
=
FALSE
;
peffect
->
cost_checked
=
FALSE
;
card
*
phandler
=
peffect
->
get_handler
();
card
*
phandler
=
peffect
->
get_handler
();
// 处理作为对象的卡片成为目标事件
if
(
clit
.
target_cards
&&
clit
.
target_cards
->
container
.
size
())
{
if
(
clit
.
target_cards
&&
clit
.
target_cards
->
container
.
size
())
{
if
(
peffect
->
is_flag
(
EFFECT_FLAG_CARD_TARGET
))
{
if
(
peffect
->
is_flag
(
EFFECT_FLAG_CARD_TARGET
))
{
for
(
auto
&
pcard
:
clit
.
target_cards
->
container
)
for
(
auto
&
pcard
:
clit
.
target_cards
->
container
)
...
@@ -4278,29 +4370,42 @@ int32_t field::add_chain(uint16_t step) {
...
@@ -4278,29 +4370,42 @@ int32_t field::add_chain(uint16_t step) {
raise_event
(
clit
.
target_cards
->
container
,
EVENT_BECOME_TARGET
,
peffect
,
0
,
clit
.
triggering_player
,
clit
.
triggering_player
,
clit
.
chain_count
);
raise_event
(
clit
.
target_cards
->
container
,
EVENT_BECOME_TARGET
,
peffect
,
0
,
clit
.
triggering_player
,
clit
.
triggering_player
,
clit
.
chain_count
);
}
}
}
}
// 处理发动的卡片的离场确认
if
(
peffect
->
type
&
EFFECT_TYPE_ACTIVATE
)
{
if
(
peffect
->
type
&
EFFECT_TYPE_ACTIVATE
)
{
core
.
leave_confirmed
.
insert
(
phandler
);
core
.
leave_confirmed
.
insert
(
phandler
);
if
(
!
(
phandler
->
data
.
type
&
(
TYPE_CONTINUOUS
|
TYPE_FIELD
|
TYPE_EQUIP
|
TYPE_PENDULUM
))
if
(
!
(
phandler
->
data
.
type
&
(
TYPE_CONTINUOUS
|
TYPE_FIELD
|
TYPE_EQUIP
|
TYPE_PENDULUM
))
&&
!
phandler
->
is_affected_by_effect
(
EFFECT_REMAIN_FIELD
))
&&
!
phandler
->
is_affected_by_effect
(
EFFECT_REMAIN_FIELD
))
phandler
->
set_status
(
STATUS_LEAVE_CONFIRMED
,
TRUE
);
phandler
->
set_status
(
STATUS_LEAVE_CONFIRMED
,
TRUE
);
}
}
// 设置连续卡片标志
if
((
phandler
->
get_type
()
&
(
TYPE_SPELL
|
TYPE_TRAP
))
if
((
phandler
->
get_type
()
&
(
TYPE_SPELL
|
TYPE_TRAP
))
&&
(
phandler
->
get_type
()
&
(
TYPE_CONTINUOUS
|
TYPE_FIELD
|
TYPE_EQUIP
|
TYPE_PENDULUM
))
&&
(
phandler
->
get_type
()
&
(
TYPE_CONTINUOUS
|
TYPE_FIELD
|
TYPE_EQUIP
|
TYPE_PENDULUM
))
&&
phandler
->
is_has_relation
(
clit
)
&&
phandler
->
current
.
location
==
LOCATION_SZONE
&&
phandler
->
is_has_relation
(
clit
)
&&
phandler
->
current
.
location
==
LOCATION_SZONE
&&
!
peffect
->
is_flag
(
EFFECT_FLAG_FIELD_ONLY
))
&&
!
peffect
->
is_flag
(
EFFECT_FLAG_FIELD_ONLY
))
clit
.
flag
|=
CHAIN_CONTINUOUS_CARD
;
clit
.
flag
|=
CHAIN_CONTINUOUS_CARD
;
// 发送连锁完成消息
pduel
->
write_buffer8
(
MSG_CHAINED
);
pduel
->
write_buffer8
(
MSG_CHAINED
);
pduel
->
write_buffer8
(
clit
.
chain_count
);
pduel
->
write_buffer8
(
clit
.
chain_count
);
// 诱发连锁事件
raise_event
(
phandler
,
EVENT_CHAINING
,
peffect
,
0
,
clit
.
triggering_player
,
clit
.
triggering_player
,
clit
.
chain_count
);
raise_event
(
phandler
,
EVENT_CHAINING
,
peffect
,
0
,
clit
.
triggering_player
,
clit
.
triggering_player
,
clit
.
chain_count
);
process_instant_event
();
process_instant_event
();
// 如果还有新的连锁需要处理,继续添加
if
(
core
.
new_chains
.
size
())
if
(
core
.
new_chains
.
size
())
add_process
(
PROCESSOR_ADD_CHAIN
,
0
,
0
,
0
,
0
,
0
);
add_process
(
PROCESSOR_ADD_CHAIN
,
0
,
0
,
0
,
0
,
0
);
// 调整所有状态
adjust_all
();
adjust_all
();
return
TRUE
;
return
TRUE
;
}
}
}
}
return
TRUE
;
return
TRUE
;
}
}
void
field
::
solve_continuous
(
uint8_t
playerid
,
effect
*
peffect
,
const
tevent
&
e
)
{
void
field
::
solve_continuous
(
uint8_t
playerid
,
effect
*
peffect
,
const
tevent
&
e
)
{
chain
newchain
;
chain
newchain
;
newchain
.
chain_id
=
0
;
newchain
.
chain_id
=
0
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment