Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Y
ygopro
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
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
MyCard
ygopro
Commits
f23cbe45
Commit
f23cbe45
authored
May 09, 2012
by
argon.sun
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of github.com:Fluorohydride/ygopro
parents
6f9ffc19
2b1b5e62
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
266 additions
and
78 deletions
+266
-78
gframe/drawing.cpp
gframe/drawing.cpp
+11
-4
gframe/duelclient.cpp
gframe/duelclient.cpp
+108
-1
gframe/game.cpp
gframe/game.cpp
+1
-0
gframe/netserver.cpp
gframe/netserver.cpp
+5
-1
gframe/network.h
gframe/network.h
+4
-4
gframe/replay_mode.cpp
gframe/replay_mode.cpp
+50
-15
gframe/single_duel.cpp
gframe/single_duel.cpp
+7
-3
gframe/tag_duel.cpp
gframe/tag_duel.cpp
+32
-5
gframe/tag_duel.h
gframe/tag_duel.h
+1
-1
ocgcore/field.cpp
ocgcore/field.cpp
+9
-0
ocgcore/operations.cpp
ocgcore/operations.cpp
+1
-1
script/c25123082.lua
script/c25123082.lua
+3
-3
script/c25924653.lua
script/c25924653.lua
+2
-2
script/c27068117.lua
script/c27068117.lua
+2
-1
script/c33302407.lua
script/c33302407.lua
+2
-2
script/c33900648.lua
script/c33900648.lua
+8
-8
script/c51589188.lua
script/c51589188.lua
+1
-1
script/c51790181.lua
script/c51790181.lua
+0
-8
script/c52628687.lua
script/c52628687.lua
+14
-13
script/c63676256.lua
script/c63676256.lua
+4
-4
script/c99004752.lua
script/c99004752.lua
+1
-1
No files found.
gframe/drawing.cpp
View file @
f23cbe45
...
...
@@ -326,10 +326,17 @@ void Game::DrawMisc() {
numFont
->
draw
(
dInfo
.
strLP
[
1
],
recti
(
691
,
11
,
990
,
30
),
0xff000000
,
true
,
false
,
0
);
numFont
->
draw
(
dInfo
.
strLP
[
1
],
recti
(
691
,
12
,
992
,
30
),
0xffffff00
,
true
,
false
,
0
);
textFont
->
draw
(
dInfo
.
hostname
,
recti
(
335
,
31
,
629
,
50
),
0xffffffff
,
false
,
false
,
0
);
auto
cld
=
textFont
->
getDimension
(
dInfo
.
clientname
);
textFont
->
draw
(
dInfo
.
clientname
,
recti
(
986
-
cld
.
Width
,
31
,
986
,
50
),
0xffffffff
,
false
,
false
,
0
);
if
(
!
dInfo
.
is_tag
||
!
dInfo
.
tag_player
[
0
])
textFont
->
draw
(
dInfo
.
hostname
,
recti
(
335
,
31
,
629
,
50
),
0xffffffff
,
false
,
false
,
0
);
else
textFont
->
draw
(
dInfo
.
hostname_tag
,
recti
(
335
,
31
,
629
,
50
),
0xffffffff
,
false
,
false
,
0
);
if
(
!
dInfo
.
is_tag
||
!
dInfo
.
tag_player
[
1
])
{
auto
cld
=
textFont
->
getDimension
(
dInfo
.
clientname
);
textFont
->
draw
(
dInfo
.
clientname
,
recti
(
986
-
cld
.
Width
,
31
,
986
,
50
),
0xffffffff
,
false
,
false
,
0
);
}
else
{
auto
cld
=
textFont
->
getDimension
(
dInfo
.
clientname_tag
);
textFont
->
draw
(
dInfo
.
clientname_tag
,
recti
(
986
-
cld
.
Width
,
31
,
986
,
50
),
0xffffffff
,
false
,
false
,
0
);
}
driver
->
draw2DRectangle
(
recti
(
632
,
10
,
688
,
30
),
0x00000000
,
0x00000000
,
0xffffffff
,
0xffffffff
);
driver
->
draw2DRectangle
(
recti
(
632
,
30
,
688
,
50
),
0xffffffff
,
0xffffffff
,
0x00000000
,
0x00000000
);
lpcFont
->
draw
(
dataManager
.
GetNumString
(
dInfo
.
turn
),
recti
(
635
,
5
,
685
,
40
),
0x80000000
,
true
,
false
,
0
);
...
...
gframe/duelclient.cpp
View file @
f23cbe45
...
...
@@ -600,7 +600,11 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
if
(
pos
>
3
)
break
;
mainGame
->
gMutex
.
Lock
();
if
(
state
==
PLAYERCHANGE_READY
)
{
if
(
state
<
8
)
{
mainGame
->
stHostPrepDuelist
[
state
]
->
setText
(
mainGame
->
stHostPrepDuelist
[
pos
]
->
getText
());
mainGame
->
stHostPrepDuelist
[
pos
]
->
setText
(
L""
);
mainGame
->
chkHostPrepReady
[
pos
]
->
setChecked
(
false
);
}
else
if
(
state
==
PLAYERCHANGE_READY
)
{
mainGame
->
chkHostPrepReady
[
pos
]
->
setChecked
(
true
);
}
else
if
(
state
==
PLAYERCHANGE_NOTREADY
)
{
mainGame
->
chkHostPrepReady
[
pos
]
->
setChecked
(
false
);
...
...
@@ -2566,6 +2570,109 @@ int DuelClient::ClientAnalyze(char* msg, unsigned int len) {
}
return
true
;
}
case
MSG_TAG_SWAP
:
{
int
player
=
mainGame
->
LocalPlayer
(
BufferIO
::
ReadInt8
(
pbuf
));
int
mcount
=
BufferIO
::
ReadInt8
(
pbuf
);
int
ecount
=
BufferIO
::
ReadInt8
(
pbuf
);
int
hcount
=
BufferIO
::
ReadInt8
(
pbuf
);
int
topcode
=
BufferIO
::
ReadInt32
(
pbuf
);
for
(
int
i
=
0
;
i
<
mainGame
->
dField
.
deck
[
player
].
size
();
++
i
)
mainGame
->
dField
.
deck
[
player
][
i
]
->
code
=
0
;
for
(
auto
cit
=
mainGame
->
dField
.
deck
[
player
].
begin
();
cit
!=
mainGame
->
dField
.
deck
[
player
].
end
();
++
cit
)
{
if
(
player
==
0
)
(
*
cit
)
->
dPos
.
Y
=
1.0
f
;
else
(
*
cit
)
->
dPos
.
Y
=
-
1.0
f
;
(
*
cit
)
->
dRot
=
irr
::
core
::
vector3df
(
0
,
0
,
0
);
(
*
cit
)
->
is_moving
=
true
;
(
*
cit
)
->
aniFrame
=
5
;
}
for
(
auto
cit
=
mainGame
->
dField
.
hand
[
player
].
begin
();
cit
!=
mainGame
->
dField
.
hand
[
player
].
end
();
++
cit
)
{
if
(
player
==
0
)
(
*
cit
)
->
dPos
.
Y
=
1.0
f
;
else
(
*
cit
)
->
dPos
.
Y
=
-
1.0
f
;
(
*
cit
)
->
dRot
=
irr
::
core
::
vector3df
(
0
,
0
,
0
);
(
*
cit
)
->
is_moving
=
true
;
(
*
cit
)
->
aniFrame
=
5
;
}
for
(
auto
cit
=
mainGame
->
dField
.
extra
[
player
].
begin
();
cit
!=
mainGame
->
dField
.
extra
[
player
].
end
();
++
cit
)
{
if
(
player
==
0
)
(
*
cit
)
->
dPos
.
Y
=
1.0
f
;
else
(
*
cit
)
->
dPos
.
Y
=
-
1.0
f
;
(
*
cit
)
->
dRot
=
irr
::
core
::
vector3df
(
0
,
0
,
0
);
(
*
cit
)
->
is_moving
=
true
;
(
*
cit
)
->
aniFrame
=
5
;
}
mainGame
->
WaitFrameSignal
(
5
);
//
mainGame
->
gMutex
.
Lock
();
if
(
mainGame
->
dField
.
deck
[
player
].
size
()
>
mcount
)
{
for
(
int
i
=
0
;
i
<
mainGame
->
dField
.
deck
[
player
].
size
()
-
mcount
;
++
i
)
{
ClientCard
*
ccard
=
*
mainGame
->
dField
.
deck
[
player
].
rbegin
();
mainGame
->
dField
.
deck
[
player
].
pop_back
();
delete
ccard
;
}
}
else
{
for
(
int
i
=
0
;
i
<
mcount
-
mainGame
->
dField
.
deck
[
player
].
size
();
++
i
)
{
ClientCard
*
ccard
=
new
ClientCard
();
ccard
->
controler
=
player
;
ccard
->
location
=
LOCATION_DECK
;
ccard
->
sequence
=
mainGame
->
dField
.
deck
[
player
].
size
()
-
1
;
mainGame
->
dField
.
deck
[
player
].
push_back
(
ccard
);
}
}
if
(
mainGame
->
dField
.
hand
[
player
].
size
()
>
mcount
)
{
for
(
int
i
=
0
;
i
<
mainGame
->
dField
.
hand
[
player
].
size
()
-
mcount
;
++
i
)
{
ClientCard
*
ccard
=
*
mainGame
->
dField
.
hand
[
player
].
rbegin
();
mainGame
->
dField
.
hand
[
player
].
pop_back
();
delete
ccard
;
}
}
else
{
for
(
int
i
=
0
;
i
<
mcount
-
mainGame
->
dField
.
hand
[
player
].
size
();
++
i
)
{
ClientCard
*
ccard
=
new
ClientCard
();
ccard
->
controler
=
player
;
ccard
->
location
=
LOCATION_HAND
;
ccard
->
sequence
=
mainGame
->
dField
.
hand
[
player
].
size
()
-
1
;
mainGame
->
dField
.
hand
[
player
].
push_back
(
ccard
);
}
}
if
(
mainGame
->
dField
.
extra
[
player
].
size
()
>
mcount
)
{
for
(
int
i
=
0
;
i
<
mainGame
->
dField
.
extra
[
player
].
size
()
-
mcount
;
++
i
)
{
ClientCard
*
ccard
=
*
mainGame
->
dField
.
extra
[
player
].
rbegin
();
mainGame
->
dField
.
extra
[
player
].
pop_back
();
delete
ccard
;
}
}
else
{
for
(
int
i
=
0
;
i
<
mcount
-
mainGame
->
dField
.
extra
[
player
].
size
();
++
i
)
{
ClientCard
*
ccard
=
new
ClientCard
();
ccard
->
controler
=
player
;
ccard
->
location
=
LOCATION_EXTRA
;
ccard
->
sequence
=
mainGame
->
dField
.
extra
[
player
].
size
()
-
1
;
mainGame
->
dField
.
extra
[
player
].
push_back
(
ccard
);
}
}
mainGame
->
gMutex
.
Unlock
();
//
for
(
auto
cit
=
mainGame
->
dField
.
deck
[
player
].
begin
();
cit
!=
mainGame
->
dField
.
deck
[
player
].
end
();
++
cit
)
{
ClientCard
*
pcard
=
*
cit
;
mainGame
->
dField
.
GetCardLocation
(
pcard
,
&
pcard
->
curPos
,
&
pcard
->
curRot
);
if
(
player
==
0
)
pcard
->
curPos
.
Y
+=
5.0
f
;
else
pcard
->
curPos
.
Y
-=
5.0
f
;
mainGame
->
dField
.
MoveCard
(
*
cit
,
5
);
}
for
(
auto
cit
=
mainGame
->
dField
.
hand
[
player
].
begin
();
cit
!=
mainGame
->
dField
.
hand
[
player
].
end
();
++
cit
)
{
ClientCard
*
pcard
=
*
cit
;
mainGame
->
dField
.
GetCardLocation
(
pcard
,
&
pcard
->
curPos
,
&
pcard
->
curRot
);
if
(
player
==
0
)
pcard
->
curPos
.
Y
+=
5.0
f
;
else
pcard
->
curPos
.
Y
-=
5.0
f
;
mainGame
->
dField
.
MoveCard
(
*
cit
,
5
);
}
for
(
auto
cit
=
mainGame
->
dField
.
extra
[
player
].
begin
();
cit
!=
mainGame
->
dField
.
extra
[
player
].
end
();
++
cit
)
{
ClientCard
*
pcard
=
*
cit
;
mainGame
->
dField
.
GetCardLocation
(
pcard
,
&
pcard
->
curPos
,
&
pcard
->
curRot
);
if
(
player
==
0
)
pcard
->
curPos
.
Y
+=
5.0
f
;
else
pcard
->
curPos
.
Y
-=
5.0
f
;
mainGame
->
dField
.
MoveCard
(
*
cit
,
5
);
}
mainGame
->
WaitFrameSignal
(
5
);
break
;
}
}
return
true
;
}
...
...
gframe/game.cpp
View file @
f23cbe45
...
...
@@ -110,6 +110,7 @@ bool Game::Initialize() {
cbMatchMode
=
env
->
addComboBox
(
rect
<
s32
>
(
140
,
85
,
300
,
110
),
wCreateHost
);
cbMatchMode
->
addItem
(
dataManager
.
GetSysString
(
1244
));
cbMatchMode
->
addItem
(
dataManager
.
GetSysString
(
1245
));
cbMatchMode
->
addItem
(
dataManager
.
GetSysString
(
1246
));
env
->
addStaticText
(
dataManager
.
GetSysString
(
1237
),
rect
<
s32
>
(
20
,
120
,
320
,
140
),
false
,
false
,
wCreateHost
);
myswprintf
(
strbuf
,
L"%d"
,
180
);
ebTimeLimit
=
env
->
addEditBox
(
strbuf
,
rect
<
s32
>
(
140
,
115
,
220
,
140
),
true
,
wCreateHost
);
...
...
gframe/netserver.cpp
View file @
f23cbe45
#include "netserver.h"
#include "single_duel.h"
#include "tag_duel.h"
namespace
ygo
{
std
::
unordered_map
<
bufferevent
*
,
DuelPlayer
>
NetServer
::
users
;
...
...
@@ -228,10 +229,13 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, char* data, unsigned int len) {
}
else
if
(
pkt
->
info
.
mode
==
MODE_MATCH
)
{
duel_mode
=
new
SingleDuel
(
true
);
duel_mode
->
etimer
=
event_new
(
net_evbase
,
0
,
EV_TIMEOUT
|
EV_PERSIST
,
SingleDuel
::
SingleTimer
,
duel_mode
);
}
else
if
(
pkt
->
info
.
mode
==
MODE_TAG
)
{
duel_mode
=
new
TagDuel
();
duel_mode
->
etimer
=
event_new
(
net_evbase
,
0
,
EV_TIMEOUT
|
EV_PERSIST
,
TagDuel
::
TagTimer
,
duel_mode
);
}
if
(
pkt
->
info
.
rule
>
3
)
pkt
->
info
.
rule
=
0
;
if
(
pkt
->
info
.
mode
>
1
)
if
(
pkt
->
info
.
mode
>
2
)
pkt
->
info
.
mode
=
0
;
unsigned
int
hash
=
1
;
for
(
auto
lfit
=
deckManager
.
_lfList
.
begin
();
lfit
!=
deckManager
.
_lfList
.
end
();
++
lfit
)
{
...
...
gframe/network.h
View file @
f23cbe45
...
...
@@ -197,10 +197,10 @@ public:
#define STOC_HS_PLAYER_CHANGE 0x21
#define STOC_HS_WATCH_CHANGE 0x22
#define PLAYERCHANGE_
READY 0x1
#define PLAYERCHANGE_
NOTREADY 0x2
#define PLAYERCHANGE_
LEAVE 0x3
#define PLAYERCHANGE_
OBSERVE 0x4
#define PLAYERCHANGE_
OBSERVE 0x8
#define PLAYERCHANGE_
READY 0x9
#define PLAYERCHANGE_
NOTREADY 0xa
#define PLAYERCHANGE_
LEAVE 0xb
#define ERRMSG_JOINERROR 0x1
#define ERRMSG_DECKERROR 0x2
...
...
gframe/replay_mode.cpp
View file @
f23cbe45
#include "replay_mode.h"
#include "duelclient.h"
#include "game.h"
#include "../ocgcore/duel.h"
#include "../ocgcore/field.h"
#include "../ocgcore/mtrandom.h"
...
...
@@ -72,20 +73,49 @@ int ReplayMode::ReplayThread(void* param) {
myswprintf
(
mainGame
->
dInfo
.
strLP
[
1
],
L"%d"
,
mainGame
->
dInfo
.
lp
[
1
]);
mainGame
->
dInfo
.
turn
=
0
;
mainGame
->
dInfo
.
strTurn
[
0
]
=
0
;
int
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
0
,
LOCATION_DECK
,
0
,
0
);
int
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
0
,
LOCATION_EXTRA
,
0
,
0
);
mainGame
->
dField
.
Initial
(
0
,
main
,
extra
);
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
1
,
LOCATION_DECK
,
0
,
0
);
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
1
,
LOCATION_EXTRA
,
0
,
0
);
mainGame
->
dField
.
Initial
(
1
,
main
,
extra
);
if
(
!
(
opt
&
DUEL_TAG_MODE
))
{
int
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
0
,
LOCATION_DECK
,
0
,
0
);
int
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
0
,
LOCATION_EXTRA
,
0
,
0
);
mainGame
->
dField
.
Initial
(
0
,
main
,
extra
);
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
1
,
LOCATION_DECK
,
0
,
0
);
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
1
,
LOCATION_EXTRA
,
0
,
0
);
mainGame
->
dField
.
Initial
(
1
,
main
,
extra
);
}
else
{
int
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
0
,
LOCATION_DECK
,
0
,
0
);
int
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
0
,
LOCATION_EXTRA
,
0
,
0
);
mainGame
->
dField
.
Initial
(
0
,
main
,
extra
);
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_tag_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
LOCATION_DECK
);
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_tag_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
LOCATION_EXTRA
);
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
1
,
LOCATION_DECK
,
0
,
0
);
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
1
,
LOCATION_EXTRA
,
0
,
0
);
mainGame
->
dField
.
Initial
(
1
,
main
,
extra
);
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_tag_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
LOCATION_DECK
);
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_tag_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
LOCATION_EXTRA
);
}
start_duel
(
pduel
,
opt
);
mainGame
->
dInfo
.
isStarted
=
true
;
mainGame
->
dInfo
.
isReplay
=
true
;
...
...
@@ -565,6 +595,11 @@ bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_TAG_SWAP
:
{
pbuf
+=
pbuf
[
4
]
*
4
+
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
}
if
(
pauseable
&&
is_pausing
)
{
is_paused
=
true
;
...
...
@@ -614,7 +649,7 @@ int ReplayMode::MessageHandler(long fduel, int type) {
wchar_t
wbuf
[
1024
];
BufferIO
::
DecodeUTF8
(
msgbuf
,
wbuf
);
mainGame
->
AddChatMsg
(
wbuf
,
9
);
}
else
if
(
enable_log
==
2
){
}
else
if
(
enable_log
==
2
)
{
FILE
*
fp
=
fopen
(
"error.log"
,
"at"
);
if
(
!
fp
)
return
0
;
...
...
gframe/single_duel.cpp
View file @
f23cbe45
...
...
@@ -1081,8 +1081,12 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
pbufw
=
pbuf
;
pbuf
+=
count
*
4
;
NetServer
::
SendBufferToPlayer
(
players
[
player
],
STOC_GAME_MSG
,
offset
,
pbuf
-
offset
);
for
(
int
i
=
0
;
i
<
count
;
++
i
)
BufferIO
::
WriteInt32
(
pbufw
,
0
);
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
if
(
!
(
pbufw
[
i
]
&
0x80000000
))
BufferIO
::
WriteInt32
(
pbufw
,
0
);
else
pbufw
+=
4
;
}
NetServer
::
SendBufferToPlayer
(
players
[
1
-
player
],
STOC_GAME_MSG
,
offset
,
pbuf
-
offset
);
for
(
auto
oit
=
observers
.
begin
();
oit
!=
observers
.
end
();
++
oit
)
NetServer
::
ReSendToPlayer
(
*
oit
);
...
...
@@ -1437,7 +1441,7 @@ int SingleDuel::MessageHandler(long fduel, int type) {
wchar_t
wbuf
[
1024
];
BufferIO
::
DecodeUTF8
(
msgbuf
,
wbuf
);
mainGame
->
AddChatMsg
(
wbuf
,
9
);
}
else
if
(
enable_log
==
2
){
}
else
if
(
enable_log
==
2
)
{
FILE
*
fp
=
fopen
(
"error.log"
,
"at"
);
if
(
!
fp
)
return
0
;
...
...
gframe/tag_duel.cpp
View file @
f23cbe45
...
...
@@ -191,13 +191,12 @@ void TagDuel::ToDuelist(DuelPlayer* dp) {
for
(
auto
pit
=
observers
.
begin
();
pit
!=
observers
.
end
();
++
pit
)
NetServer
::
SendPacketToPlayer
(
*
pit
,
STOC_HS_PLAYER_CHANGE
,
scpc
);
STOC_TypeChange
sctc
;
sctc
.
type
=
(
dp
==
host_player
?
0x10
:
0
)
|
dp
->
type
;
sctc
.
type
=
(
dp
==
host_player
?
0x10
:
0
)
|
dptype
;
NetServer
::
SendPacketToPlayer
(
dp
,
STOC_TYPE_CHANGE
,
sctc
);
players
[
dptype
]
=
dp
;
players
[
dp
->
type
]
=
0
;
dp
->
type
=
dptype
;
}
}
void
TagDuel
::
ToObserver
(
DuelPlayer
*
dp
)
{
if
(
dp
->
type
>
3
)
...
...
@@ -448,6 +447,8 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
else
startbuf
[
1
]
=
0x11
;
for
(
auto
oit
=
observers
.
begin
();
oit
!=
observers
.
end
();
++
oit
)
NetServer
::
SendBufferToPlayer
(
*
oit
,
STOC_GAME_MSG
,
startbuf
,
18
);
RefreshExtra
(
0
);
RefreshExtra
(
1
);
start_duel
(
pduel
,
opt
);
Process
();
}
...
...
@@ -1090,8 +1091,12 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
pbufw
=
pbuf
;
pbuf
+=
count
*
4
;
NetServer
::
SendBufferToPlayer
(
cur_player
[
player
],
STOC_GAME_MSG
,
offset
,
pbuf
-
offset
);
for
(
int
i
=
0
;
i
<
count
;
++
i
)
BufferIO
::
WriteInt32
(
pbufw
,
0
);
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
if
(
!
(
pbufw
[
i
]
&
0x80000000
))
BufferIO
::
WriteInt32
(
pbufw
,
0
);
else
pbufw
+=
4
;
}
for
(
int
i
=
0
;
i
<
4
;
++
i
)
if
(
players
[
i
]
!=
cur_player
[
player
])
NetServer
::
SendBufferToPlayer
(
players
[
i
],
STOC_GAME_MSG
,
offset
,
pbuf
-
offset
);
...
...
@@ -1318,6 +1323,28 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer
::
ReSendToPlayer
(
*
oit
);
break
;
}
case
MSG_TAG_SWAP
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
int
mcount
=
BufferIO
::
ReadInt8
(
pbuf
);
int
ecount
=
BufferIO
::
ReadInt8
(
pbuf
);
int
hcount
=
BufferIO
::
ReadInt8
(
pbuf
);
pbufw
=
pbuf
+
4
;
pbuf
+=
hcount
*
4
+
4
;
NetServer
::
SendBufferToPlayer
(
cur_player
[
player
],
STOC_GAME_MSG
,
offset
,
pbuf
-
offset
);
for
(
int
i
=
0
;
i
<
hcount
;
++
i
)
{
if
(
!
(
pbufw
[
i
]
&
0x80000000
))
BufferIO
::
WriteInt32
(
pbufw
,
0
);
else
pbufw
+=
4
;
}
for
(
int
i
=
0
;
i
<
4
;
++
i
)
if
(
players
[
i
]
!=
cur_player
[
player
])
NetServer
::
SendBufferToPlayer
(
players
[
i
],
STOC_GAME_MSG
,
offset
,
pbuf
-
offset
);
for
(
auto
oit
=
observers
.
begin
();
oit
!=
observers
.
end
();
++
oit
)
NetServer
::
ReSendToPlayer
(
*
oit
);
RefreshExtra
(
player
);
break
;
}
}
}
return
0
;
...
...
@@ -1510,7 +1537,7 @@ int TagDuel::MessageHandler(long fduel, int type) {
}
return
0
;
}
void
TagDuel
::
Single
Timer
(
evutil_socket_t
fd
,
short
events
,
void
*
arg
)
{
void
TagDuel
::
Tag
Timer
(
evutil_socket_t
fd
,
short
events
,
void
*
arg
)
{
TagDuel
*
sd
=
static_cast
<
TagDuel
*>
(
arg
);
sd
->
time_elapsed
++
;
if
(
sd
->
time_elapsed
>=
sd
->
time_limit
[
sd
->
last_response
])
{
...
...
gframe/tag_duel.h
View file @
f23cbe45
...
...
@@ -39,7 +39,7 @@ public:
void
RefreshSingle
(
int
player
,
int
location
,
int
sequence
,
int
flag
=
0x181fff
);
static
int
MessageHandler
(
long
fduel
,
int
type
);
static
void
Single
Timer
(
evutil_socket_t
fd
,
short
events
,
void
*
arg
);
static
void
Tag
Timer
(
evutil_socket_t
fd
,
short
events
,
void
*
arg
);
protected:
DuelPlayer
*
players
[
4
];
...
...
ocgcore/field.cpp
View file @
f23cbe45
...
...
@@ -585,6 +585,15 @@ void field::tag_swap(uint8 playerid) {
}
pduel
->
write_buffer8
(
MSG_TAG_SWAP
);
pduel
->
write_buffer8
(
playerid
);
pduel
->
write_buffer8
(
player
[
playerid
].
list_main
.
size
());
pduel
->
write_buffer8
(
player
[
playerid
].
list_extra
.
size
());
pduel
->
write_buffer8
(
player
[
playerid
].
list_hand
.
size
());
if
(
core
.
deck_reversed
)
pduel
->
write_buffer32
((
*
player
[
playerid
].
list_main
.
rbegin
())
->
data
.
code
);
else
pduel
->
write_buffer32
(
0
);
for
(
auto
cit
=
player
[
playerid
].
list_hand
.
begin
();
cit
!=
player
[
playerid
].
list_hand
.
end
();
++
cit
)
pduel
->
write_buffer32
((
*
cit
)
->
data
.
code
|
((
*
cit
)
->
is_status
(
STATUS_IS_PUBLIC
)
?
0x80000000
:
0
));
}
void
field
::
add_effect
(
effect
*
peffect
,
uint8
owner_player
)
{
if
(
!
peffect
->
handler
)
{
...
...
ocgcore/operations.cpp
View file @
f23cbe45
...
...
@@ -352,7 +352,7 @@ int32 field::draw(uint16 step, effect* reason_effect, uint32 reason, uint8 reaso
pduel
->
write_buffer8
(
playerid
);
pduel
->
write_buffer8
(
drawed
);
for
(
uint32
i
=
0
;
i
<
drawed
;
++
i
)
pduel
->
write_buffer32
(
cv
[
i
]
->
data
.
code
);
pduel
->
write_buffer32
(
cv
[
i
]
->
data
.
code
|
(
cv
[
i
]
->
is_status
(
STATUS_IS_PUBLIC
)
?
0x80000000
:
0
)
);
if
(
core
.
deck_reversed
&&
(
public_count
<
drawed
))
{
pduel
->
write_buffer8
(
MSG_CONFIRM_CARDS
);
pduel
->
write_buffer8
(
1
-
playerid
);
...
...
script/c25123082.lua
View file @
f23cbe45
...
...
@@ -26,7 +26,7 @@ function c25123082.target(e,tp,eg,ep,ev,re,r,rp,chk,chkc)
end
function
c25123082
.
activate
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
local
tc
=
Duel
.
GetFirstTarget
()
if
tc
:
IsRelateToEffect
(
e
)
and
tc
:
IsFaceup
()
then
if
tc
:
IsRelateToEffect
(
e
)
and
tc
:
IsFaceup
()
and
not
tc
:
IsImmuneToEffect
(
e
)
then
local
e1
=
Effect
.
CreateEffect
(
e
:
GetHandler
())
e1
:
SetType
(
EFFECT_TYPE_SINGLE
)
e1
:
SetCode
(
EFFECT_UPDATE_ATTACK
)
...
...
@@ -38,7 +38,7 @@ function c25123082.activate(e,tp,eg,ep,ev,re,r,rp)
e2
:
SetCategory
(
CATEGORY_TOHAND
+
CATEGORY_SEARCH
)
e2
:
SetType
(
EFFECT_TYPE_FIELD
+
EFFECT_TYPE_TRIGGER_O
)
e2
:
SetCode
(
EVENT_BATTLE_DESTROYING
)
e2
:
SetLabel
Object
(
tc
)
e2
:
SetLabel
(
tc
:
GetFieldID
()
)
e2
:
SetCondition
(
c25123082
.
shcon
)
e2
:
SetTarget
(
c25123082
.
shtg
)
e2
:
SetOperation
(
c25123082
.
shop
)
...
...
@@ -47,7 +47,7 @@ function c25123082.activate(e,tp,eg,ep,ev,re,r,rp)
end
end
function
c25123082
.
shcon
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
return
eg
:
IsContains
(
e
:
GetLabelObject
()
)
return
eg
:
GetFirst
():
GetFieldID
()
==
e
:
GetLabel
(
)
end
function
c25123082
.
shfilter
(
c
)
return
c
:
IsSetCard
(
0x106e
)
and
c
:
IsType
(
TYPE_SPELL
)
and
c
:
IsAbleToHand
()
...
...
script/c25924653.lua
View file @
f23cbe45
...
...
@@ -51,7 +51,7 @@ function c25924653.spgop(e,tp,eg,ep,ev,re,r,rp)
if
tc
and
tc
:
IsRelateToEffect
(
e
)
and
Duel
.
SpecialSummon
(
tc
,
104
,
tp
,
tp
,
false
,
false
,
POS_FACEUP
)
>
0
and
c
:
IsFaceup
()
and
c
:
IsRelateToEffect
(
e
)
then
c
:
SetCardTarget
(
tc
)
tc
:
RegisterFlagEffect
(
2592465
3
,
RESET_EVENT
+
0x13e0000
,
0
,
1
)
tc
:
RegisterFlagEffect
(
2592465
4
,
RESET_EVENT
+
0x13e0000
,
0
,
1
)
local
e1
=
Effect
.
CreateEffect
(
c
)
e1
:
SetType
(
EFFECT_TYPE_SINGLE
)
e1
:
SetProperty
(
EFFECT_FLAG_OWNER_RELATE
)
...
...
@@ -71,7 +71,7 @@ function c25924653.discon(e)
return
e
:
GetOwner
():
IsHasCardTarget
(
e
:
GetHandler
())
end
function
c25924653
.
disop
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
if
re
:
GetHandler
():
GetFlagEffect
(
2592465
3
)
~=
0
then
if
re
:
GetHandler
():
GetFlagEffect
(
2592465
4
)
~=
0
then
Duel
.
NegateEffect
(
ev
)
end
end
...
...
script/c27068117.lua
View file @
f23cbe45
...
...
@@ -14,7 +14,8 @@ function c27068117.filter(c)
end
function
c27068117
.
target
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
chk
,
chkc
)
if
chkc
then
return
chkc
:
IsLocation
(
LOCATION_MZONE
)
and
c27068117
.
filter
(
chkc
)
end
if
chk
==
0
then
return
Duel
.
IsExistingTarget
(
c27068117
.
filter
,
tp
,
LOCATION_MZONE
,
LOCATION_MZONE
,
1
,
nil
)
end
if
chk
==
0
then
return
not
e
:
GetHandler
():
IsLocation
(
LOCATION_GRAVE
)
and
Duel
.
IsExistingTarget
(
c27068117
.
filter
,
tp
,
LOCATION_MZONE
,
LOCATION_MZONE
,
1
,
nil
)
end
Duel
.
Hint
(
HINT_SELECTMSG
,
tp
,
HINTMSG_TARGET
)
Duel
.
SelectTarget
(
tp
,
c27068117
.
filter
,
tp
,
LOCATION_MZONE
,
LOCATION_MZONE
,
1
,
1
,
nil
)
end
...
...
script/c33302407.lua
View file @
f23cbe45
...
...
@@ -25,13 +25,13 @@ function c33302407.filter(c)
return
c
:
IsSetCard
(
0x25
)
and
c
:
IsType
(
TYPE_MONSTER
)
end
function
c33302407
.
distg
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
chk
)
local
ct
=
Duel
.
GetMatchingGroupCount
(
c33302407
.
filter
,
tp
,
LOCATION_
GRAV
E
,
0
,
nil
)
local
ct
=
Duel
.
GetMatchingGroupCount
(
c33302407
.
filter
,
tp
,
LOCATION_
MZON
E
,
0
,
nil
)
if
chk
==
0
then
return
ct
>
0
and
Duel
.
IsPlayerCanDiscardDeck
(
1
-
tp
,
0
)
end
Duel
.
SetOperationInfo
(
0
,
CATEGORY_DECKDES
,
nil
,
0
,
1
-
tp
,
ct
)
end
function
c33302407
.
disop
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
if
not
e
:
GetHandler
():
IsRelateToEffect
(
e
)
then
return
end
local
ct
=
Duel
.
GetMatchingGroupCount
(
c33302407
.
filter
,
tp
,
LOCATION_
GRAV
E
,
0
,
nil
)
local
ct
=
Duel
.
GetMatchingGroupCount
(
c33302407
.
filter
,
tp
,
LOCATION_
MZON
E
,
0
,
nil
)
if
ct
>
0
then
Duel
.
DiscardDeck
(
1
-
tp
,
ct
,
REASON_EFFECT
)
end
...
...
script/c33900648.lua
View file @
f23cbe45
...
...
@@ -6,14 +6,14 @@ function c33900648.initial_effect(c)
e1
:
SetCode
(
EVENT_FREE_CHAIN
)
c
:
RegisterEffect
(
e1
)
--maintain
--
local e2=Effect.CreateEffect(c)
--
e2:SetType(EFFECT_TYPE_FIELD+EFFECT_TYPE_CONTINUOUS)
--
e2:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE)
-- e2:SetCode(EVENT_PHASE+PHASE_STANDBY
)
--
e2:SetRange(LOCATION_SZONE)
--
e2:SetCountLimit(1)
--
e2:SetOperation(c33900648.mtop)
--
c:RegisterEffect(e2)
local
e2
=
Effect
.
CreateEffect
(
c
)
e2
:
SetType
(
EFFECT_TYPE_FIELD
+
EFFECT_TYPE_CONTINUOUS
)
e2
:
SetProperty
(
EFFECT_FLAG_CANNOT_DISABLE
+
EFFECT_FLAG_UNCOPYABLE
)
e2
:
SetCode
(
EVENT_PHASE
+
PHASE_END
)
e2
:
SetRange
(
LOCATION_SZONE
)
e2
:
SetCountLimit
(
1
)
e2
:
SetOperation
(
c33900648
.
mtop
)
c
:
RegisterEffect
(
e2
)
--adjust
local
e3
=
Effect
.
CreateEffect
(
c
)
e3
:
SetType
(
EFFECT_TYPE_FIELD
+
EFFECT_TYPE_CONTINUOUS
)
...
...
script/c51589188.lua
View file @
f23cbe45
...
...
@@ -26,7 +26,7 @@ function c51589188.target(e,tp,eg,ep,ev,re,r,rp,chk,chkc)
end
function
c51589188
.
activate
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
local
tc
=
Duel
.
GetFirstTarget
()
if
tc
:
IsRelateToEffect
(
e
)
and
tc
:
IsFaceup
()
then
if
tc
:
IsRelateToEffect
(
e
)
and
tc
:
IsFaceup
()
and
not
tc
:
IsImmuneToEffect
(
e
)
then
local
e1
=
Effect
.
CreateEffect
(
e
:
GetHandler
())
e1
:
SetType
(
EFFECT_TYPE_SINGLE
)
e1
:
SetCode
(
EFFECT_UPDATE_ATTACK
)
...
...
script/c51790181.lua
View file @
f23cbe45
...
...
@@ -13,14 +13,6 @@ function c51790181.initial_effect(c)
end
function
c51790181
.
cost
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
chk
)
if
chk
==
0
then
return
Duel
.
GetFlagEffect
(
tp
,
51790181
)
==
0
end
--oath effects
local
e1
=
Effect
.
CreateEffect
(
e
:
GetHandler
())
e1
:
SetType
(
EFFECT_TYPE_FIELD
)
e1
:
SetProperty
(
EFFECT_FLAG_PLAYER_TARGET
+
EFFECT_FLAG_OATH
)
e1
:
SetCode
(
EFFECT_CANNOT_SPECIAL_SUMMON
)
e1
:
SetReset
(
RESET_PHASE
+
PHASE_END
)
e1
:
SetTargetRange
(
1
,
0
)
Duel
.
RegisterEffect
(
e1
,
tp
)
Duel
.
RegisterFlagEffect
(
tp
,
51790181
,
RESET_PHASE
+
PHASE_END
,
EFFECT_FLAG_OATH
,
1
)
end
function
c51790181
.
target
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
chk
,
chkc
)
...
...
script/c52628687.lua
View file @
f23cbe45
...
...
@@ -52,22 +52,23 @@ function c52628687.operation(e,tp,eg,ep,ev,re,r,rp)
local
c
=
e
:
GetHandler
()
local
tc
=
Duel
.
GetFirstTarget
()
if
c
:
IsRelateToEffect
(
e
)
and
tc
:
IsRelateToEffect
(
e
)
and
Duel
.
SpecialSummon
(
tc
,
0
,
tp
,
tp
,
false
,
false
,
POS_FACEUP_ATTACK
)
~=
0
then
Duel
.
Equip
(
tp
,
c
,
tc
)
--Add Equip limit
local
e1
=
Effect
.
CreateEffect
(
tc
)
e1
:
SetType
(
EFFECT_TYPE_SINGLE
)
e1
:
SetCode
(
EFFECT_EQUIP_LIMIT
)
e1
:
SetProperty
(
EFFECT_FLAG_CANNOT_DISABLE
)
and
Duel
.
SpecialSummonStep
(
tc
,
0
,
tp
,
tp
,
false
,
false
,
POS_FACEUP_ATTACK
)
then
--levelup
local
e1
=
Effect
.
CreateEffect
(
c
)
e1
:
SetType
(
EFFECT_TYPE_EQUIP
)
e1
:
SetCode
(
EFFECT_UPDATE_LEVEL
)
e1
:
SetValue
(
e
:
GetLabel
())
e1
:
SetReset
(
RESET_EVENT
+
0x1fe0000
)
e1
:
SetValue
(
c52628687
.
eqlimit
)
c
:
RegisterEffect
(
e1
)
--levelup
local
e2
=
Effect
.
CreateEffect
(
c
)
e2
:
SetType
(
EFFECT_TYPE_EQUIP
)
e2
:
SetCode
(
EFFECT_UPDATE_LEVEL
)
e2
:
SetValue
(
e
:
GetLabel
())
Duel
.
SpecialSummonComplete
()
Duel
.
Equip
(
tp
,
c
,
tc
)
--Add Equip limit
local
e2
=
Effect
.
CreateEffect
(
tc
)
e2
:
SetType
(
EFFECT_TYPE_SINGLE
)
e2
:
SetCode
(
EFFECT_EQUIP_LIMIT
)
e2
:
SetProperty
(
EFFECT_FLAG_CANNOT_DISABLE
)
e2
:
SetReset
(
RESET_EVENT
+
0x1fe0000
)
e2
:
SetValue
(
c52628687
.
eqlimit
)
c
:
RegisterEffect
(
e2
)
end
end
script/c63676256.lua
View file @
f23cbe45
...
...
@@ -99,18 +99,18 @@ end
function
c63676256
.
descon
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
return
e
:
GetHandler
():
IsStatus
(
STATUS_UNION
)
and
eg
:
GetCount
()
==
1
and
eg
:
GetFirst
()
==
e
:
GetHandler
():
GetEquipTarget
()
end
function
c63676256
.
dfilter
(
c
,
att
)
return
c
:
IsFaceup
()
and
c
:
Is
Attribute
(
att
)
and
c
:
IsDestructable
()
function
c63676256
.
dfilter
(
c
,
rac
)
return
c
:
IsFaceup
()
and
c
:
Is
Race
(
rac
)
and
c
:
IsDestructable
()
end
function
c63676256
.
destg
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
chk
)
if
chk
==
0
then
return
true
end
local
tc
=
eg
:
GetFirst
():
GetBattleTarget
()
local
desg
=
Duel
.
GetMatchingGroup
(
c63676256
.
dfilter
,
tp
,
LOCATION_MZONE
,
LOCATION_MZONE
,
nil
,
tc
:
Get
Attribut
e
())
local
desg
=
Duel
.
GetMatchingGroup
(
c63676256
.
dfilter
,
tp
,
LOCATION_MZONE
,
LOCATION_MZONE
,
nil
,
tc
:
Get
Rac
e
())
Duel
.
SetOperationInfo
(
0
,
CATEGORY_DESTROY
,
desg
,
desg
:
GetCount
(),
0
,
0
)
end
function
c63676256
.
desop
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
if
not
e
:
GetHandler
():
IsRelateToEffect
(
e
)
then
return
end
local
tc
=
eg
:
GetFirst
():
GetBattleTarget
()
local
desg
=
Duel
.
GetMatchingGroup
(
c63676256
.
dfilter
,
tp
,
LOCATION_MZONE
,
LOCATION_MZONE
,
nil
,
tc
:
Get
Attribut
e
())
local
desg
=
Duel
.
GetMatchingGroup
(
c63676256
.
dfilter
,
tp
,
LOCATION_MZONE
,
LOCATION_MZONE
,
nil
,
tc
:
Get
Rac
e
())
Duel
.
Destroy
(
desg
,
REASON_EFFECT
)
end
script/c99004752.lua
View file @
f23cbe45
...
...
@@ -24,7 +24,7 @@ function c99004752.target(e,tp,eg,ep,ev,re,r,rp,chk,chkc)
end
function
c99004752
.
activate
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
local
tc
=
Duel
.
GetFirstTarget
()
if
tc
:
IsFaceup
()
and
tc
:
IsRelateToEffect
(
e
)
then
if
tc
:
IsFaceup
()
and
tc
:
IsRelateToEffect
(
e
)
and
not
tc
:
IsImmuneToEffect
(
e
)
then
local
e1
=
Effect
.
CreateEffect
(
e
:
GetHandler
())
e1
:
SetType
(
EFFECT_TYPE_SINGLE
)
e1
:
SetCode
(
EFFECT_SET_ATTACK_FINAL
)
...
...
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