Re: [confirmed]Suspend prevents planewalker abilities
Posted: 17 Jan 2022, 00:24
Thanks again, Korath; yes, that was the only crash.
I've got the two new functions mostly working; the only issue is something in the AI threading, specifically around the section for determining x-values. I can't get AI to cast an x spell under any circumstances. I bet it's a similar issue around a pointer - I'm not sure if I should do the recasts to char or not. Maybe you can see something obvious I'm overlooking? Maybe a lot of things I'm misunderstanding?
If not, we can just keep your shim and be done with it, although it would be very nice to start changing this function to handle hybrid.
I've got the two new functions mostly working; the only issue is something in the AI threading, specifically around the section for determining x-values. I can't get AI to cast an x spell under any circumstances. I bet it's a similar issue around a pointer - I'm not sure if I should do the recasts to char or not. Maybe you can see something obvious I'm overlooking? Maybe a lot of things I'm misunderstanding?
If not, we can just keep your shim and be done with it, although it would be very nice to start changing this function to handle hybrid.
- Code: Select all
#define mana_cost_xbugrw EXE_BYTE_PTR(0x55cf18)
static void fn_402593(card_data_t* cd)
{
int i;
for(i=COLOR_COLORLESS;i<=COLOR_WHITE;i++)
pay_mana_xbugrwaU[i] = mana_cost_xbugrw[i];
if ( cd->type & TYPE_ARTIFACT )
{
PAY_MANA_ARTIFACT = PAY_MANA_COLORLESS;
PAY_MANA_COLORLESS = 0;
}
}
#undef mana_cost_xbugrw
#define TENTATIVE_ai_branch_value_99_is_abort EXE_DWORD(0x7a2fe4)
#define TENTATIVE_mana_paid_for_spell EXE_BYTE_PTR(0x55cef0)
#define TENTATIVE_ai_save_values_on_speculative_branch EXE_FN(int, 0x498F20, int)
#define TENTATIVE_ai_retrieve_values_on_chosen_branch EXE_FN(int, 0x499050, void)
#define charge_mana_w_global_cost_mod EXE_FN(int, 0x4302c0, int, int, color_t, int)
#define TENTATIVE_update_mana_spent EXE_FN(int, 0x430260, int)
#define FN_42DE60 EXE_FN(int, 0x42DE60, int, int, int, int, int)
static int charge_spell_cost(card_data_t* cd, int player, int card)
{ // 0x402680
fn_402593(cd);
card_ptr_t* cp = cards_ptr[ get_id(player, card) ];
int i, is_x_spell = cp->req_colorless == 40;
int8_t* byte_55CF20 = (int8_t*)EXE_BYTE_PTR(0x55cf20); // Amount of surplus free mana?
int8_t* byte_4EF4FC = (int8_t*)EXE_BYTE_PTR(0x4EF4FC);
if ( (player == HUMAN || trace_mode & 2) && ai_is_speculating != 1 ){
// if ( !v5 ) // something in edx?
// return charge_mana_w_global_cost_mod(player, card, COLOR_COLORLESS, 0);
int result;
if ( !(result = charge_mana_w_global_cost_mod(player, card, COLOR_COLORLESS, 0)) )
return 0;
memcpy(TENTATIVE_mana_paid_for_spell, &mana_paid, 0x1Cu);
int v7[8];
for(i=0;i<8;i++)
v7[i] = byte_55CF20[i];
if ( *byte_55CF20 < 0 ){
for(i=0;i<8;i++){
mana_pool[player][i] -= byte_55CF20[i];
byte_4EF4FC[player] -= v7[i];
}
}
if( is_x_spell )
charge_mana(player, 0, -1);
goto LABEL_33;
}
if ( cd->type & TYPE_ARTIFACT ){
int v9 = PAY_MANA_ARTIFACT;
PAY_MANA_ARTIFACT = 0;
return charge_mana_w_global_cost_mod(player, card, COLOR_ARTIFACT, v9);
}
int result = charge_mana_w_global_cost_mod(player, card, COLOR_COLORLESS, 0);
if ( result ){
result = cd->cc[1];
if ( result < 0 ){
memcpy(TENTATIVE_mana_paid_for_spell, &mana_paid, 0x1Cu);
int v11 = mana_paid[COLOR_ANY];
int v10 = TENTATIVE_mana_paid_for_spell[COLOR_ANY];
int v12[8];
for(i=0;i<8;i++)
v12[i] = byte_55CF20[i];
if ( *byte_55CF20 < 0 ){
for(i=0;i<8;i++){
mana_pool[player][i] -= byte_55CF20[i];
byte_4EF4FC[player] -= v12[i];
}
}
if ( player == HUMAN ){
int old_max_x = max_x_value;
max_x_value = has_mana(player, COLOR_ANY, 1);
FN_42DE60(v10, v11, player, 0, -1);
max_x_value = old_max_x;
}
else{
int amt_for_x;
if ( ai_is_speculating == 1 ){
if ( internal_rand(2) ){
amt_for_x = has_mana(player, COLOR_ANY, 1);
TENTATIVE_ai_branch_value_99_is_abort = amt_for_x;
if ( life[HUMAN] < amt_for_x && !internal_rand(3) ){
amt_for_x = life[HUMAN];
TENTATIVE_ai_branch_value_99_is_abort = life[HUMAN];
}
if ( max_x_value != -1 && max_x_value < TENTATIVE_ai_branch_value_99_is_abort ){
amt_for_x = max_x_value;
TENTATIVE_ai_branch_value_99_is_abort = max_x_value;
}
}
else{
int v14 = has_mana(player, COLOR_ANY, 1);
if ( v14 )
v14 = internal_rand(v14) + 1;
amt_for_x = v14;
TENTATIVE_ai_branch_value_99_is_abort = v14;
}
TENTATIVE_ai_save_values_on_speculative_branch(v11);
}
else{
TENTATIVE_ai_retrieve_values_on_chosen_branch();
amt_for_x = TENTATIVE_ai_branch_value_99_is_abort;
}
int store_max_x_value = max_x_value;
max_x_value = amt_for_x;
FN_42DE60(v10, v11, player, 0, -1);
max_x_value = store_max_x_value;
}
LABEL_33:
result = *byte_55CF20;
if ( byte_55CF20[COLOR_ANY] != 0 ){
int found = 0;
for(i=0;i<8;i++){
if( byte_55CF20[i] + (mana_pool[player][i] < 0) )
found = 1;
mana_pool[player][i] += byte_55CF20[i];
}
if ( found ){
int8_t v19 = 0;
for(i=0;i<8;i++)
v19 |= ((mana_pool[player][i] > 0) << i);
EXE_FN(int, 0x4301a0, int, int)(0, v19);
result = v19;
memset(mana_pool[player], 0, sizeof(mana_pool[player]));
}
else{
byte_4EF4FC[player] += result;
}
}
if ( !x_value )
ai_modifier -= 100;
if ( spell_fizzled == 1 ){
TENTATIVE_update_mana_spent(*TENTATIVE_mana_paid_for_spell);
for(i=0;i<8;i++){
result = TENTATIVE_mana_paid_for_spell[i];
mana_pool[player][i] += result;
byte_4EF4FC[player] += result;
}
}
return result;
}
}
return result;
}
#undef TENTATIVE_ai_branch_value_99_is_abort
#undef TENTATIVE_mana_paid_for_spell
#undef TENTATIVE_ai_save_values_on_speculative_branch
#undef TENTATIVE_ai_retrieve_values_on_chosen_branch
#undef charge_mana_w_global_cost_mod
#undef TENTATIVE_update_mana_spent
#undef FN_42DE60
- Code: Select all
int __usercall sub_402680@<eax>(int a1@<edi>, int a2, int a3)
{
int v3; // edx
int result; // eax
int v5; // eax
int v6; // ecx
int v7; // eax
int v8; // eax
int v9; // ecx
int v10; // eax
int v11; // ST0C_4
int v12; // ST0C_4
int v13; // ecx
bool v14; // sf
int v15; // ST0C_4
int v16; // ecx
unsigned int v17; // edx
int v18; // [esp+8h] [ebp-4h]
sub_402593(a1);
if ( (!a2 || dword_790640 & 2) && dword_728574 != 1 )
{
if ( !v3 )
return sub_4302C0(a2, a3, 0, 0);
result = sub_4302C0(a2, a3, 0, 0);
if ( !result )
return result;
qmemcpy(dword_55CEF0, &dword_55CED0, 0x1Cu);
v5 = (char)dword_55CF20;
if ( (dword_55CF20 & 0x80u) != 0 )
{
v6 = 8 * a2;
dword_4EF4E0[v6] -= (char)dword_55CF20;
dword_4EF4FC[v6] -= v5;
}
sub_42DE60(a2, 0, -1);
goto LABEL_33;
}
if ( *(_BYTE *)(a1 + 40) & 0x40 )
{
v7 = dword_4EF418;
dword_4EF418 = 0;
return sub_4302C0(a2, a3, 6, v7);
}
result = sub_4302C0(a2, a3, 0, 0);
if ( result )
{
result = *(char *)(a1 + 44);
if ( result < 0 )
{
qmemcpy(dword_55CEF0, &dword_55CED0, 0x1Cu);
v8 = (char)dword_55CF20;
if ( (dword_55CF20 & 0x80u) != 0 )
{
v9 = 8 * a2;
dword_4EF4E0[v9] -= (char)dword_55CF20;
dword_4EF4FC[v9] -= v8;
}
if ( a2 == dword_736AD8 )
{
v12 = dword_4EF198;
dword_4EF198 = sub_49D510(a2, 7, 1);
sub_42DE60(a2, 0, -1);
dword_4EF198 = v12;
}
else
{
if ( dword_728574 == 1 )
{
if ( sub_44E050(2) )
{
v18 = sub_49D510(a2, 7, 1);
dword_7A2FE4 = v18;
if ( dword_4EF528 < v18 && !sub_44E050(3) )
{
v18 = dword_4EF528;
dword_7A2FE4 = dword_4EF528;
}
if ( dword_4EF198 != -1 && dword_4EF198 < dword_7A2FE4 )
{
v18 = dword_4EF198;
dword_7A2FE4 = dword_4EF198;
}
}
else
{
v10 = sub_49D510(a2, 7, 1);
if ( v10 )
v10 = sub_44E050(v10) + 1;
v18 = v10;
dword_7A2FE4 = v10;
}
sub_498F20();
}
else
{
sub_499050();
v18 = dword_7A2FE4;
}
v11 = dword_4EF198;
dword_4EF198 = v18;
sub_42DE60(a2, 0, -1);
dword_4EF198 = v11;
}
LABEL_33:
v13 = 8 * a2;
result = (char)dword_55CF20;
if ( (dword_55CF20 & 0x80u) != 0 )
{
v14 = (char)dword_55CF20 + dword_4EF4E0[v13] < 0;
dword_4EF4E0[v13] += (char)dword_55CF20;
if ( v14 )
{
v15 = dword_4EF4E0[v13];
sub_4301A0(0, v15);
result = v15;
dword_4EF4E0[8 * a2] = 0;
}
else
{
dword_4EF4FC[v13] += result;
}
}
if ( !dword_4EF1A0 )
dword_7A31A8 -= 100;
if ( dword_4EF194 == 1 )
{
sub_430260(dword_55CEF0);
v17 = 0;
do
{
result = dword_55CEF0[v17];
*(int *)((char *)&dword_4EF4E0[v17] + v16) += result;
*(int *)((char *)dword_4EF4FC + v16) += result;
++v17;
}
while ( v17 < 8 );
}
return result;
}
}
return result;
}