exile_if_would_be_put_into_graveyard_legacy() is setting kill_code to KILL_REMOVE whenever it's nonzero (just like the disintegrate legacy does). Only setting it in EVENT_GRAVEYARD_FROM_PLAY lets regeneration work. (It still increases creatures_dead_this_turn, which normally doesn't happen for KILL_REMOVE, lets other EVENT_GRAVEYARD_FROM_PLAY handlers that happen to run before it see the original KILL_BURY/KILL_DESTROY/KILL_SACRIFICE kill code, and might incorrectly run TRIGGER_GRAVEYARD_FROM_PLAY before it gets here, though.)
A positive event_result from EVENT_GRAVEYARD_FROM_PLAY keeps the card from being killed at all.
- The function that does most of kill_card()'s work | Open
- Code: Select all
//----- (00477B30) --------------------------------------------------------
void kill_card_guts(int player, int card)
{
card_instance_t* instance = get_card_instance(player, card);
int iid = instance->internal_card_id;
kill_t kill_code = instance->kill_code;
if (!instance->kill_code)
return;
if (!(instance->token_status & STATUS_CANNOT_LEAVE_PLAY))
{
if (!(instance->token_status & STATUS_OBLITERATED))
{
card_data_t* cd = card_data_pointers[iid];
if (kill_code != KILL_REMOVE
&& (cd->type & TYPE_CREATURE)
&& !(instance->state & STATE_INVISIBLE))
++creatures_dead_this_turn;
if (cd->type & (TYPE_EFFECT|TYPE_PERMANENT))
{
push_affected_card_stack();
event_result = 0;
affected_card_controller = player;
affected_card = card;
attacking_card_controller = 1 - player;
attacking_card = -1;
dispatch_event_raw(EVENT_GRAVEYARD_FROM_PLAY);
if (event_result > 0)
{
LOBYTE(instance->token_status) &= ~STATUS_DYING;
pop_affected_card_stack();
return 0;
}
kill_code = instance->kill_code;
pop_affected_card_stack();
}
if (!(cd->type & TYPE_EFFECT))
{
if (kill_code == KILL_REMOVE)
put_card_in_exile(instance->state & STATE_OWNED_BY_OPPONENT ? 1 : 0, card, player);
else
{
if (kill_code != KILL_SACRIFICE && ai_is_speculating != 1)
{
card_data_t* cd = card_data_pointers[instance->original_internal_card_id];
if (cd->type & TYPE_CREATURE)
play_sound_effect(WAV_KILL);
else if (!(cd->type & TYPE_SPELL))
play_sound_effect(WAV_BURIED);
}
if (!(instance->token_status & STATUS_TOKEN))
put_card_in_graveyard(player, card);
if (kill_code == KILL_SACRIFICE)
dispatch_trigger_twice_once_with_each_player_as_reason(current_turn, TRIGGER_GRAVEYARD_FROM_PLAY, "Card(s) to graveyard", 0);
// TRIGGER_GRAVEYARD_FROM_PLAY is also dispatched in TENTATIVE_damage_prevention_step2() for KILL_DESTROY and KILL_BURY
}
}
}
push_affected_card_stack();
int old_trigger_cause_controller = trigger_cause_controller;
int old_trigger_cause = trigger_cause;
trigger_cause_controller = player;
trigger_cause = card;
if (card_data_pointers[iid]->type & TYPE_PERMANENT)
dispatch_trigger_twice_once_with_each_player_as_reason(current_turn, TRIGGER_LEAVE_PLAY, "Card leaving play", 0);
trigger_cause_controller = old_trigger_cause_controller;
trigger_cause = old_trigger_cause;
pop_affected_card_stack();
}
type_t typ = card_data_pointers[iid]->type;
if (typ & TYPE_CREATURE)
--TENTATIVE_creature_count[player];
if (typ & TYPE_ARTIFACT)
--TENTATIVE_artifact_count[player];
if (typ & TYPE_ENCHANTMENT)
--TENTATIVE_enchantment_count[player];
redraw_libraries();
instance->internal_card_id = -1;
instance->kill_code = 0;
instance->unknown0x14 = 0;
if (ai_is_speculating != 1)
sub_471D60(); // redraw everything?
destroy_attached_auras(player, card);
if (card_data_pointers[iid]->type & TYPE_PERMANENT)
recalculate_all_cards_in_play();
}