[fixed] Demonic Pact dialog
Moderators: BAgate, drool66, Aswan jaguar, gmzombie, stassy, CCGHQ Admins
Re: [confirmed] Demonic Pact dialog
by drool66 » 01 Dec 2021, 15:57
Confirmed. We can fix this in individual cards with DLG_OMIT_ILLEGAL, but that's not exactly copacetic. Fixing that probably involves working with the windows interface, which I don't know a lot about.
Another idiosyncrasy - if a dialog option's ai_priority <= 0, AI can just run through the options without actually choosing that one, like if it has a Demonic Pact with the first three options already chosen. Changing the fourth option's ai_priority to 1 disallows this behavior. I can speculate on how to get dialog_ai() to handle non-positive values for ai_priority.
Fixed both issues for Demonic Pact, unpushed, but leaving this open for the sake of the two issues above.
Another idiosyncrasy - if a dialog option's ai_priority <= 0, AI can just run through the options without actually choosing that one, like if it has a Demonic Pact with the first three options already chosen. Changing the fourth option's ai_priority to 1 disallows this behavior. I can speculate on how to get dialog_ai() to handle non-positive values for ai_priority.
Fixed both issues for Demonic Pact, unpushed, but leaving this open for the sake of the two issues above.
The latest images for Manalink will be here.
The latest Manalink installation directory will be here. Well, not quite, anymore. Check the latest patches.
The latest Manalink installation directory will be here. Well, not quite, anymore. Check the latest patches.
-
drool66 - Programmer
- Posts: 1163
- Joined: 25 Nov 2010, 22:38
- Has thanked: 186 times
- Been thanked: 267 times
Re: [confirmed] Demonic Pact dialog
by Korath » 01 Dec 2021, 16:15
See the WM_INITDIALOG handler in Shandalar's hook_dlgproc_do_dialog() for how I fixed the first issue over there. (Basically, if the first option is grayed out when the dialog is created, send it a "home" keypress. And, on reflection, it's probably not even necessary to check if the first option is grayed out, either - just always send the key.)
Having at least one option with positive ai_priority, or being cancellable, is part of DIALOG()'s documented preconditions. I suppose you could add a popup to complain if that's untrue, though whether that's more irritating for end-users than the current wrong behavior would vary from card to card. Or you could just give each legal option an even weighting.
Having at least one option with positive ai_priority, or being cancellable, is part of DIALOG()'s documented preconditions. I suppose you could add a popup to complain if that's untrue, though whether that's more irritating for end-users than the current wrong behavior would vary from card to card. Or you could just give each legal option an even weighting.
-
Korath - DEVELOPER
- Posts: 3707
- Joined: 02 Jun 2013, 05:57
- Has thanked: 496 times
- Been thanked: 1106 times
Re: [confirmed] Demonic Pact dialog
by drool66 » 03 Dec 2021, 06:35
Done,unpushed, though I just made it dependent on "(who_sees = EXE_DWORD(0x736ad8)) == HUMAN"; I don't see a separate param in ML for "who_chooses." Does it even need to do that?See the WM_INITDIALOG handler in Shandalar's hook_dlgproc_do_dialog() for how I fixed the first issue over there. (Basically, if the first option is grayed out when the dialog is created, send it a "home" keypress. And, on reflection, it's probably not even necessary to check if the first option is grayed out, either - just always send the key.)
The latest images for Manalink will be here.
The latest Manalink installation directory will be here. Well, not quite, anymore. Check the latest patches.
The latest Manalink installation directory will be here. Well, not quite, anymore. Check the latest patches.
-
drool66 - Programmer
- Posts: 1163
- Joined: 25 Nov 2010, 22:38
- Has thanked: 186 times
- Been thanked: 267 times
Re: [fixed] Demonic Pact dialog
by Korath » 03 Dec 2021, 16:34
It's harmless to send it regardless of who_sees - wndproc_BigCardChoiceClass(), which eventually gets the message, ignores WM_KEYDOWN unless player 0 is choosing.
do_dialog()@0x471EB0 sends !who_chooses as the last parameter to raw_do_dialog()@0x471B60, which sets it in one of the fields of the struct dialog_args_t { int bigcard_player; int bigcard_card; int smallcard_player; int smallcard_card; char* prompt; int human_chooses; } it passes as the dialog's dwInitParam, becoming lparam in dlgproc_do_dialog()'s WM_INITDIALOG handler. A pointer to the struct gets stored in static_dlg_args, which is at 0x607490 in Manalink. What leads you to think 0x736ad8 is relevant?
do_dialog()@0x471EB0 sends !who_chooses as the last parameter to raw_do_dialog()@0x471B60, which sets it in one of the fields of the struct dialog_args_t { int bigcard_player; int bigcard_card; int smallcard_player; int smallcard_card; char* prompt; int human_chooses; } it passes as the dialog's dwInitParam, becoming lparam in dlgproc_do_dialog()'s WM_INITDIALOG handler. A pointer to the struct gets stored in static_dlg_args, which is at 0x607490 in Manalink. What leads you to think 0x736ad8 is relevant?
-
Korath - DEVELOPER
- Posts: 3707
- Joined: 02 Jun 2013, 05:57
- Has thanked: 496 times
- Been thanked: 1106 times
Re: [fixed] Demonic Pact dialog
by drool66 » 03 Dec 2021, 21:37
Not having everything mapped properly. I deduced (wrongly) from the lines in do_dialog():What leads you to think 0x736ad8 is relevant?
- Code: Select all
v10 = a2 == dword_736AD8;
v13 = sub_471B60(a1, HIDWORD(a2), a3, a4, HIDWORD(a4), (int)&byte_60A690, v10); //raw_do_dialog()
- Code: Select all
typedef struct
{
int bigcard_player;
int bigcard_card;
int smallcard_player;
int smallcard_card;
const char* prompt;
int human_chooses;
} dialog_args_t;
#define option_Layout EXE_DWORD(0x787260)
#define hwnd_FullCardClass EXE_PTR_VOID(0x715ca0)
#define static_dlg_args EXE_TYP_PTR(dialog_args_t, 0x607490)
INT_PTR __stdcall dlgproc_do_dialog_hook(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
if (msg == (option_Layout == 2 ? WM_RBUTTONDBLCLK : WM_RBUTTONDOWN))
{
SendMessageA(hwnd_FullCardClass, WM_COMMAND, 1, 0);
return 0;
}
// move to first legal choice by sending a home key press
if( static_dlg_args->human_chooses ){
int num_choices = SendDlgItemMessage(hwnd, 1021, WM_USER, 0, 0);
if (num_choices > 0)
SendDlgItemMessage(hwnd, 1021, WM_KEYDOWN, VK_HOME, 0);
}
return EXE_STDCALL_FN(INT_PTR, 0x4aa090, HWND, UINT, WPARAM, LPARAM)(hwnd, msg, wparam, lparam); // dlgproc_do_dialog()
}
- Code: Select all
typedef struct
{
int bigcard_player;
int bigcard_card;
int smallcard_player;
int smallcard_card;
const char* prompt;
int human_chooses;
} dialog_args_t;
#define option_Layout EXE_DWORD(0x787260)
#define hwnd_FullCardClass EXE_PTR_VOID(0x715ca0)
#define static_dlg_args EXE_TYP_PTR(dialog_args_t, 0x607490)
INT_PTR __stdcall dlgproc_do_dialog_hook(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
if (msg == (option_Layout == 2 ? WM_RBUTTONDBLCLK : WM_RBUTTONDOWN))
{
SendMessageA(hwnd_FullCardClass, WM_COMMAND, 1, 0);
return 0;
}
if( msg == WM_INITDIALOG ){
INT_PTR rv = EXE_STDCALL_FN(INT_PTR, 0x4aa090, HWND, UINT, WPARAM, LPARAM)(hwnd, msg, wparam, lparam); // dlgproc_do_dialog()
// move to first legal choice by sending a home key press
if( static_dlg_args->human_chooses ){
int num_choices = SendDlgItemMessage(hwnd, 1021, WM_USER, 0, 0);
if (num_choices > 0)
SendDlgItemMessage(hwnd, 1021, WM_KEYDOWN, VK_HOME, 0);
}
return rv;
}
return EXE_STDCALL_FN(INT_PTR, 0x4aa090, HWND, UINT, WPARAM, LPARAM)(hwnd, msg, wparam, lparam); // dlgproc_do_dialog()
}
The latest images for Manalink will be here.
The latest Manalink installation directory will be here. Well, not quite, anymore. Check the latest patches.
The latest Manalink installation directory will be here. Well, not quite, anymore. Check the latest patches.
-
drool66 - Programmer
- Posts: 1163
- Joined: 25 Nov 2010, 22:38
- Has thanked: 186 times
- Been thanked: 267 times
Re: [fixed] Demonic Pact dialog
by Korath » 03 Dec 2021, 22:09
Second kind of thing is almost right. (The first isn't. A DLGPROC gets all kinds of messages; you only want to respond to WM_INITDIALOG, and only after what the original does - including setting up static_dlg_args in the first place - is complete.)
The problem is that you haven't defined static_dlg_args correctly. What you have is saying that there's a dialog_args_t stored starting at address 0x607490, and that your symbol static_dlg_args is a pointer to it. It's actually stored on the stack, as one of the local variables in raw_do_dialog(), and what's stored at 0x607490 is its address. (That's why I can get away with tacking extra data members onto the end of the structure in Shandalar just by replacing raw_do_dialog().) So you want to make static_dlg_args to be an alias of the pointer at 0x607490, and the way you do that is by #defining it as EXE_TYP(dialog_args_t*, 0x607490).
Omitting the check against dialog_args_t::human_chooses is harmless. Omitting the one against num_choices might not be; it's not completely clear what would happen with an unchoiced popup without it.
The value at 0x736ad8 looks like the equivalent of our HUMAN. It's set once to zero and then never changed again.
The problem is that you haven't defined static_dlg_args correctly. What you have is saying that there's a dialog_args_t stored starting at address 0x607490, and that your symbol static_dlg_args is a pointer to it. It's actually stored on the stack, as one of the local variables in raw_do_dialog(), and what's stored at 0x607490 is its address. (That's why I can get away with tacking extra data members onto the end of the structure in Shandalar just by replacing raw_do_dialog().) So you want to make static_dlg_args to be an alias of the pointer at 0x607490, and the way you do that is by #defining it as EXE_TYP(dialog_args_t*, 0x607490).
Omitting the check against dialog_args_t::human_chooses is harmless. Omitting the one against num_choices might not be; it's not completely clear what would happen with an unchoiced popup without it.
The value at 0x736ad8 looks like the equivalent of our HUMAN. It's set once to zero and then never changed again.
-
Korath - DEVELOPER
- Posts: 3707
- Joined: 02 Jun 2013, 05:57
- Has thanked: 496 times
- Been thanked: 1106 times
Re: [fixed] Demonic Pact dialog
by drool66 » 04 Dec 2021, 01:46
Oh wow, thanks! That explains an awful lot.
EDIT: fixed in c4d64b4 & 41e1a37
EDIT: fixed in c4d64b4 & 41e1a37
The latest images for Manalink will be here.
The latest Manalink installation directory will be here. Well, not quite, anymore. Check the latest patches.
The latest Manalink installation directory will be here. Well, not quite, anymore. Check the latest patches.
-
drool66 - Programmer
- Posts: 1163
- Joined: 25 Nov 2010, 22:38
- Has thanked: 186 times
- Been thanked: 267 times
7 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 76 guests