#include "maps\export.lgc"
#include "maps\table.lgc"
#include "maps\common_options.lgc"

#ifndef COMMON_FAME_H
	#include "maps\common_fame.lgc"
#endif

#ifndef COMMON_DEFS_H
    #include "maps\common_defs.lgc"
#endif


#define FLAME_SHIFT_X 0 // смещение сильного пламени дюз
#define FLAME_SHIFT_Y 0 // смещение сильного пламени дюз

int NoBall           = 0;
int PlayerVehi       = 0; // спрайт тележки игрока
int BallInVehi       = 0; // 1 если шарик прилип на тележку
int VehiIsSticky     = 0; // 1 если шарик прилипает к тележке
int VehiHaveMissile  = 0; // 1 если есть ракеты
int VehiHaveGun      = 0; // 1 если есть пулемет
//int ShiftBallInVehi  = 0; // сдвиг шарика относительно центра тележки когда он прилип к ней
int BallSpeed        = 0; // скорость движения шарика
int StartLevelTime2   = 0; // время начала подуровня
//int ExitDoor         = 0; // ссылка на выходныю калитку на данном уровне
//int ExitDoorY        = 0; // координата Y выходной калитки на данном уровне
int StartWind        = 0;
int CreateBallTime   = 0; // время когда родился шарик на тележке
int LastFireTime     = 0; // время последнего выстрела
int GameStartWinEffectTime = 0;// 1 если начался собственно переход на след уровень, иначе ждем пока упадут все бонусы
int VehiDeathTime    = 0; // время уничтожения ракетки
bool giStatWasShownTime = 0;
int NoOtskok         = 0;// количество отскоков шарика перед увеличением скорости


int DbgTextCurLevel  = 0;

int GameState        = 0; // см #define GAMESTATE_
int StartChangeState = 0;
string MapNameForState;   // имя men файла для нового состояния игры
//zmNEW
int giBossDeathTime  = 0; //время умирания босса, пока не пройдет определенное время карту не перегружать


#define GAMESTATE_NORMAL     0
#define GAMESTATE_WIN        1
#define GAMESTATE_HELP       2
#define GAMESTATE_OPTIONS    3
#define GAMESTATE_CHANGE     4 // в процессе смены состояния
#define GAMESTATE_MAINMENU   5 // выход в главное меню
#define GAMESTATE_WIN_BONUS  6 // победа при помощи бонуса
#define GAMESTATE_NEXT_LEVEL 7
#define GAMESTATE_QUIT_YESNO 8 // вопрос уточнение о выходе из игры
#define GAMESTATE_DEATH      9 // игрок проиграл

//
DestoyObjectsOnScreen(bool bForBoss);

HaveBonusInMap()
{
    int i;
    for ( i = 0; BonusObject[i]; i++)
        if ( GetVidData(BonusObject[i], VID_COUNT) )
            return 1;
    return 0;
}
ChangeState(int new_state, int effect)
{
    if ( effect != 0 )
        Effect(effect,0,0,FADE_GAME_TIME);
    StartChangeState = GetTime();
    GameState = new_state;
}
DeleteLink(int parent, int vid_link)
{
    int link;
    for ( link = Action(parent, ACT_GET_LINK); link; link = Action(link, ACT_GET_LINK) )
        if ( GetUnitVid(link) == vid_link )
        {
            Destroy(link);
            return;
        }
}
ChangeVehiAnimation(int ani)
{
	if(!PlayerVehi || IsDying(PlayerVehi))
		return;
	//
    int link;
    Action(PlayerVehi, ani);
    link = Action(PlayerVehi, ACT_GET_LINK);
    if ( (GetAnimation(link) != ANI_HIT || ani == ANI_HIT) && GetUnitVid(link) != 39 )
        Action(link, ani);
    for ( link = Action(link, ACT_GET_LINK); link; link = Action(link, ACT_GET_LINK) )
        if ( GetAnimation(link) != ani )
            Action(link, ani);
}

// превращение тележки в обычную, убирание с нее и с шариков всех бонусов
ResetVehiAndBall()
{
    if ( !Flagman(0) )
    {
        int x;         x         = GetInputX();
        int size_x;    size_x    = 0;//GetVidData(GetUnitVid(link), VID_SIZE_X)/2;// если нужно учитывать размер тележки при ограничении ее движения
        int left;      left      = SCREEN_FIELD_LEFT  - SCREEN_FIELD_VEHI_LIMIT + size_x;
        int right;     right     = SCREEN_FIELD_RIGHT + SCREEN_FIELD_VEHI_LIMIT - size_x;
        int scr_right; scr_right = (150 - MouseSensitivity) * (right - left) / 100;
        if ( x > scr_right )
        {
            x = scr_right;
        }
        x = left + ((right - left) * x) / scr_right;
/*        int x;      x      = GetInputX();
        int size_x; size_x = 0;//GetVidData(14, VID_SIZE_X)/2;
        if ( (x - size_x) < SCREEN_FIELD_LEFT - SCREEN_FIELD_VEHI_LIMIT  )
            x = SCREEN_FIELD_LEFT - SCREEN_FIELD_VEHI_LIMIT + size_x;
        if ( (x + size_x) > SCREEN_FIELD_RIGHT + SCREEN_FIELD_VEHI_LIMIT )
            x = SCREEN_FIELD_RIGHT + SCREEN_FIELD_VEHI_LIMIT - size_x;*/
        PlayerVehi = CreateSprite(10, x, FromScreenY(768 - FLAGMAN_Y + FLAGMAN_Z), FLAGMAN_Z, 64);
        CreateSprite(24, GetX(PlayerVehi), GetY(PlayerVehi), GetZ(PlayerVehi), 0, PlayerVehi);// создание пулемета
        CreateSprite(20, GetX(PlayerVehi), GetY(PlayerVehi), GetZ(PlayerVehi), 0, PlayerVehi);// создание ракетницы
        SetFlagman(0, PlayerVehi);
        giBornTime = GetTime();
    }
    VehiDeathTime = 0;
    VehiIsSticky = 0; DeleteLink(PlayerVehi, 33);// уничтожение прилипалки
//    DeleteLink(PlayerVehi, 20);// уничтожение ракетницы
    VehiHaveMissile = 0;
    DeleteLink(PlayerVehi, 21);// уничтожение ракеты 1
    DeleteLink(PlayerVehi, 22);// уничтожение ракеты 2
    DeleteLink(PlayerVehi, 23);// уничтожение ракеты 3
//    DeleteLink(PlayerVehi, 24);// уничтожение пулемета пустого
//    DeleteLink(PlayerVehi, 25);// уничтожение пулемета заряженного
    VehiHaveGun = 0;
    int link;
    for ( link = Action(PlayerVehi, ACT_GET_LINK); link; link = Action(link, ACT_GET_LINK) )
        if ( GetUnitVid(link) == 25 )
            Action(link, ACT_CHANGE_VID, 24);// превращение заряженного пулемета в пустой
//        else if ( GetUnitVid(link) == 13 )
//            Action(link, ACT_CHANGE_VID, 11);// превращение тени
        else if ( GetUnitVid(link) == 31 )
            Action(link, ACT_CHANGE_VID, 32);// превращение усиленного пламени из дюз в обычное
//    SetVidData(32, VID_LINK, 11);
    SetVidData(26, VID_LINK, 32);
//    DeleteLink(PlayerVehi, 31);// превращение усиленного пламени из дюз в обычное
    BallSpeed = NORMAL_BALL_SPEED;
    NoOtskok = 0;
    SetVidData(500, VID_SPEED, NORMAL_BALL_SPEED);
    SetVidData(501, VID_SPEED, NORMAL_BALL_SPEED);
    SetVidData(502, VID_SPEED, NORMAL_BALL_SPEED);
    SetVidData(503, VID_SPEED, NORMAL_BALL_SPEED);
    SetVidData(504, VID_SPEED, NORMAL_BALL_SPEED);
    Action(Action(PlayerVehi, ACT_GET_LINK), ACT_CHANGE_VID, 14);
    SetVidData(33, VID_SCALE_X, 1000);
    //
#ifdef GAMEPLAY_FLY		//zmNEW2006Oct02
    Action(Action(PlayerVehi, ACT_GET_LINK), ACT_CHANGE_VID, 39);
    Action(Action(PlayerVehi, ACT_GET_LINK), ANI_HIT);
//    CreateSprite(31, GetX(PlayerVehi) + FLAME_SHIFT_X, GetY(PlayerVehi) + FLAME_SHIFT_Y, GetZ(PlayerVehi), 0, PlayerVehi);
//    SetVidData(32, VID_LINK, 13);
    SetVidData(26, VID_LINK, 31);
    for ( link = Action(PlayerVehi, ACT_GET_LINK); link; link = Action(link, ACT_GET_LINK) )
        if ( GetUnitVid(link) == 32 )
            Action(link, ACT_CHANGE_VID, 31);// превращение обычное пламени из дюз в усиленного
//        if ( GetUnitVid(link) == 11 )
//            Action(link, ACT_CHANGE_VID, 13);// превращение тени
    ChangeVehiAnimation(ANI_STAND);
#endif
	bDeathByBoss = false;
}

