X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fanim.c;h=68147f0bc06ac100e36e0a51135864a93b587e84;hb=3e76edd9591c599d4ec9b3a179e07c23c0aa135c;hp=bbc38dc45903bde745711a925b9ad3bc3983333e;hpb=064d7909aadd84f633fefcccee3c6f6eb44d47ff;p=rocksndiamonds.git diff --git a/src/anim.c b/src/anim.c index bbc38dc4..68147f0b 100644 --- a/src/anim.c +++ b/src/anim.c @@ -122,6 +122,9 @@ struct GlobalAnimPartControlInfo int x, y; int step_xoffset, step_yoffset; + int tile_x, tile_y; + int tile_xoffset, tile_yoffset; + unsigned int initial_anim_sync_frame; unsigned int anim_random_frame; @@ -1191,6 +1194,7 @@ static void PlayGlobalAnimSoundIfLoop(struct GlobalAnimPartControlInfo *part) static boolean checkGlobalAnimEvent(int anim_event, int mask) { int mask_anim_only = mask & ~ANIM_EVENT_PART_MASK; + int mask_ce_only = mask & ~ANIM_EVENT_PAGE_MASK; if (mask & ANIM_EVENT_ANY) return (anim_event & ANIM_EVENT_ANY); @@ -1199,7 +1203,8 @@ static boolean checkGlobalAnimEvent(int anim_event, int mask) else if (mask & ANIM_EVENT_UNCLICK_ANY) return (anim_event & ANIM_EVENT_UNCLICK_ANY); else if (mask & ANIM_EVENT_CE_CHANGE) - return (anim_event == mask); + return (anim_event == mask || + anim_event == mask_ce_only); else return (anim_event == mask || anim_event == mask_anim_only); @@ -1208,24 +1213,32 @@ static boolean checkGlobalAnimEvent(int anim_event, int mask) static boolean isClickablePart(struct GlobalAnimPartControlInfo *part, int mask) { struct GraphicInfo *c = &part->control_info; - int num_init_events = GetGlobalAnimEventValueCount(c->init_event); - int num_anim_events = GetGlobalAnimEventValueCount(c->anim_event); int i; - for (i = 0; i < num_init_events; i++) + if (part->init_event_state) { - int init_event = GetGlobalAnimEventValue(c->init_event, i); + int num_init_events = GetGlobalAnimEventValueCount(c->init_event); - if (checkGlobalAnimEvent(init_event, mask)) - return TRUE; + for (i = 0; i < num_init_events; i++) + { + int init_event = GetGlobalAnimEventValue(c->init_event, i); + + if (checkGlobalAnimEvent(init_event, mask)) + return TRUE; + } } - for (i = 0; i < num_anim_events; i++) + if (part->anim_event_state) { - int anim_event = GetGlobalAnimEventValue(c->anim_event, i); + int num_anim_events = GetGlobalAnimEventValueCount(c->anim_event); + + for (i = 0; i < num_anim_events; i++) + { + int anim_event = GetGlobalAnimEventValue(c->anim_event, i); - if (checkGlobalAnimEvent(anim_event, mask)) - return TRUE; + if (checkGlobalAnimEvent(anim_event, mask)) + return TRUE; + } } return FALSE; @@ -1358,12 +1371,14 @@ static void InitGlobalAnim_Triggered(struct GlobalAnimPartControlInfo *part, } } -static void InitGlobalAnim_Triggered_ByCustomElement(int nr) +static void InitGlobalAnim_Triggered_ByCustomElement(int nr, int page, + int x, int y) { struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[GAME_MODE_PLAYING]; int event_value = ANIM_EVENT_CE_CHANGE; - int mask = event_value | (nr << ANIM_EVENT_CE_BIT); + int event_bits = (nr << ANIM_EVENT_CE_BIT) | (page << ANIM_EVENT_PAGE_BIT); + int mask = event_value | event_bits; int anim2_nr; for (anim2_nr = 0; anim2_nr < ctrl->num_anims; anim2_nr++) @@ -1380,8 +1395,26 @@ static void InitGlobalAnim_Triggered_ByCustomElement(int nr) if (isClickablePart(part2, mask)) { + struct GraphicInfo *c = &part2->control_info; + + if (c->position == POS_CE) + { + // store CE tile and offset position to handle scrolling + part2->tile_x = x; + part2->tile_y = y; + part2->tile_xoffset = c->x; + part2->tile_yoffset = c->y; + + // restart animation (by using current sync frame) + part2->initial_anim_sync_frame = anim_sync_frame; + } + part2->triggered = TRUE; + // do not trigger any other animation if CE change event was consumed + if (c->style == STYLE_CONSUME_CE_EVENT) + return; + #if 0 Debug("anim:InitGlobalAnim_Triggered_ByCustomElement", "%d.%d TRIGGERED BY CE %d", anim2_nr, part2_nr, nr + 1); @@ -1563,7 +1596,12 @@ static int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part, part->init_event_state) { if (part->initial_anim_sync_frame > 0) - part->initial_anim_sync_frame -= part->init_delay_counter - 1; + { + if (part->init_delay_counter > 0) + part->initial_anim_sync_frame -= part->init_delay_counter - 1; + else + part->initial_anim_sync_frame = anim_sync_frame; + } part->init_delay_counter = 1; part->init_event_state = FALSE; @@ -1688,8 +1726,27 @@ static int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part, } #endif - part->x += part->step_xoffset; - part->y += part->step_yoffset; + if (c->position == POS_CE) + { + // calculate playfield position (with scrolling) for related CE tile + int fx = getFieldbufferOffsetX_RND(ScreenMovDir, ScreenGfxPos); + int fy = getFieldbufferOffsetY_RND(ScreenMovDir, ScreenGfxPos); + int sx = FX + SCREENX(part->tile_x) * TILEX_VAR; + int sy = FY + SCREENY(part->tile_y) * TILEY_VAR; + int x = sx - fx; + int y = sy - fy; + + part->tile_xoffset += part->step_xoffset; + part->tile_yoffset += part->step_yoffset; + + part->x = x + part->tile_xoffset; + part->y = y + part->tile_yoffset; + } + else + { + part->x += part->step_xoffset; + part->y += part->step_yoffset; + } anim->last_x = part->x; anim->last_y = part->y; @@ -2140,10 +2197,12 @@ int getGlobalAnimSyncFrame(void) return anim_sync_frame; } -void HandleGlobalAnimEventByElementChange(int element) +void HandleGlobalAnimEventByElementChange(int element, int page, int x, int y) { if (!IS_CUSTOM_ELEMENT(element)) return; - InitGlobalAnim_Triggered_ByCustomElement(element - EL_CUSTOM_START); + // custom element stored as 0 to 255, change page stored as 1 to 32 + InitGlobalAnim_Triggered_ByCustomElement(element - EL_CUSTOM_START, page + 1, + x, y); }