+ ei->change_events |= CH_EVENT_BIT(CE_DELAY);
+ }
+
+#if 1
+ /* add change events from custom element configuration */
+ for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+ {
+ struct ElementInfo *ei = &element_info[EL_CUSTOM_START + i];
+
+ for (j=0; j < ei->num_change_pages; j++)
+ {
+ if (!ei->change_page[j].can_change)
+ continue;
+
+ for (k=0; k < NUM_CHANGE_EVENTS; k++)
+ {
+ /* only add event page for the first page found with this event */
+ if (ei->change_page[j].events & CH_EVENT_BIT(k) &&
+ !(ei->change_events & CH_EVENT_BIT(k)))
+ {
+ ei->change_events |= CH_EVENT_BIT(k);
+ ei->event_page_nr[k] = j;
+ ei->event_page[k] = &ei->change_page[j];
+ }
+ }
+ }
+ }
+
+#else
+
+ /* add change events from custom element configuration */
+ for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+ {
+ int element = EL_CUSTOM_START + i;
+
+ /* only add custom elements that change after fixed/random frame delay */
+ if (CAN_CHANGE(element) && HAS_CHANGE_EVENT(element, CE_DELAY))
+ element_info[element].change_events |= CH_EVENT_BIT(CE_DELAY);
+ }
+#endif
+
+ /* ---------- initialize trigger events ---------------------------------- */
+
+ /* initialize trigger events information */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ trigger_events[i] = EP_BITMASK_DEFAULT;
+
+#if 1
+ /* add trigger events from element change event properties */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ {
+ struct ElementInfo *ei = &element_info[i];
+
+ for (j=0; j < ei->num_change_pages; j++)
+ {
+ if (!ei->change_page->can_change)
+ continue;
+
+ if (ei->change_page[j].events & CH_EVENT_BIT(CE_BY_OTHER_ACTION))
+ {
+ int trigger_element = ei->change_page[j].trigger_element;
+
+ trigger_events[trigger_element] |= ei->change_page[j].events;
+ }
+ }
+ }
+#else
+ /* add trigger events from element change event properties */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ if (HAS_CHANGE_EVENT(i, CE_BY_OTHER_ACTION))
+ trigger_events[element_info[i].change->trigger_element] |=
+ element_info[i].change->events;
+#endif
+
+ /* ---------- initialize push delay -------------------------------------- */
+
+ /* initialize push delay values to default */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ {
+ if (!IS_CUSTOM_ELEMENT(i))
+ {
+ element_info[i].push_delay_fixed = 2;
+ element_info[i].push_delay_random = 8;
+ }
+ }
+
+ /* set push delay value for certain elements from pre-defined list */
+ for (i=0; push_delay_list[i].element != EL_UNDEFINED; i++)
+ {
+ int e = push_delay_list[i].element;
+
+ element_info[e].push_delay_fixed = push_delay_list[i].push_delay_fixed;
+ element_info[e].push_delay_random = push_delay_list[i].push_delay_random;
+ }
+
+ /* ---------- initialize move stepsize ----------------------------------- */
+
+ /* initialize move stepsize values to default */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ if (!IS_CUSTOM_ELEMENT(i))
+ element_info[i].move_stepsize = MOVE_STEPSIZE_NORMAL;
+
+ /* set move stepsize value for certain elements from pre-defined list */
+ for (i=0; move_stepsize_list[i].element != EL_UNDEFINED; i++)
+ {
+ int e = move_stepsize_list[i].element;
+
+ element_info[e].move_stepsize = move_stepsize_list[i].move_stepsize;
+ }
+
+ /* ---------- initialize gem count --------------------------------------- */
+
+ /* initialize gem count values for each element */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ if (!IS_CUSTOM_ELEMENT(i))
+ element_info[i].collect_count = 0;
+
+ /* add gem count values for all elements from pre-defined list */
+ for (i=0; collect_count_list[i].element != EL_UNDEFINED; i++)
+ element_info[collect_count_list[i].element].collect_count =
+ collect_count_list[i].count;
+}
+
+
+/*
+ =============================================================================
+ InitGame()
+ -----------------------------------------------------------------------------
+ initialize and start new game
+ =============================================================================
+*/
+
+void InitGame()
+{
+ boolean emulate_bd = TRUE; /* unless non-BOULDERDASH elements found */
+ boolean emulate_sb = TRUE; /* unless non-SOKOBAN elements found */
+ boolean emulate_sp = TRUE; /* unless non-SUPAPLEX elements found */
+ int i, j, x, y;
+
+ InitGameEngine();
+
+#if 0
+#if DEBUG
+#if USE_NEW_AMOEBA_CODE
+ printf("Using new amoeba code.\n");
+#else
+ printf("Using old amoeba code.\n");
+#endif
+#endif
+#endif
+
+ /* don't play tapes over network */
+ network_playing = (options.network && !tape.playing);
+
+ for (i=0; i<MAX_PLAYERS; i++)
+ {
+ struct PlayerInfo *player = &stored_player[i];
+
+ player->index_nr = i;
+ player->element_nr = EL_PLAYER_1 + i;
+
+ player->present = FALSE;
+ player->active = FALSE;
+
+ player->action = 0;
+ player->effective_action = 0;
+ player->programmed_action = 0;
+
+ player->score = 0;
+ player->gems_still_needed = level.gems_needed;
+ player->sokobanfields_still_needed = 0;
+ player->lights_still_needed = 0;
+ player->friends_still_needed = 0;
+
+ for (j=0; j<4; j++)
+ player->key[j] = FALSE;
+
+ player->dynabomb_count = 0;
+ player->dynabomb_size = 1;
+ player->dynabombs_left = 0;
+ player->dynabomb_xl = FALSE;
+
+ player->MovDir = MV_NO_MOVING;
+ player->MovPos = 0;
+ player->Pushing = FALSE;
+ player->Switching = FALSE;
+ player->GfxPos = 0;
+ player->GfxDir = MV_NO_MOVING;
+ player->GfxAction = ACTION_DEFAULT;
+ player->Frame = 0;
+ player->StepFrame = 0;
+
+ player->use_murphy_graphic = FALSE;
+ player->use_disk_red_graphic = FALSE;
+
+ player->actual_frame_counter = 0;
+
+ player->last_move_dir = MV_NO_MOVING;
+
+ player->is_moving = FALSE;
+ player->is_waiting = FALSE;
+ player->is_digging = FALSE;
+ player->is_collecting = FALSE;
+
+ player->show_envelope = 0;
+
+ player->move_delay = game.initial_move_delay;
+ player->move_delay_value = game.initial_move_delay_value;
+
+ player->push_delay = 0;
+ player->push_delay_value = 5;
+
+ player->snapped = FALSE;
+
+ player->last_jx = player->last_jy = 0;
+ player->jx = player->jy = 0;
+
+ player->shield_normal_time_left = 0;
+ player->shield_deadly_time_left = 0;
+
+ player->inventory_size = 0;
+
+ DigField(player, 0, 0, 0, 0, DF_NO_PUSH);
+ SnapField(player, 0, 0);
+
+ player->LevelSolved = FALSE;
+ player->GameOver = FALSE;
+ }
+
+ network_player_action_received = FALSE;
+
+#if defined(PLATFORM_UNIX)
+ /* initial null action */
+ if (network_playing)
+ SendToServer_MovePlayer(MV_NO_MOVING);
+#endif
+
+ ZX = ZY = -1;
+
+ FrameCounter = 0;
+ TimeFrames = 0;
+ TimePlayed = 0;
+ TimeLeft = level.time;
+
+ ScreenMovDir = MV_NO_MOVING;
+ ScreenMovPos = 0;
+ ScreenGfxPos = 0;