#ifndef UTIL_BOSS_H
    #include "maps\util_boss.lgc"
#endif

#ifndef UTIL_HELPMENS_H
	#include "maps\util_helpmens.lgc"
#endif

#ifndef UTILHELP_H
    #include "maps\util_help.lgc"
#endif

#ifndef UTIL_BUTTONS_H
    #include "maps\util_buttons.lgc"
#endif

#ifndef COMMON_BONUS_H
#include "maps\common_bonus.lgc"
#endif

#ifndef COMMON_BALL_H
	#include "maps\common_ball.lgc"
#endif

#include "maps\common_fly.lgc"

#ifndef UTIL_BONUSTABLE_H
	#include "maps\util_bonustable.lgc"
#endif

#include "maps\common_objects.lgc"

#ifndef UTIL_CRYSTALS_H
    #include "maps\util_crystals.lgc"
#endif

#ifndef COMMON_MAP_H
	#include "maps\common_map.lgc"
#endif

#ifndef COMMON_GAMEBAR_H
    #include "maps\common_gamebar.lgc"
#endif


//------------------------------------------------------------------------------------------
SetCursorToVehiPosition()
{
    int x;         x         = GetX(PlayerVehi);
    int size_x;    size_x    = 0;//GetVidData(GetUnitVid(Action(PlayerVehi, ACT_GET_LINK)), VID_SIZE_X)/2;
    int left;      left      = SCREEN_FIELD_LEFT  - SCREEN_FIELD_VEHI_LIMIT + size_x;
    int right;     right     = SCREEN_FIELD_RIGHT + SCREEN_FIELD_VEHI_LIMIT - size_x;
    int scr_right; scr_right = (150 - MouseSensitivity) * (right - left) / 100;
//    iInputX = x = left + ((right - left) * x) / scr_right;
    int iInputX = ((x - left) * scr_right) / (right - left);
    if ( iInputX > scr_right )
        iInputX = scr_right;
    SetCursorPosition(ToScreenX(iInputX), ToScreenY(GetY(PlayerVehi)));
}

InitForStartLevel()
{
//    ExitDoor = FindNearestSprite(GETSPRITE_VID + 401, 512, GetY(PlayerVehi) - 750, 300);
//    ExitDoorY = GetY(ExitDoor);
    StartLevelTime2 = GetTime();
    StartBallLevelTime = 0;
    LastFireTime = 0;
    StartWind = 0;
    GameStartWinEffectTime = 0;
    giStatWasShownTime = 0;
//    BallInVehi = 1;
    CreateBallTime = GetTime() + 1;
    VehiDeathTime = 0;
    ResetVehiAndBall();
    GameState = GAMESTATE_NORMAL;
    SetCursorToVehiPosition();
    giScoresLev = 0;
	giCrystOnLev = GetCrystalOnScreenCnt();
	giCrystSubLevScore = 0;
	giBigCrystHit = 0;
	giBonusSubLevScore = 0;
	giBonusSubLevTotal = 0;
	giWinTime = 0;

	if(!Z_DEBUG)
		ShowCurHelp();
}

