#define  COMMON_BONUS_H aaa
//----------------------------------------------------------------------------
//  @brief
//        бонусы
//        

//  @ingroup
    
//  2006 created by wit.
//  2006Oct24 *zm всю логику бонусов вынес в отдельные процедуры для удобства заведения читов
//                логику подбирания бонусов вынес из всех процедур в CommonBonusProc(..)
//  (C) 2006    Sigma-Team
//-----------------------------------------------------------------------------


#define DEATH_SHIFT_Y 20 // расстояние от нижней кромки экрана на котором умирает бонус (-10)


//------------------------------------------------------------------------------------------
ChangeBallTo(int ball, int new_ball_vid)
{
    int old_ball_vid, link;
    old_ball_vid = GetUnitVid(ball);
    for ( link = Action(ball, ACT_GET_LINK); link; link = Action(link, ACT_GET_LINK) )
        if ( GetUnitVid(link) > 520 )
        {
            Destroy(link);
            break;
        }

//    Action(ball, ACT_SET_INVISIBLE, 1);
    Action(ball, ACT_CHANGE_VID, new_ball_vid);

    if ( old_ball_vid == 500 && new_ball_vid == 501 )// превращение нормального шарика в уменьшенный
        CreateSprite(521, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else if ( old_ball_vid == 500 && new_ball_vid == 502 )//  превращение нормального шарика в разрушитель
        CreateSprite(522, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else if ( old_ball_vid == 500 && new_ball_vid == 503 )// 
        CreateSprite(523, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else if ( old_ball_vid == 500 && new_ball_vid == 504 )// превращение нормального шарика в взрывающий
        CreateSprite(524, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else if ( old_ball_vid == 501 && new_ball_vid == 500 )// превращение уменьшенного шарика в нормальный
        CreateSprite(525, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else if ( old_ball_vid == 501 && new_ball_vid == 502 )// 
        CreateSprite(526, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else if ( old_ball_vid == 501 && new_ball_vid == 503 )// 
        CreateSprite(527, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else if ( old_ball_vid == 501 && new_ball_vid == 504 )// 
        CreateSprite(528, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else if ( old_ball_vid == 502 && new_ball_vid == 500 )// 
        CreateSprite(529, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else if ( old_ball_vid == 502 && new_ball_vid == 501 )// 
        CreateSprite(530, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else if ( old_ball_vid == 502 && new_ball_vid == 503 )// 
        CreateSprite(531, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else if ( old_ball_vid == 502 && new_ball_vid == 504 )// 
        CreateSprite(532, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else if ( old_ball_vid == 503 && new_ball_vid == 500 )// 
        CreateSprite(533, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else if ( old_ball_vid == 503 && new_ball_vid == 501 )// 
        CreateSprite(534, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else if ( old_ball_vid == 503 && new_ball_vid == 502 )// 
        CreateSprite(535, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else if ( old_ball_vid == 503 && new_ball_vid == 504 )// 
        CreateSprite(536, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else if ( old_ball_vid == 504 && new_ball_vid == 500 )// 
        CreateSprite(537, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else if ( old_ball_vid == 504 && new_ball_vid == 501 )// 
        CreateSprite(538, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else if ( old_ball_vid == 504 && new_ball_vid == 502 )// 
        CreateSprite(539, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else if ( old_ball_vid == 504 && new_ball_vid == 503 )// 
        CreateSprite(540, GetX(ball), GetY(ball) + 5, GetZ(ball) + 5, 0, ball);
    else
        Action(ball, ACT_SET_INVISIBLE, 0);
}


//------------------------------------------------------------------------------------------
ChangeAllBallsTo(int iVid)
{
	int i;
	for ( i = FirstUnit(U_UNIT); i; i = NextUnit() )
	{
		if ( GetVidData(GetUnitVid(i), VID_CLASS) == B_BALL )
			ChangeBallTo(i, iVid);
	}
}


//------------------------------------------------------------------------------------------
//расширение тележки
BnsIncreaseVehi()
{
	if(!PlayerVehi)
		return;
    int shield; shield = Action(PlayerVehi, ACT_GET_LINK);
	if ( GetUnitVid(shield) == 17 )     //ширина -1
		Action(shield, ACT_CHANGE_VID, 14);
	else if ( GetUnitVid(shield) == 18 )//ширина -2
		Action(shield, ACT_CHANGE_VID, 17);
	else if ( GetUnitVid(shield) < 16 ) //ширина 0, 1
		Action(shield, ACT_CHANGE_VID, GetUnitVid(shield) + 1);
	SetVidData(33, VID_SCALE_X, GetVidData(GetUnitVid(shield), VID_SIZE_X) * 1000 / GetVidData(14, VID_SIZE_X));
}


//------------------------------------------------------------------------------------------
BnsDecrBallSpeed()
{
	BallSpeed -= BallSpeed * BONUS_BALL_SPEED / 100;//STEP_BALL_SPEED;
	if ( BallSpeed < MIN_BALL_SPEED )
		BallSpeed = MIN_BALL_SPEED;
/*        int i;
        for ( i = FirstUnit(U_UNIT); i; i = NextUnit() )
            if ( GetVidData(GetUnitVid(i), VID_CLASS) == B_BALL )
            {
                int diff_speed, no_otskok, max_speed;
                no_otskok = Action(i, ACT_GET_ITEM, 0);
                max_speed = Action(i, ACT_GET_ITEM, 1);
                max_speed -= max_speed * BONUS_BALL_SPEED / 100;
                if ( max_speed < MIN_BALL_SPEED )
                    max_speed = MIN_BALL_SPEED;
                Action(i, ACT_SET_MAX_SPEED, max_speed);
                Action(i, ACT_DELETE_ALL_ITEM);
                Action(i, ACT_ADD_ITEM, no_otskok);
                Action(i, ACT_ADD_ITEM, max_speed);
            }*/
}


//------------------------------------------------------------------------------------------
BnsIncrBallSpeed()
{
	BallSpeed += BallSpeed * BONUS_BALL_SPEED / 100;//STEP_BALL_SPEED;
	if ( BallSpeed > MAX_BALL_SPEED )
		BallSpeed = MAX_BALL_SPEED;
/*        int i;
        for ( i = FirstUnit(U_UNIT); i; i = NextUnit() )
            if ( GetVidData(GetUnitVid(i), VID_CLASS) == B_BALL )
            {
                int diff_speed, no_otskok, max_speed;
                no_otskok = Action(i, ACT_GET_ITEM, 0);
                max_speed = Action(i, ACT_GET_ITEM, 1);
                max_speed += max_speed * BONUS_BALL_SPEED / 100;
                if ( max_speed > MAX_BALL_SPEED )
                    max_speed = MAX_BALL_SPEED;
                Action(i, ACT_SET_MAX_SPEED, max_speed);
                Action(i, ACT_DELETE_ALL_ITEM);
                Action(i, ACT_ADD_ITEM, no_otskok);
                Action(i, ACT_ADD_ITEM, max_speed);
            }*/
}


//------------------------------------------------------------------------------------------
BnsLevelWin()
{
	int cannon, i;
	GameState = GAMESTATE_WIN_BONUS;
	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 = FirstUnit(U_UNIT); i; i = NextUnit() )//уничтожение шариков
	if ( GetVidData(GetUnitVid(i), VID_CLASS) == B_BALL )
	{
//		Action( Action(i, ACT_GET_LINK), ACT_SET_LINK, CreateSprite(509, GetX(i), GetY(i), GetZ(i + 1)) );
		CreateSprite(509, GetX(i), GetY(i), GetZ(i + 1));
		Action(i, ACT_STOP, 1);// 1 чтобы остановился мнгновенно
		Action(i, ACT_SET_DEATH_TIMER, 1500);
	}
/*        int link;
        for ( link = Action(PlayerVehi, ACT_GET_LINK); link; link = Action(link, ACT_GET_LINK) )
            if ( GetUnitVid(link) == 32 )
                Action(link, ACT_CHANGE_VID, 31);// превращение обычного пламени из дюз в усиленное*/
//        cannon = CreateSprite(104, GetX(unit), GetY(unit), GetZ(unit), 0);
//        Action(cannon, ACT_MOVE, GetX(ExitDoor), GetY(ExitDoor) - 40, GetZ(ExitDoor));
}


//------------------------------------------------------------------------------------------
BnsDecreaseVehi()
{
	int shield; shield = Action(PlayerVehi, ACT_GET_LINK);
	if ( GetUnitVid(shield) == 17 )     //ширина -1
		Action(shield, ACT_CHANGE_VID, 18);
	else if ( GetUnitVid(shield) == 14 )//ширина 0
		Action(shield, ACT_CHANGE_VID, 17);
	else if ( GetUnitVid(shield) <= 16 )//ширина 1, 2
		Action(shield, ACT_CHANGE_VID, GetUnitVid(shield) - 1);
	SetVidData(33, VID_SCALE_X, GetVidData(GetUnitVid(shield), VID_SIZE_X) * 1000 / GetVidData(14, VID_SIZE_X));
}


//------------------------------------------------------------------------------------------
BnsAddLife()
{
	AddLife(AL_BONUS);
}


//------------------------------------------------------------------------------------------
BnsTrippleBalls()
{
	if(GameState == GAMESTATE_WIN)
		return;
	//
	int i, no_ball, list_ball[256], j, is_sticky, ii;
	no_ball = 0;
	for ( i = FirstUnit(U_UNIT); i; i = NextUnit() )
		if ( GetVidData(GetUnitVid(i), VID_CLASS) == B_BALL )
			if ( no_ball < 256 )
				list_ball[no_ball++] = i;
	//
	for ( i = 0; i < no_ball; i++ )
	{
		is_sticky = Action(list_ball[i], ACT_HAVE_ITEM, -999999);// 1 если шарик прилеплен к тележке
		//
		for(ii = 0; ii < 2; ii++)	//создаем 2 шарика
		{
			j = CreateSprite(GetUnitVid(list_ball[i]), GetX(list_ball[i]), GetY(list_ball[i]), GetZ(list_ball[i]), Random(255));
			if ( is_sticky )
			{
				Action(j, ACT_ADD_ITEM, Action(list_ball[i], ACT_GET_ITEM, 0));
				Action(j, ACT_ADD_ITEM, -999999);
				BallInVehi++;
				Log2("BallInVehi = " + itoa(BallInVehi));
			}
			else
				Action(j, ACT_SET_SPEED, BallSpeed);//NORMAL_BALL_SPEED);
		}
	}
}


//------------------------------------------------------------------------------------------
BnsVehSticky()
{
	if ( !VehiIsSticky )
	{
		VehiIsSticky = 1;
		CreateSprite(33, GetX(PlayerVehi), GetY(PlayerVehi) - 0, GetZ(PlayerVehi), 0, PlayerVehi);
	}
}


//------------------------------------------------------------------------------------------
BnsVehGun()
{
    if ( !VehiHaveGun )
    {
    	VehiHaveMissile = 0;
    	DeleteLink(PlayerVehi, 21);// уничтожение ракеты 1
    	DeleteLink(PlayerVehi, 22);// уничтожение ракеты 2
    	DeleteLink(PlayerVehi, 23);// уничтожение ракеты 3
    	VehiHaveGun = 1;
    	int link;
    	for ( link = Action(PlayerVehi, ACT_GET_LINK); link; link = Action(link, ACT_GET_LINK) )
    		if ( GetUnitVid(link) == 24 )
    			Action(link, ACT_CHANGE_VID, 25);// превращение пустой пулемета в заряженного
    }
}


//------------------------------------------------------------------------------------------
BnsBallsDeath()
{
    int i;
	for ( i = FirstUnit(U_UNIT); i; i = NextUnit() )
		if ( GetVidData(GetUnitVid(i), VID_CLASS) == B_BALL )
			Action(i, ANI_DEATH);
}


//------------------------------------------------------------------------------------------
BnsVehMissile()
{
    if ( !VehiHaveMissile )
    {
    	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);// превращение заряженного пулемета в пустой
    	VehiHaveMissile = 1;
    	CreateSprite(23, GetX(PlayerVehi), GetY(PlayerVehi), GetZ(PlayerVehi), 0, PlayerVehi);
    }
}


//------------------------------------------------------------------------------------------
GetBonusPoints(int Vid)
{
	int ret = 0;
	//
    if(Vid==100)
    {	ret = SCORES_FOR_BONUS;	}		// бонус расширения тележки
	else if(Vid==101)
	{	ret = SCORES_FOR_BONUS;	}		// бонус замедления шарика
	else if(Vid==102)
	{	ret = SCORES_FOR_NEG_BONUS;	}	// бонус ускорения шарика
	else if(Vid==103)
	{	ret = SCORES_FOR_BONUS;	}		// бонус победы на уровне
	else if(Vid==106)
	{	ret = SCORES_FOR_BONUS;	}		// бонус превращения шарика в разрушитель
	else if(Vid==107)
	{	ret = SCORES_FOR_NEG_BONUS;	}	// бонус сужения тележки
	else if(Vid==108)
	{	ret = SCORES_FOR_BONUS;	}		// бонус добавление жизни(шарика)
	else if(Vid==109)
	{	ret = SCORES_FOR_BONUS;	}		// бонус растроения шариков
	else if(Vid==110)
	{	ret = SCORES_FOR_NEG_BONUS;	}	// бонус превращения шарика в уменьшенный
	else if(Vid==111)
	{	ret = SCORES_FOR_BONUS;	}		// бонус липучки на тележку
	else if(Vid==112)
	{	ret = SCORES_FOR_BONUS;	}		// бонус пулемета на тележку
	else if(Vid==113)
	{	ret = SCORES_FOR_NEG_BONUS;	}	// бонус смерти всех шариков
	else if(Vid==114)
	{	ret = SCORES_FOR_BONUS;	}		// бонус превращения шарика в взрывающий
	else if(Vid==115)
	{	ret = SCORES_FOR_BONUS;	}		// бонус превращения шарика в нормальный
	else if(Vid==116)
	{	ret = SCORES_FOR_BONUS;	}		// бонус превращения шарика в увеличенный
	else if(Vid==117)
	{	ret = SCORES_FOR_BONUS;	}		// бонус ракетницы на тележку
	else if(Vid==880)
	{	ret = SCORES_FOR_CRYSTALL;	}	// бонус кристалл
	//
	return ret;
}


//------------------------------------------------------------------------------------------
CommonBonusProc(int unit)
{
    if( ToScreenY(GetY(unit)) > (ScreenY() + DEATH_SHIFT_Y))	//улетели с экрана
    {
        Action(unit, ANI_DEATH);
        return;
    }
	//
    int shield; shield = Action(PlayerVehi, ACT_GET_LINK);
    //if( GetY(unit) > GetY(shield) && Abs(GetX(unit) - GetX(shield)) < GetVidData(GetUnitVid(shield), VID_SIZE_X)/2 )
    if(IntersectWithVehi(unit, true, true))
    {
        int Vid; Vid = GetUnitVid(unit);
        //
        if(Vid==100)
        {	BnsIncreaseVehi();			}		// бонус расширения тележки
		else if(Vid==101)
		{	BnsDecrBallSpeed();			}		// бонус замедления шарика
		else if(Vid==102)
		{	BnsIncrBallSpeed();			}		// бонус ускорения шарика
		else if(Vid==103)
		{	BnsLevelWin();				}		// бонус победы на уровне
		else if(Vid==106)
		{	ChangeAllBallsTo(502);		}		// бонус превращения шарика в разрушитель
		else if(Vid==107)
		{	BnsDecreaseVehi();			}		// бонус сужения тележки
		else if(Vid==108)
		{	BnsAddLife();				}		// бонус добавление жизни(шарика)
		else if(Vid==109)
		{	BnsTrippleBalls();			}		// бонус растроения шариков
		else if(Vid==110)
		{	ChangeAllBallsTo(501);		}		// бонус превращения шарика в уменьшенный
		else if(Vid==111)
		{	BnsVehSticky();				}		// бонус липучки на тележку
		else if(Vid==112)
		{	BnsVehGun();				}		// бонус пулемета на тележку
		else if(Vid==113)
		{	BnsBallsDeath();			}		// бонус смерти всех шариков
		else if(Vid==114)
		{	ChangeAllBallsTo(504);		}		// бонус превращения шарика в взрывающий
		else if(Vid==115)
		{	ChangeAllBallsTo(500);		}		// бонус превращения шарика в нормальный
		else if(Vid==116)
		{	ChangeAllBallsTo(503);		}		// бонус превращения шарика в увеличенный
		else if(Vid==117)
		{	BnsVehMissile();			}		// бонус ракетницы на тележку
		else if(Vid==880)
		{								}		// бонус кристалл
		//else if(Vid==916)
		//{																// огненный шар
		//	Action(PlayerVehi, ANI_DEATH);
		//}
		else
			Log("Error! Unknown bonus vid " + itoa(Vid) + " of unit " + itoa(unit));
		//
		int dd = GetBonusPoints(Vid);
		giBonusSubLevScore += dd;
		gScoreTot += dd * 10;
        //
        Action(unit, ANI_DEATH2);
    }
}


//------------------------------------------------------------------------------------------
F100_2(int unit) { CommonBonusProc(unit); }// бонус расширения тележки
F101_2(int unit) { CommonBonusProc(unit); }// бонус замедления шарика
F102_2(int unit) { CommonBonusProc(unit); }// бонус ускорения шарика
F103_2(int unit) { CommonBonusProc(unit); }// бонус победы на уровне
F106_2(int unit) { CommonBonusProc(unit); }// бонус превращения шарика в разрушитель
F107_2(int unit) { CommonBonusProc(unit); }// бонус сужения тележки
F108_2(int unit) { CommonBonusProc(unit); }// бонус добавление жизни(шарика)
F109_2(int unit) { CommonBonusProc(unit); }// бонус растроения шариков
F110_2(int unit) { CommonBonusProc(unit); }// бонус превращения шарика в уменьшенный
F111_2(int unit) { CommonBonusProc(unit); }// бонус липучки на тележку
F112_2(int unit) { CommonBonusProc(unit); }// бонус пулемета на тележку
F113_2(int unit) { CommonBonusProc(unit); }// бонус смерти всех шариков
F114_2(int unit) { CommonBonusProc(unit); }// бонус превращения шарика в взрывающий
F115_2(int unit) { CommonBonusProc(unit); }// бонус превращения шарика в нормальный
F116_2(int unit) { CommonBonusProc(unit); }// бонус превращения шарика в увеличенный
F117_2(int unit) { CommonBonusProc(unit); }// бонус ракетницы на тележку
F880_2(int unit) { CommonBonusProc(unit); }// бонус кристалл
//F916_2(int unit) { CommonBonusProc(unit); }// огненный шар


//------------------------------------------------------------------------------------------
//F104_15(int unit)
//{// при взрыве ядра победного бонуса 
//    GameState = GAMESTATE_WIN_BONUS;
//    Action(ExitDoor, ANI_DEATH);
//    Action(PlayerVehi, ACT_MOVE, GetX(ExitDoor), GetY(ExitDoor) + 40, GetZ(ExitDoor));
//    AddCommand(PlayerVehi, ACT_MOVE, GetX(ExitDoor), ExitDoorY - 140, GetZ(ExitDoor));
//    AddCommand(PlayerVehi, ACT_PAUSE, 300);
//}