InitGame()
{
	//zmNEW2006Oct26. чтобы при загрузке уровня через F3 его номер прописывался
#ifndef GAMEPLAY_FLY
    LevelNumber = CUR_LEVEL_NUM;
#endif
#ifdef GAMEPLAY_FLY
    LevelNumber = CUR_LEVEL_NUM+1;
    bPlayVehiMove = true;
    SetValI("WasFlyLevel", 1);
#endif
	SetMaxLevelTry(LevelNumber);
	//
	if(GetValI("GoldCoins", 0))
		gbGoldCoins = true;
	//
	if(!Z_DEBUG2)
	    SetCursor(CURSOR_OFF);
    SetScrollType(0);
    // выставляем границы уровней
#ifndef GAMEPLAY_FLY		//zmNEW2006Oct02
    int x, y;
    for ( y = 0; y < MapSizeY(); y += 8 )
    {
        CreateSprite(400, 0, y, 0);
        CreateSprite(400, SCREEN_FIELD_RIGHT + 7, y, 0);
    }
    for ( y = 0; y < MapSizeY(); y += 768 )
    {
        for ( x = 0; x < 800; x += 8 )
            CreateSprite(400, x, y, 0);
    }
    SetPosition(ScreenX()/2, y - 768 * 2 + ScreenY()/2);
#endif
#ifdef GAMEPLAY_FLY		//zmNEW2006Oct02
    SetPosition(ScreenX()/2, MapSizeY() - ScreenY()/2);
#endif
	//
/*    PlayerVehi = CreateSprite(10, ScreenX()/2, FromScreenY(768 - FLAGMAN_Y + FLAGMAN_Z), FLAGMAN_Z, 64);
    giBornTime = GetTime();
    CreateSprite(24, GetX(PlayerVehi), GetY(PlayerVehi), GetZ(PlayerVehi), 0, PlayerVehi);// создание пулемета
    CreateSprite(20, GetX(PlayerVehi), GetY(PlayerVehi), GetZ(PlayerVehi), 0, PlayerVehi);// создание ракетницы
    SetFlagman(0, PlayerVehi);*/
    //
    MouseSensitivity = GetValI("MouseSensitivity",50);
    NoBall = 0;
    //NoPlayerLife = 3;
    //gScoreTot = 0;
    giScoresLev = 0;
    MenuLoad("maps\\gamemenu.men");
    MenuGameTime = MenuFind(3, 164);
    MenuBallSpeed = MenuFind(3, 165);
    MenuBallSpeedBar = MenuFind(473, 10);
    MenuNoPlayerLife = MenuFind(3, 166);
    MenuNoPlayerLifeBar = MenuFind(474);
    MenuCrystals = MenuFind(3, 167);
    MenuScores = MenuFind(3, 168);
    MenuScoresTotal = MenuFind(4, 169);
    MenuCrystalsBar = MenuFind(480);
    int spr = MenuFind(761);
    MenuCrystalsAddLifeX = ToScreenX(GetX(spr));
    MenuCrystalsAddLifeY = ToScreenY(GetY(spr), GetZ(spr));
    MenuCrystalsAddLifeZ = GetZ(spr);
    Destroy(spr);
    //
	LoadCurData();
	//
    //if ( LevelNumber == 1 )
    //    MenuHelpText = CreateText(3, ScreenX()/2, ScreenY()/2+200, 0, GetString("menu", "Help"), BEH_CENTER);
	//if(!Z_DEBUG)
	    PlayMusicFile(MUSIC);
    StartGameTime = GetTime();
    InitForStartLevel();
    InitStatistics();
    //
    InitBoss();
    giSubLevelNum = 0;
    //
	InitPhysics();
	//
    GameBarTact();
    if(!gbHelpMenuShown)
		HideObjectsForMenu(0);
	//
//    SetCursorToVehiPosition();
}

ChangePlayerVehiPosition()
{
	if(!PlayerVehi || IsDying(PlayerVehi) || gbVehiFlying || giStatShown)
		return;

#ifdef GAMEPLAY_FLY		//zmNEW2006Oct02
	ChangePlayerVehiPosition2();
	return;
#endif
	//
    static int last_change_animation = -1000;
    static int last_stop_move = -1000;
    int link;
    link = Action(PlayerVehi, ACT_GET_LINK);
	//
	int iInputX = GetInputX();
    int x;         x         = iInputX;
    int size_x;    size_x    = 0;//GetVidData(GetUnitVid(link), VID_SIZE_X)/2;// если нужно учитывать размер тележки при ограничении ее движения
    int left;      left      = SCREEN_FIELD_LEFT  - SCREEN_FIELD_VEHI_LIMIT + size_x;
    int right;     right     = SCREEN_FIELD_RIGHT + SCREEN_FIELD_VEHI_LIMIT - size_x;
    int scr_right; scr_right = (150 - MouseSensitivity) * (right - left) / 100;
    if ( x > scr_right )
    {
        x = scr_right;
        if(!Z_DEBUG)
	        SetCursorPosition(scr_right, ToScreenY(GetInputY()));
    }
    iInputX = x = left + ((right - left) * x) / scr_right;
	if(giUnFreezeTime)
		iInputX = GetX(PlayerVehi);
//string log; log = "";
    if ( iInputX < GetX(PlayerVehi) )
    {
//log = itoa(last_change_animation)+"leftbeg "+itoa(GetAnimation(PlayerVehi)) + "->"+itoa(GetAnimation(link)) + "->"+itoa(GetAnimation(Action(link, ACT_GET_LINK)));        
        last_stop_move = -1000;
        Action(PlayerVehi, ACT_CHANGE_DIRECTION, 64);
        Action(link, ACT_CHANGE_DIRECTION, 64);
        if ( last_change_animation >= 0 && GetAnimation(PlayerVehi) != ANI_START_MOVE )
            ChangeVehiAnimation(ANI_GO);
        else
            ChangeVehiAnimation(ANI_START_MOVE);
        last_change_animation = GetTime();
//log = log + "leftend "+itoa(GetAnimation(PlayerVehi)) + "->"+itoa(GetAnimation(link)) + "->"+itoa(GetAnimation(Action(link, ACT_GET_LINK)));        
    }
    else if ( iInputX > GetX(PlayerVehi) )
    {
//log = "rightbeg "+itoa(GetAnimation(PlayerVehi)) + "->"+itoa(GetAnimation(link)) + "->"+itoa(GetAnimation(Action(link, ACT_GET_LINK)));        
        last_stop_move = -1000;
        Action(PlayerVehi, ACT_CHANGE_DIRECTION, 192);
        Action(link, ACT_CHANGE_DIRECTION, 192);
        if ( last_change_animation >= 0 && GetAnimation(PlayerVehi) != ANI_START_MOVE )
            ChangeVehiAnimation(ANI_GO);
        else
            ChangeVehiAnimation(ANI_START_MOVE);
        last_change_animation = GetTime();
//log =log +  "rightend "+itoa(GetAnimation(PlayerVehi)) + "->"+itoa(GetAnimation(link)) + "->"+itoa(GetAnimation(Action(link, ACT_GET_LINK)));        
    }
    else if ( (GetTime() - last_change_animation) > 70 )
    {
//log ="timebeg "+itoa(GetAnimation(PlayerVehi)) + "->"+itoa(GetAnimation(link)) + "->"+itoa(GetAnimation(Action(link, ACT_GET_LINK)));        
        last_change_animation = -1000;
//        Action(PlayerVehi, ACT_CHANGE_DIRECTION, 0);
        if ( last_stop_move >= 0 && GetAnimation(PlayerVehi) != ANI_STOP_MOVE )
            ChangeVehiAnimation(ANI_STAND);
        else
            ChangeVehiAnimation(ANI_STOP_MOVE);//STAND);
/*        if ( GetAnimation(link) != ANI_HIT )
            if ( last_stop_move >= 0 && GetAnimation(PlayerVehi) != ANI_STOP_MOVE )
//            if ( last_stop_move >= 0 && GetAnimation(link) != ANI_STOP_MOVE )
                Action(link, ANI_STAND);
            else
                {Action(link, ANI_STOP_MOVE);AddCommand(link, ANI_STAND);}*/
        last_stop_move = GetTime();
//log =log +  "timeend "+itoa(GetAnimation(PlayerVehi)) + "->"+itoa(GetAnimation(link)) + "->"+itoa(GetAnimation(Action(link, ACT_GET_LINK)));        
    }
    else
    {
//log = "ostbeg "+itoa(GetAnimation(PlayerVehi)) + "->"+itoa(GetAnimation(link)) + "->"+itoa(GetAnimation(Action(link, ACT_GET_LINK)));        
        if ( GetAnimation(PlayerVehi) == ANI_STAND )
            ChangeVehiAnimation(ANI_GO);
        if ( GetAnimation(link) == ANI_STAND )
            Action(link, ANI_GO);
//log =log +  "ostend "+itoa(GetAnimation(PlayerVehi)) + "->"+itoa(GetAnimation(link)) + "->"+itoa(GetAnimation(Action(link, ACT_GET_LINK)));        
    }

    if(!giUnFreezeTime)
	    Action(PlayerVehi, ACT_CHANGE_COOR, x, FromScreenY(768 - FLAGMAN_Y)/*GetY(PlayerVehi)*/, GetZ(PlayerVehi));
	else
        SetCursorToVehiPosition();

    static int old_x = 0, old_time_x = 0, speed = 0, period = 50;
/*    if ( (GetTime() - old_time_x) > 50 )
    {
        speed = GetX(PlayerVehi) - old_x;
        old_time_x = GetTime();
        old_x = GetX(PlayerVehi);
    }*/
    if ( (GetTime() - old_time_x) > period )
    {
/*        int shift_x;
        if ( GetX(link) > old_x ) speed++;
        else if ( GetX(link) < old_x ) speed--;
        else if ( speed > 0 ) { speed-=2; if ( speed < 0 ) speed = 0; }
        else if ( speed < 0 ) { speed+=2; if ( speed > 0 ) speed = 0; }
        if ( speed > 5  ) speed = 5;
        if ( speed < -5 ) speed = -5;
        shift_x += speed;
        if ( shift_x > 10  ) shift_x = 10;
        if ( shift_x < -10 ) shift_x = -10;
        Action(link, ACT_CHANGE_COOR, GetX(PlayerVehi) - shift_x, GetY(link), GetZ(link));
        old_time_x = GetTime();
        old_x = GetX(link);*/
/*        if ( GetX(PlayerVehi) > old_x ) speed++;
        else if ( GetX(PlayerVehi) < old_x ) speed--;
        else if ( speed > 0 ) { speed-=1; if ( speed < 0 ) speed = 0; }
        else if ( speed < 0 ) { speed+=1; if ( speed > 0 ) speed = 0; }
        if ( speed > 10  ) speed = 10;
        if ( speed < -10 ) speed = -10;
        period = 120 - Abs(speed) * 10;// 20 - 120
        Action(link, ACT_CHANGE_COOR, GetX(PlayerVehi) - speed, GetY(link), GetZ(link));
        old_time_x = GetTime();
        old_x = GetX(PlayerVehi);*/
    }
}


//------------------------------------------------------------------------------
PlayVehiFlySound()
{
	if(bPlayVehiMove && !bGameIsPaused)
		PlaySFX(FLYING_VEHI_SFX);
	else
	{
		//*StopSFX для за-loop-ленных звуков бессмысленнен. к сожалению
		//StopSFX(FLYING_VEHI_SFX);
	}
}


//------------------------------------------------------------------------------
GameTact()
{
#ifndef GAMEPLAY_FLY
	static int giTimesToBlink = 0;
    iff(GetValI("WasFlyLevel", 0) != 0)
    {
    	SetValI("WasFlyLevel", 0);
    	giTimesToBlink = 5;
    }
    if(!bGameIsPaused && giTimesToBlink > 0 && !MenuFind(767))
    {
	    CreateSprite(767, 179, 50, 0);
	    giTimesToBlink--;
	}
#endif

//if ( GetKey() == 9 ) {Destroy(PlayerVehi);PlayerVehi = 0; }
    int i, j;
    string str;
//Log(itoa(GetTime()) + " "+itoa(GetAnimation(Action(PlayerVehi, ACT_GET_LINK))));
    if(giOldScores != gScoreTot/10)
    {
        /*if ( gScoreTot/10 / SCORES_FOR_LIFE != giOldScores / SCORES_FOR_LIFE )
        {// добавляем жизнь за SCORES_FOR_LIFE очков
        	if(NoPlayerLife < MAX_LIVES_CNT)
            	NoPlayerLife++;
            ShowGameBarLives();
        }*/
        if(GameState != GAMESTATE_WIN)	//чтбы не добавлять очки за статистику	
	        giScoresLev += (gScoreTot/10-giOldScores);
        giOldScores = gScoreTot/10;
        ShowGameBarScores();
    }
	//
	if(giWin95Time && !bWin95Total)
		CreateFallingGold();
	//
    if ( GameState == GAMESTATE_HELP )
    {
        if ( StartChangeState && (GetTime() - StartChangeState) > 100 )//&& GetEffectState(EFF_FADE) > 45 )
        {
            Pause2(1);
			Genocide(1250);
            StartChangeState = 0;
            MenuLoad(MapNameForState = "maps\\help.men");
        }
        if ( GetKey() || (GetInputState()&(INPUT_LCLICK|INPUT_RCLICK)) )
            ChangeState(GAMESTATE_NORMAL, 0);
        return 1;
    }
    else if ( GameState == GAMESTATE_OPTIONS )
    {
        if ( StartChangeState && (GetTime() - StartChangeState) > 100 )//&& (GetEffectState(EFF_FADE) > 45 || StartChangeState == 1) )
        {
            SetCursor(CURSOR_NORMAL);
            Pause2(1);
            Genocide(1250);
            StartChangeState = 0;
            HideObjectsForMenu(1);
            if(/*!Z_DEBUG && */MapNameForState == "" )
	            PlayMusicFile(MUSIC_MENU);
            if ( MapNameForState != "" ) MenuRelease(MapNameForState); MapNameForState = "";
            CreateOptionsMenu(MapNameForState = "maps\\options_game.men");
            return 1;
        }
        TactOptionsMenu();
        //
        if ( MenuLClick() && MenuNVidUnderCursor()==704 && GetDirection(MenuLClick()) == 32)
            ChangeState(GAMESTATE_QUIT_YESNO, 0);
		//
        if( !StartChangeState &&
        	 (GetKey() == VK_ESC || (MenuLClick() && MenuNVidUnderCursor()==704 && GetDirection(MenuLClick()) == 0))
        	 	|| (GetInputState()&INPUT_RCLICK) )
       	 {
            //HideObjectsForMenu(0);
            ChangeState(GAMESTATE_NORMAL, 0);
			//if(!Z_DEBUG)
				PlayMusicFile(MUSIC);
	        for ( i = FirstUnit(U_UNIT); i; i = NextUnit() )
	        {
    	        if ( GetVidData(GetUnitVid(i), VID_CLASS) == B_BALL )
    	        {
    	        	if(Action(i, ACT_GET_SPEED) != 0)
			            Action(i, ACT_SET_SPEED, 1);
				}
			}
			giFromPauseTime = -1;
		}
        return 1;
    }
    else if ( GameState == GAMESTATE_QUIT_YESNO )
    {
        if ( StartChangeState && (GetTime() - StartChangeState) > 100 )//&& GetEffectState(EFF_FADE) > 45 )
        {
            StartChangeState = 0;
            if ( MapNameForState != "" ) MenuRelease(MapNameForState); MapNameForState = "";
            MenuLoad(MapNameForState = "maps\\quit_game.men");
            return 1;
        }
//        if ( StartChangeState )
//            return 1;
        //
        if ( GetKey() == VK_RETURN || GetKey() == ' '
             || (MenuLClick() && MenuNVidUnderCursor()==704 && GetDirection(MenuLClick()) == 0) )
            ChangeState(GAMESTATE_MAINMENU, EFF_FADE);
        else if( GetKey() == VK_ESC
             || (MenuLClick() && MenuNVidUnderCursor()==704 && GetDirection(MenuLClick()) == 32) )
        {
            ChangeState(GAMESTATE_OPTIONS, 0);
        }
        return 1;
    }
    else if ( GameState == GAMESTATE_WIN )
    {// если игрок победил
        ChangePlayerVehiPosition();
        if( (HaveBonusInMap() && !Z_DEBUG
        	 || giBossDeathTime && GetTime()-giBossDeathTime < PAUSE_AFTER_BOSS_DEATH)
        	 && !bWin95Total
			)
        {
            return 1;
		}
		//показ статистики через некоторое время
		static bool bWasShown = false;
		static bool bWasShownTipEnd = false;
		if(!giStatShown && !giStatWasShownTime)
		{
        	giStatWasShownTime = giWinTime+2500;
        	//if(Z_DEBUG)
        	//	giStatWasShownTime = giWinTime+500;
			//
        	if(giStatWasShownTime < GetTime()+300)
        		giStatWasShownTime = GetTime()+300;
        	bWasShown = false;
		}
		if(!giStatShown && giStatWasShownTime && (giStatWasShownTime < GetTime())
				&& (!bWasShown || giWin95Time && !bWasShownTipEnd))
		{
            ResetVehiAndBall();// wit
			if(!giWin95Time)
				ShowStatistics(STAT_TYPE_NORM);
			else
			{
				HideWinObjects();
				if(!bWasShown)
				{
					//*zm07Feb12
					ShowStatistics(STAT_TYPE_NORM);
					//ShowStatistics(STAT_TYPE_END);
				}
				else
				{
					ShowStatistics(STAT_TYPE_TIP_END);
					bWasShownTipEnd = true;
				}
			}
			bWasShown = true;
		}
		if(giStatShown)
		{
			ProcessStatistics();
			CheatsTact();
			return 1;
		}
		if(!bWasShown || giWin95Time && !bWasShownTipEnd)
			return 1;

		//------------------------------------------------
		//если 5-ый подуровень, то улетаем тележкой
		if(giSubLevelNum == 4)
		{
			bPlayVehiMove = true;
			if(FlyVehiTact())
			{
				PlayVehiFlySound();
				return 1;
			}
		}
		//
		int ttt = 4000;
		if(bCheatWin)
			ttt = 1500;
		//if(ST_DEBUG)
		//	ttt = 1500;
		static int siGoalY = -1;
		//
        if( !GameStartWinEffectTime )
        {
            GameStartWinEffectTime = GetTime();
            ResetVehiAndBall();
            if(bWin95Total)
            	ChangeState(GAMESTATE_NEXT_LEVEL, 0);
			else
            if ( !PlayerVehi || GetY(PlayerVehi) < 768)
                ChangeState(GAMESTATE_NEXT_LEVEL, EFF_FADE);
            else
            {
            	siGoalY = -768/2 - ToScreenY(0);
                Effect(EFF_SCROLL, 512, siGoalY, ttt);
                bPlayVehiMove = true;
			}
			if(!bWin95Total && PlayerVehi)
			{
	            Action(Action(PlayerVehi, ACT_GET_LINK), ACT_CHANGE_VID, 39);
    	        Action(Action(PlayerVehi, ACT_GET_LINK), ANI_HIT);
                SetVidData(26, VID_LINK, 31);
                for ( int link = Action(PlayerVehi, ACT_GET_LINK); link; link = Action(link, ACT_GET_LINK) )
                    if ( GetUnitVid(link) == 32 )
                        Action(link, ACT_CHANGE_VID, 31);// превращение обычного пламени из дюз в усиленное
//                    if ( GetUnitVid(link) == 11 )
//                        Action(link, ACT_CHANGE_VID, 13);// превращение тени
            	ChangeVehiAnimation(ANI_STAND);
			}
        }
		//
		//if(1)
		{
			if( GetKey()||(GetInputState() & INPUT_RCLICK)||(GetInputState() & INPUT_LCLICK) )
			{
				if(siGoalY != -1 && GetEffectState(EFF_SCROLL) != -1)
				{
					int ttt2 = ttt-(GetTime()-GameStartWinEffectTime);
					if(ttt2 > 700)
						ttt2 = 700;
					Effect(EFF_SCROLL, 512, siGoalY, ttt2);
					siGoalY = -1;
				}
			}
			//
	        if ( !PlayerVehi || GetY(PlayerVehi) < 100)
    	        ChangeState(GAMESTATE_NEXT_LEVEL, EFF_FADE);
	        if ( GameState == GAMESTATE_WIN && GetEffectState(EFF_SCROLL) == -1 )
    	    {
	            giSubLevelNum++;
	            InitForStartLevel();
    	        if(PlayerVehi)
        	    {
		            Action(Action(PlayerVehi, ACT_GET_LINK), ACT_CHANGE_VID, 39);
    		        Action(Action(PlayerVehi, ACT_GET_LINK), ANI_OPEN);
				}
				bPlayVehiMove = false;
    	    }
		}
		PlayVehiFlySound();
        return 1;
    }
    else if ( GameState == GAMESTATE_WIN_BONUS )
    {// если игрок победил подобрав бонус и взорвав им калитку
        if ( !PlayerVehi || GetY(PlayerVehi) < 100 )
            ChangeState(GAMESTATE_NEXT_LEVEL, EFF_FADE);
        if ( GetEffectState(EFF_SCROLL) == -1 )
            InitForStartLevel();
        ChangePlayerVehiPosition();
        return 1;
    }
    else if ( GameState == GAMESTATE_NEXT_LEVEL )
    {
        if ( bWin95Total && GetEffectState(EFF_FADE) > 45 || StartChangeState && GetEffectState(EFF_FADE) > 45 && !Z_DEBUG2)
        {
        	SaveCurData();
            SetMaxLevelTry(++LevelNumber);
            //Log("aaa - " + itoa(LevelNumber) + ". " + itoa(bHaveFlyLevel[LevelNumber-2]));
			if(DEMO_VERSION && LevelNumber > MAX_LEVEL_NUM)
			{
				SetGlobValI("SlideFromMainMenu",0);
				Load("maps\\slide.map");
			}
			else
            if(LevelNumber >= 10)
            {
            	AddCurRecord(); //временно
            	Load("maps\\mainmenu.map");
			}
			else
            if(LevelNumber >= 2 && bHaveFlyLevel[GetLevArrNum()])
            	Load("maps\\level_land_0" + itoa(LevelNumber-1) + ".map");
			else
	            Load("maps\\level_0" + itoa(LevelNumber) + ".map");
        }
        return 1;
    }
    else if ( GameState == GAMESTATE_MAINMENU )
    {
        if ( StartChangeState && GetEffectState(EFF_FADE) > 45 )
        {
        	//if(!Z_DEBUG)
	            PlayMusicFile(MUSIC_MENU);
            Load("maps\\mainmenu.map");
        }
        return 1;
    }
    else if ( GameState == GAMESTATE_DEATH )
	{
        if(StartChangeState)
        {
        	//if(!Z_DEBUG)
	            PlayMusicFile(MUSIC_MENU);
            MenuLoad("maps\\death.men");
            StartChangeState = 0;
            HideObjectsForMenu(1);
            SetCursor(CURSOR_NORMAL);
            //
            SetValI("WasGameOver", 1);
            Log("WasGameOver");
        }
        if( GetKey() == VK_RETURN || GetKey() == ' ' || GetKey() == VK_ESCAPE
             || (MenuLClick() && MenuNVidUnderCursor()==704 && GetDirection(MenuLClick()) == 0) )
		{
			ChangeState(GAMESTATE_MAINMENU, EFF_FADE);
		}
		return 1;
    }

    //
    if ( StartChangeState && (GetTime() - StartChangeState) > 100 && (GetEffectState(EFF_FADE) ==-1 || GetEffectState(EFF_FADE) > 45) )
    {
        StartChangeState = 0;
        if(MapNameForState != "")
        	MenuRelease(MapNameForState);
        MapNameForState = "";
        if(GameState == GAMESTATE_NORMAL)
			HideObjectsForMenu(0);
        Pause2(0);
        SetCursor(CURSOR_OFF);
    }
	//
    if ( GetKey() == VK_F1 )
		ShowCurHelp();
    else
    if(gbHelpMenuShown)
    {
    	if(HelpMenuTact())
    	{
    		giFromPauseTime = -1;
    		return 1;
    	}
    }
    else
    if ( (GetKey() == VK_ESC || (GetInputState()&INPUT_RCLICK)) && !StartChangeState && !giStatShown)
    {
        ChangeState(GAMESTATE_OPTIONS, 0);
        Pause2(1);
    }

#ifdef GAMEPLAY_FLY
	ChangeMapPosition(bGameIsPaused);
#endif
	ProcessStatistics();
#ifdef GAMEPLAY_FLY
	if(MapTact())
		ChangeState(GAMESTATE_MAINMENU, EFF_FADE);
	//
	PlayVehiFlySound();

#endif
	if(!bGameIsPaused)
	{
	    UtilsTact();
	    ChangePlayerVehiPosition();
	    BossTact();
	    CrystalsTact();
	    UnFreezeVehiIfNeed();
	    ButtonsTact();
	    Level_9_5_Tact();
	}

//Log(itoa(GetTime()) + " "+itoa(GetAnimation(Action(PlayerVehi, ACT_GET_LINK))));

    if ( !bGameIsPaused && OneTimeInSecond() )
    {
        iff ( MenuHelpText && (GetTime() - StartGameTime) > 10000 )
            Destroy(MenuHelpText);
#ifndef GAMEPLAY_FLY		//zmNEW2006Oct02
        int object;
        for ( object = FirstInBox(0, -ToScreenY(0), 1024, 768-ToScreenY(0)); object; object = NextInBox() )
        {
        	int vid = GetUnitVid(object);
            if(	GetVidData(GetUnitVid(object), VID_SPRITETYPE) == U_OBJECT
            		&& GetVidData(GetUnitVid(object), VID_CLASS) != B_TERRAIN
	                && ToScreenY(GetY(object),GetZ(object)) > 0 && ToScreenY(GetY(object),GetZ(object)) < ScreenY()
	                && vid != 1220 && vid != 1222
	                && vid != 1230
	                && vid != 963
	                && vid != 964
	                && vid != 970
	                && vid != 960
	                && vid != 961
	                && vid != 962
	                && vid != 1238
	                && vid != 1241
	                && vid != 1237
	                || vid == 441
	          )
			{
				//Log3(itoa(GetUnitVid(object)));
                break;
			}
		}
//        if ( !FindNearestSprite(GETSPRITE_HASH + GETSPRITE_OBJECT, 512, GetY(PlayerVehi) - 350, 670) )
        if( (!object || bCheatWin || giBossDeathTime) && !Z_DEBUG2
        		&& GetVidData(1221, VID_COUNT) <= 0		//вдруг кристаллы еще летят
        		&& (!gbGoldCoins || GetVidData(bWinGoldVids[0], VID_COUNT) <= 0)		//вдруг монетки еще летят
        		&& (LevelNumber != 9 || giSubLevelNum != 4)
        		|| bWin95Total		//на 9-5 только если bWin95Total
        	)
        {// все кирпичи разрушены игрок победил
            GameState = GAMESTATE_WIN;
            giWinTime = GetTime();
            //
            string bStr;
            bStr = "LevelNum = " + itoa(LevelNumber) + ". SubLevelNum = " + itoa(giSubLevelNum+1);
            if(StartBallLevelTime)
	            bStr = bStr + ". Time = " + itoa((GetTime()-StartBallLevelTime)/1000);
           	Log2(bStr);
            //Call_s(EXT_LogStr, bStr);
            //
/*            if ( GetY(PlayerVehi) < 768 )
                ChangeState(GAMESTATE_NEXT_LEVEL, EFF_FADE);
            else
                Effect(EFF_SCROLL, 512, -768/2 - ToScreenY(0), 8000);
            CreateSprite(31, GetX(PlayerVehi), GetY(PlayerVehi), GetZ(PlayerVehi), 0, PlayerVehi);
            ChangeVehiAnimation(ANI_STAND);*/
/*            for ( i = Action(PlayerVehi, ACT_GET_LINK); i; i = Action(i, ACT_GET_LINK) )
                if ( GetUnitVid(i) == 32 )
                    Action(i, ACT_CHANGE_VID, 31);// превращение обычного пламени из дюз в усиленное*/
			if(!bWin95Total)
			{
				DestroyBalls();
				giCrystSubLevScore2 = giCrystSubLevScore + giBigCrystHit;
				DeathOfCrystals();
			}
            return 1;
        }
#endif
    }
	
	//обрабатываем возможную смену скорости шариков
	if(giFromPauseTime == -1 && !bGameIsPaused)
		giFromPauseTime = GetTime(); //потому что если берешь в конце паузы, то GetTime() неправильный
	//
	int NewSpeed = 0;
    if(giFromPauseTime && !bGameIsPaused)
    {
    	//после паузы постепенно разгоняемся (сделано тут, т.к. из скриптов acceleration не сменить)
    	NewSpeed = (GetTime()-giFromPauseTime) * 100 / 1000;
    	if(NewSpeed >= BallSpeed)
    	{
    		NewSpeed = BallSpeed;
    		giFromPauseTime = 0;
		}
    }
    else
    if ( BallSpeed != GetVidData(500, VID_SPEED)  )
    {//если нужно поменять максимальную скорость шариков
        NewSpeed = BallSpeed;
    }
	if(NewSpeed)
    {
        ShowGameBarSpeed(NewSpeed);
        SetBallVidsSpeed(NewSpeed);
    }
    else
    	ShowGameBarSpeed(BallSpeed);
	//
	if(Call_v(EXT_GetDebugMode) && (GetKey() == VK_F5))
			gbShowDbg = !gbShowDbg;
    if ( !bGameIsPaused && OneTimeInQuarterSecond() )
    {
    	GameBarTact();
    }


#ifndef GAMEPLAY_FLY		//zmNEW2006Oct02
    if ( !bGameIsPaused && (NoBall <= 0 || !Flagman(0)) )
    {// если все шарики разбились или тележка игрока разбита
        if ( !Flagman(0) )
        {// уничтожаем все шарики если тележка разбита
            for ( i = FirstUnit(U_UNIT); i; i = NextUnit() )
            {
                if ( GetVidData(GetUnitVid(i), VID_CLASS) == B_BALL )
                {
                	//если убит боссом, то убиваем шарики, прилепленные к тележке
                	if(!bDeathByBoss || Action(i, ACT_HAVE_ITEM, -999999))
                	{
	                    Action(i, ANI_DEATH);
	                    BallInVehi--;
					}
				}
			}
        }
        //
        //если нет шариков либо если убиты не боссом
		if( !giWin95Time && (NoBall <= 0 || (!Flagman(0) && !bDeathByBoss))
             && (!VehiDeathTime || (GetTime() - VehiDeathTime) > 2000) )
		{
	        if ( NoPlayerLife <= 0 && !CreateBallTime && !Z_DEBUG2)
    	    {// если жизней больше не осталось и не начало уровня
    	    	AddCurRecord();
        	    ChangeState(GAMESTATE_DEATH, 0);
        	    //ChangeState(GAMESTATE_MAINMENU, EFF_FADE);
	        }
    	    else
        	{
	            if ( !CreateBallTime )
    	        {
        	        --NoPlayerLife;// если не начало уровня то уменьшить количество шариков
            	    CreateBallTime = GetTime();
	            }
	            ShowGameBarLives();
            	ResetVehiAndBall();
	            BallInVehi = 1;
    	        i = CreateSprite(500, GetX(PlayerVehi), GetY(PlayerVehi) - 150, GetZ(PlayerVehi), 128);
        	    Action(i, ACT_SET_INVISIBLE, 1);
            	Action(i, ACT_ADD_ITEM, Random(100) - 50);// выставим позицию шарика на тележке -100, 100
	            Action(i, ACT_ADD_ITEM, -999999);// признак что шарик прилеплен к ракетке
    	        Action( Action(i, ACT_GET_LINK), ACT_SET_LINK, CreateSprite(509, GetX(i), GetY(i), GetZ(i + 1)) );
			}
        }
    }
#endif

    if ( !bWin95Total && !bGameIsPaused && BallInVehi && PlayerVehi)
    {// пока шарик прилеплен к тележке
        for ( i = FirstUnit(U_UNIT); i; i = NextUnit() )
            if ( GetVidData(GetUnitVid(i), VID_CLASS) == B_BALL && Action(i, ACT_HAVE_ITEM, -999999) )
            {
                int shift_x, shift_y, shield, wall_x;
                shield  = Action(PlayerVehi, ACT_GET_LINK);
//                eff = Action(Action(i, ACT_GET_LINK), ACT_GET_LINK);
                shift_x = Action(i, ACT_GET_ITEM, 0) * GetVidData(GetUnitVid(shield), VID_SIZE_X) / 200;
                shift_y = -GetVidData(GetUnitVid(shield), VID_SIZE_Y)/2 - GetVidData(GetUnitVid(i), VID_SIZE_Y)/2 - 2 + Abs(Action(i, ACT_GET_ITEM, 0))/20;
                wall_x = 0;
                if ( LevelNumber > 7 || (LevelNumber == 7 && giSubLevelNum >= 3) )
                    wall_x = 35;
                if ( (GetX(shield) + shift_x + GetVidData(GetUnitVid(i), VID_SIZE_X) + wall_x) > SCREEN_FIELD_RIGHT )
                    shift_x = SCREEN_FIELD_RIGHT - (GetX(shield) + GetVidData(GetUnitVid(i), VID_SIZE_X) + wall_x);
                else if ( (GetX(shield) + shift_x - GetVidData(GetUnitVid(i), VID_SIZE_X) - wall_x) < SCREEN_FIELD_LEFT )
                    shift_x = SCREEN_FIELD_LEFT - (GetX(shield) - GetVidData(GetUnitVid(i), VID_SIZE_X) - wall_x);
/*                if ( GetAnimation(PlayerVehi) == ANI_GO )
                    if ( GetDirection(PlayerVehi) == 64 )
                        shift_y -= Action(i, ACT_GET_ITEM, 0)/20;
                    else
                        shift_y += Action(i, ACT_GET_ITEM, 0)/20;*/
                Action(i, ACT_CHANGE_COOR, GetX(shield) + shift_x, GetY(shield) + shift_y, GetZ(i));
                if ( CreateBallTime && (GetTime() - CreateBallTime) > 1500 )
                {
                    CreateBallTime = 0;
                    Action(i, ACT_SET_INVISIBLE, 0);
                }
                if ( !CreateBallTime && (GetKey() == ' ' || (GetInputState()&INPUT_LCLICK) 
                    || ((GetInputState()&INPUT_LDOWN) && !giFromPauseTime)) )
                {
                    BallInVehi--;
                    Log2("BallInVehi = " + itoa(BallInVehi));
//                    Action(i, ACT_DELETE_ITEM, -999999);
					Action(i, ACT_SET_INVISIBLE, 0);
                    Action(i, ACT_DELETE_ALL_ITEM);
                    //zmNEW061018
                    if(VehiIsSticky)
	                    Action(i, ACT_SET_SPEED, NORMAL_BALL_SPEED);
					else
                    	Action(i, ACT_SET_SPEED, 1);
					//
					if(!StartBallLevelTime)
						StartBallLevelTime = GetTime();
                }
            }
    }

    if ( !bGameIsPaused && PlayerVehi && (GetKey() == ' ' || (GetInputState()&INPUT_LDOWN)) )
    {
        if ( VehiHaveMissile && (GetTime() - LastFireTime) >= MISSILE_RELOAD_TIME )
        {
            static int prev_coor_x = 58;
            LastFireTime = GetTime();
            prev_coor_x = -prev_coor_x;
            i = CreateSprite(34, GetX(PlayerVehi) + prev_coor_x, GetY(PlayerVehi) - 10, GetZ(PlayerVehi) + 10, 0);
            Action(i, ACT_MOVE, GetX(PlayerVehi) + prev_coor_x, -ToScreenY(0), GetZ(PlayerVehi) + 10);
/*            int link;
            for ( link = Action(PlayerVehi, ACT_GET_LINK); link; link = Action(link, ACT_GET_LINK) )
                if ( GetUnitVid(link) == 20 )
                    Action(link, ANI_FIGHT);*/
        }
        else if ( VehiHaveGun && (GetTime() - LastFireTime) >= GUN_RELOAD_TIME )
        {
            LastFireTime = GetTime();
            i = CreateSprite(35, GetX(PlayerVehi) - 52, GetY(PlayerVehi) - 20, GetZ(PlayerVehi) + 10, 0);
            Action(i, ACT_MOVE, GetX(PlayerVehi) - 52, -ToScreenY(0), GetZ(PlayerVehi) + 10);
            i = CreateSprite(35, GetX(PlayerVehi) + 52, GetY(PlayerVehi) - 20, GetZ(PlayerVehi) + 10, 0);
            Action(i, ACT_MOVE, GetX(PlayerVehi) + 52, -ToScreenY(0), GetZ(PlayerVehi) + 10);
/*            int link;
            for ( link = Action(PlayerVehi, ACT_GET_LINK); link; link = Action(link, ACT_GET_LINK) )
                if ( GetUnitVid(link) == 25 )
                    Action(link, ANI_FIGHT);*/
        }
	}

/*    if ( !StartWind )ветер решено убрать
        if ( OneTimeInSecond() && !Random(WIND_SQUALL_FREQ) )
        {
            StartWind = GetTime();
            SetEnvironment(ENV_SQUALL);
            i = FirstInBox(0, -ToScreenY(0), 1024, -ToScreenY(0) + 768);//FindNearestSprite(GETSPRITE_HASH + GETSPRITE_OBJECT, 512, GetY(PlayerVehi) - 230, 630);
            while ( i )
            {
                for ( j = 0; ObjectForWind[j]; j++ )
                    if ( GetUnitVid(i) == ObjectForWind[j] )
                        Action(i, ANI_STOP_MOVE);
                i = NextInBox();//FindNearestSprite(GETSPRITE_HASH + GETSPRITE_OBJECT, 512, GetY(PlayerVehi) - 350, 630, i);
            }
        }else;
    else if ( (GetTime() - StartWind) > 4000 )
    {
        StartWind = 0;
        i = FirstInBox(0, -ToScreenY(0), 1024, -ToScreenY(0) + 768);//FindNearestSprite(GETSPRITE_HASH + GETSPRITE_OBJECT, 512, GetY(PlayerVehi) - 230, 630);
        while ( i )
        {
            for ( j = 0; ObjectForWind[j]; j++ )
                if ( GetUnitVid(i) == ObjectForWind[j] )
                    Action(i, ANI_STAND);
            i = NextInBox();//FindNearestSprite(GETSPRITE_HASH + GETSPRITE_OBJECT, 512, GetY(PlayerVehi) - 350, 630, i);
        }
    }*/

    //
	if( GetKey() == 'w'&& Call_v(EXT_GetDebugMode))
		gbCheatAllObjDeath = true;
	if(gbCheatAllObjDeath)
	{
		//вызываем каждый такт, пока не кончатся объекты
    	gbCheatAllObjDeath = DestoyObjectsOnScreen(false);

    	//zmNEW
    	gbCheatAllObjDeath = false;
	}
    //
    if(GetKey() == 'l' && Call_v(EXT_GetDebugMode) && !Z_DEBUG)
    {
    	AddLife(AL_NONE);
    }
    if ( GetKey() == '-' && (BallSpeed - 10) > MIN_BALL_SPEED && Call_v(EXT_GetDebugMode))
        BallSpeed -= 10;
    if ( GetKey() == '+' && (BallSpeed + 10) < MAX_BALL_SPEED && Call_v(EXT_GetDebugMode))
        BallSpeed += 10;
	CheatsTact();

//Log(itoa(GetTime()) + " "+itoa(GetAnimation(Action(PlayerVehi, ACT_GET_LINK))));
    return 0;
}


//------------------------------------------------------------------------------------------
//если bForBoss, то не убиваем, а просто DeathTimer-ы расставляем,
//также не убиваем кристаллы и объекты, у которых MaxHP > 20
DestoyObjectsOnScreen(bool bForBoss)
{
	int i;
	bool ret = false;
    //
    static int siUnitsDest[500];
    static int siUnitsDestCnt;
    siUnitsDestCnt = 0;
    if(PlayerVehi)
    {
        i = FirstInBox(0, -ToScreenY(0), 1024, 768-ToScreenY(0));
        while ( i )
        {
       		//Log3("vid = " + itoa(GetUnitVid(i)) + ". unit = " + itoa(i));
        	if( GetUnitVid(i) != 1220 && GetUnitVid(i) != 1221 && GetUnitVid(i) != 1222
				&& GetUnitVid(i) != 1230 && GetUnitVid(i) != 940 && GetUnitVid(i) != 941
				&& GetUnitVid(i) != 1238 && GetUnitVid(i) != 1237
				&& GetUnitVid(i) != 1241
				&& GetUnitVid(i) >= 100)	//шоб тележку не горохать
        	{
        		ret = true;
	            if(!IsDying(i) && siUnitsDestCnt < 500)
	            {
		            siUnitsDest[siUnitsDestCnt] = i;
		            siUnitsDestCnt++;
				}
			}
			//zmNEW2006Dec11. затычка: в ф-ии FindNearestSprite есть баг - бесконечно начинает возвращать
			//один и тот же элемент
			static int siPrevSpr = 0;
            //i = FindNearestSprite(GETSPRITE_HASH + GETSPRITE_OBJECT, 512, GetY(PlayerVehi) - 350, 640, i);
            i = NextInBox();
            if(siPrevSpr == i)
            	break;
            siPrevSpr = i;
        }
    }
    for(i = 0; i < siUnitsDestCnt; i++)
    {
    	if(!bForBoss)
	    	Action(siUnitsDest[i], ANI_DEATH);
		else
		{
			int hp = GetVidData(GetUnitVid(siUnitsDest[i]), VID_MAXHP);
			if(hp <= 20)
				Action(siUnitsDest[i], ACT_SET_DEATH_TIMER, Random(2000));
		}
	}
	//
	return ret;
}

