PDA

Просмотр полной версии : [Мануал] Система однорукого бандита | Слот-машина(Аналог Advance-RP)



Syme
27.06.2016, 16:59
Здравствуйте, уважаемые посетители портала Pro-Pawn. Это моя давняя работа, которую я делал знакомому 1,5 года назад, но она осталась невостребованной, поэтому я её слегка доработал и выкладываю в паблик для наработки собственного портфолио.

Идея была позаимствована у Advance RP, однако она не просто скопирована, а усовершенствована доп.функционалом.

Посмотреть данную систему в действии можно в видео:

https://www.youtube.com/watch?v=I-rwOW5n91U

Слот-машины созданы в интерьере казино "Калигула".

Ресурсы:


#include <a_samp>
#include <streamer>


Дефайны коэффициентов выигрыша:



#define COMBO_DOUBLE_GOLD 1
#define COMBO_GOLD 2
#define COMBO_CHERRY 3
#define COMBO_BELL 4
#define COMBO_69 5
#define COMBO_GRAPES 6


#define sm_count 6 // кол-во слот-машин

Переменные:


/* Массивы координат rotx соответствующие своей картинке на слот-барабане */

new Float: image_rot [ ] ={ 3.00, 23.00, 43.00, 63.00, 83.00, 103.00, 123.00, 143.00, 163.00, 183.00, 203.00, 223.00, 243.00, 263.00, 283.00, 303.00, 323.00, 343.00, 363.00 } ;
new Float: cherry_combo [ 4 ] ={ 23.00, 163.00, 223.00, 343.00 } ;
new Float: gold_combo [ 2 ] ={ 183.00, 303.00 } ;
new Float: bell_combo [ 4 ] ={ 63.00, 103.00, 243.00, 323.00 } ;
new Float: grapes_combo [ 5 ] ={ 3.00, 83.00, 143.00, 283.00, 363.00 } ;
new Float: sn_combo [ 3 ] ={ 43.00, 123.00, 263.00 } ;

/* Стат автомата */

new sm_used [ sm_count char ] ; // переменная для записи статуса автомата(занят/свободен)

/* Ручки автоматов */

new sm_hand [ 6 ] ; // переменная для записи ID объекта ручки нашей слот-машины
new Float: sm_hand_coord [ 6 ] [ 6 ] ={ // массив координат объекта ручки слот-машины
{ 2255.27051, 1609.61804, 1005.81678, 15.00000, 0.00000, 0.00000 },
{ 2255.23047, 1610.11804, 1005.81678, 15.00000, 0.00000, 180.00000 },
{ 2255.27051, 1613.65796, 1005.81678, 15.00000, 0.00000, 0.00000 },
{ 2255.23047, 1614.15796, 1005.81678, 15.00000, 0.00000, 180.00000 },
{ 2255.27051, 1617.55798, 1005.81678, 15.00000, 0.00000, 0.00000 },
{ 2255.23047, 1618.05798, 1005.81678, 15.00000, 0.00000, 180.00000 }
} ;

/* Слот-механизмы автоматов */

new sm_slot [ sm_count * 3 ] ; // переменная под запись id объекта слота
new Float: sm_slot_coord [ sm_count * 3 ] [ 6 ] ={ // массив координат для объектов слотов
{ 2255.15039, 1609.70215, 1006.72223, 3.00000, 0.00000, 0.00000 },
{ 2255.26050, 1609.70215, 1006.72223, 3.00000, 0.00000, 0.00000 },
{ 2255.37061, 1609.70215, 1006.72223, 3.00000, 0.00000, 0.00000 },

{ 2255.3599, 1610.0387, 1006.7222, 3.00000, 0.00000, 180.00000 },
{ 2255.25000, 1610.03870, 1006.72223, 3.00000, 0.00000, 180.00000 },
{ 2255.13989, 1610.03870, 1006.72223, 3.00000, 0.00000, 180.00000 },

{ 2255.15039, 1613.74207, 1006.72223, 3.00000, 0.00000, 0.00000 },
{ 2255.26050, 1613.74207, 1006.72223, 3.00000, 0.00000, 0.00000 },
{ 2255.37061, 1613.74207, 1006.72223, 3.00000, 0.00000, 0.00000 },

{ 2255.35986, 1614.07874, 1006.72223, 3.00000, 0.00000, 180.00000 },
{ 2255.25000, 1614.07874, 1006.72223, 3.00000, 0.00000, 180.00000 },
{ 2255.13989, 1614.07874, 1006.72223, 3.00000, 0.00000, 180.00000 },

{ 2255.15039, 1617.64209, 1006.72223, 3.00000, 0.00000, 0.00000 },
{ 2255.26050, 1617.64209, 1006.72223, 3.00000, 0.00000, 0.00000 },
{ 2255.37061, 1617.64209, 1006.72223, 3.00000, 0.00000, 0.00000 },

{ 2255.35986, 1617.97876, 1006.72223, 3.00000, 0.00000, 180.00000 },
{ 2255.25000, 1617.97876, 1006.72223, 3.00000, 0.00000, 180.00000 },
{ 2255.13989, 1617.97876, 1006.72223, 4.00000, 0.00000, 180.00000 }
} ;

/* Зона использования автомата */

new Float: sm_coord [ sm_count ] [ 3 ] = { // массив с координатами расположения зоны использования слот-машины
{ 2255.3538, 1608.2896, 1006.1860 },
{ 2255.2034, 1611.2628, 1006.1797 },
{ 2255.3030, 1612.6776, 1006.1797 },
{ 2255.1860, 1615.4429, 1006.1797 },
{ 2255.2361, 1616.5598, 1006.1797 },
{ 2255.2834, 1618.9281, 1006.1797 }
} ;

/* TextDraws */

new Text: sm_td [ 4 ] ;
new PlayerText: sm_ptd [ MAX_PLAYERS ] = {PlayerText:-1, ...} ;


Далее нам нужно создать объекты наших слот-машин, для этого вставляем в OnGameModeInit:


/* Коробки автоматов */
CreateDynamicObject ( 1948, 2255.22510, 1609.66577, 1006.73523, 0.00000, 0.00000, 0.00000 ) ;
CreateDynamicObject ( 1948, 2255.28516, 1610.07581, 1006.73523, 0.00000, 0.00000, 180.00000 ) ;
CreateDynamicObject ( 1948, 2255.22510, 1613.70593, 1006.73523, 0.00000, 0.00000, 0.00000 ) ;
CreateDynamicObject ( 1948, 2255.28516, 1614.11584, 1006.73523, 0.00000, 0.00000, 180.00000 ) ;
CreateDynamicObject ( 1948, 2255.22510, 1617.60596, 1006.73523, 0.00000, 0.00000, 0.00000 ) ;
CreateDynamicObject ( 1948, 2255.28516, 1618.01587, 1006.73523, 0.00000, 0.00000, 180.00000 ) ;

/* Ручки автоматов */

for ( new i = 0 ; i < sm_count; i ++ )
{
sm_hand [ i ] = CreateDynamicObject ( 1832, sm_hand_coord [ i ] [ 0 ], sm_hand_coord [ i ] [ 1 ], sm_hand_coord [ i ] [ 2 ], sm_hand_coord [ i ] [ 3 ], sm_hand_coord [ i ] [ 4 ], sm_hand_coord [ i ] [ 5 ] ) ;
SetDynamicObjectMaterial ( sm_hand [ i ], 0, -1, "none", "none", 255 ) ; // т.к отдельный объект ручки мной не был найден, пришлось изобрести её
SetDynamicObjectMaterial ( sm_hand [ i ], 2, -1, "none", "none", 255 ) ;
}

/* Слот-механизмы автоматов */

for ( new i = 0 ; i < sm_count * 3; i ++ )
{
sm_slot [ i ] = CreateDynamicObject ( 2349, sm_slot_coord [ i ] [ 0 ], sm_slot_coord [ i ] [ 1 ], sm_slot_coord [ i ] [ 2 ], sm_slot_coord [ i ] [ 3 ], sm_slot_coord [ i ] [ 4 ], sm_slot_coord [ i ] [ 5 ] ) ;
}

/* Текстдравы */
sm_td [ 0 ] = TextDrawCreate ( 276.000000, 355.000000, " SET" ) ;
TextDrawBackgroundColor ( sm_td [ 0 ], 255 ) ;
TextDrawFont ( sm_td [ 0 ], 2 ) ;
TextDrawLetterSize ( sm_td [ 0 ], 0.419999, 2.099999 ) ;
TextDrawColor ( sm_td [ 0 ], -2711041 ) ;
TextDrawSetOutline ( sm_td [ 0 ], 0 ) ;
TextDrawSetProportional ( sm_td [ 0 ], 1 ) ;
TextDrawSetShadow ( sm_td [ 0 ], 1 ) ;
TextDrawBoxColor ( sm_td [ 0 ], 255 ) ;
TextDrawTextSize ( sm_td [ 0 ], 336.000000, 12.000000 ) ;
TextDrawSetSelectable ( sm_td [ 0 ], 1 ) ;

sm_td [ 1 ] = TextDrawCreate ( 375.000000, 355.000000, " RESET" ) ;
TextDrawBackgroundColor ( sm_td [ 1 ], 255 ) ;
TextDrawFont ( sm_td [ 1 ], 2 ) ;
TextDrawLetterSize ( sm_td [ 1 ], 0.419999, 2.099999 ) ;
TextDrawColor ( sm_td [ 1 ], -2711041 ) ;
TextDrawSetOutline ( sm_td [ 1 ], 0 ) ;
TextDrawSetProportional ( sm_td [ 1 ], 1 ) ;
TextDrawSetShadow ( sm_td [ 1 ], 1 ) ;
TextDrawBoxColor ( sm_td [ 1 ], 255 ) ;
TextDrawTextSize ( sm_td [ 1 ], 436.000000, 12.000000 ) ;
TextDrawSetSelectable ( sm_td [ 1 ], 1 ) ;

sm_td [ 2 ] = TextDrawCreate ( 182.000000, 355.000000, " ~r~Exit" ) ;
TextDrawBackgroundColor ( sm_td [ 2 ], 255 ) ;
TextDrawFont ( sm_td [ 2 ], 2 ) ;
TextDrawLetterSize ( sm_td [ 2 ], 0.419999, 2.099999 ) ;
TextDrawColor ( sm_td [ 2 ], -2711041 ) ;
TextDrawSetOutline ( sm_td [ 2 ], 0 ) ;
TextDrawSetProportional ( sm_td [ 2 ], 1 ) ;
TextDrawSetShadow ( sm_td [ 2 ], 1 ) ;
TextDrawBoxColor ( sm_td [ 2 ], 255 ) ;
TextDrawTextSize ( sm_td [ 2 ], 244.000000, 12.000000 ) ;
TextDrawSetSelectable ( sm_td [ 2 ], 1 ) ;

sm_td [ 3 ] = TextDrawCreate ( 554.000000, 123.000000, "slot hand" ) ;
TextDrawBackgroundColor ( sm_td [ 3 ], 0 ) ;
TextDrawFont ( sm_td [ 3 ], 5 ) ;
TextDrawLetterSize ( sm_td [ 3 ], 0.500000, 1.000000 ) ;
TextDrawColor ( sm_td [ 3 ], 16711935 ) ;
TextDrawSetOutline ( sm_td [ 3 ], 0 ) ;
TextDrawSetProportional ( sm_td [ 3 ], 1 ) ;
TextDrawSetShadow ( sm_td [ 3 ], 1 ) ;
TextDrawUseBox ( sm_td [ 3 ], 1 ) ;
TextDrawBoxColor ( sm_td [ 3 ], 255 ) ;
TextDrawTextSize ( sm_td [ 3 ], 86.000000, 260.000000 ) ;
TextDrawSetPreviewModel ( sm_td [ 3 ], 1 ) ;
TextDrawSetPreviewRot ( sm_td [ 3 ], -16.000000, 0.000000, -55.000000, -1.000000 ) ;
TextDrawSetSelectable ( sm_td [ 3 ], 1 ) ;

Дефолтные слот-машины мешали при установке новых, поэтому в OnPlayerConnect нужно использовать следующую функцию:



RemoveDefaultSm ( playerid ) ;


Сама функция:



stock RemoveDefaultSm ( playerid )
{
RemoveBuildingForPlayer(playerid, 1836, 2253.1250, 1609.6406, 1006.0000, 0.25 ) ;
RemoveBuildingForPlayer(playerid, 2325, 2255.1563, 1609.6016, 1006.7656, 0.25 ) ;
RemoveBuildingForPlayer(playerid, 1836, 2257.2422, 1609.6406, 1006.0000, 0.25 ) ;
RemoveBuildingForPlayer(playerid, 1837, 2253.1016, 1610.1172, 1006.0000, 0.25 ) ;
RemoveBuildingForPlayer(playerid, 1837, 2257.2500, 1610.1172, 1006.0000, 0.25 ) ;
RemoveBuildingForPlayer(playerid, 2325, 2255.1875, 1610.1250, 1006.7656, 0.25 ) ;
RemoveBuildingForPlayer(playerid, 1837, 2253.1016, 1614.1641, 1006.0000, 0.25 ) ;
RemoveBuildingForPlayer(playerid, 1836, 2253.1250, 1613.6875, 1006.0000, 0.25 ) ;
RemoveBuildingForPlayer(playerid, 2325, 2255.1563, 1613.6484, 1006.7656, 0.25 ) ;
RemoveBuildingForPlayer(playerid, 1837, 2257.2500, 1614.1641, 1006.0000, 0.25 ) ;
RemoveBuildingForPlayer(playerid, 1836, 2257.2422, 1613.6875, 1006.0000, 0.25 ) ;
RemoveBuildingForPlayer(playerid, 2325, 2255.1875, 1614.1719, 1006.7656, 0.25 ) ;
RemoveBuildingForPlayer(playerid, 1836, 2253.1250, 1617.5781, 1006.0000, 0.25 ) ;
RemoveBuildingForPlayer(playerid, 1836, 2257.2422, 1617.5781, 1006.0000, 0.25 ) ;
RemoveBuildingForPlayer(playerid, 2325, 2255.1563, 1617.5469, 1006.7656, 0.25 ) ;
RemoveBuildingForPlayer(playerid, 1837, 2253.1016, 1618.0547, 1006.0000, 0.25 ) ;
RemoveBuildingForPlayer(playerid, 1837, 2257.2500, 1618.0547, 1006.0000, 0.25 ) ;
RemoveBuildingForPlayer(playerid, 2325, 2255.1875, 1618.0703, 1006.7656, 0.25 ) ;
return 1 ;
}


Теперь мы переходим к самой активации слот-машин. Я сделал использование через клавишу "ALT", но Вы, естественно, можете изменить на удобный для Вас вариант. В OnPlayerKeyStateChange:


if ( GetPlayerState ( playerid ) == PLAYER_STATE_ONFOOT )
{
if ( newkeys == KEY_WALK )
{
if ( GetPlayerInterior ( playerid ) != 1 ) return 1 ; // у Калигулы 1 id интерьера
if ( GetPVarInt ( playerid, "p_sm_used" ) != 0 ) return 1 ; // Проверяем использует уже игрок какую-либо слот-машину или нет
for ( new sm = 0; sm < sm_count ; sm ++ )
{
if ( sm_used { sm } != 0 ) continue ; // Проверяем занята слот-машина или нет
if ( ! IsPlayerInRangeOfPoint ( playerid, 1.50, sm_coord [ sm ] [ 0 ], sm_coord [ sm ] [ 1 ], sm_coord [ sm ] [ 2 ] ) ) continue ; // Проверяем на нахождение в площади активации слот-машины
SetPVarInt ( playerid, "p_sm_used", sm + 1 ) ;
TogglePlayerControllable ( playerid, false ) ;

sm_used { sm } = 1 ;

sm_ptd [ playerid ] = CreatePlayerTextDraw ( playerid, 266.000000, 272.000000, "BET: 0$" ) ;
PlayerTextDrawBackgroundColor ( playerid, sm_ptd [ playerid ] , 255 ) ;
PlayerTextDrawFont ( playerid, sm_ptd [ playerid ] , 2 ) ;
PlayerTextDrawLetterSize ( playerid, sm_ptd [ playerid ] , 0.310000, 2.700000 ) ;
PlayerTextDrawColor ( playerid, sm_ptd [ playerid ] , -2711041 ) ;
PlayerTextDrawSetOutline ( playerid, sm_ptd [ playerid ] , 1 ) ;
PlayerTextDrawSetProportional ( playerid, sm_ptd [ playerid ] , 1 ) ;
PlayerTextDrawSetSelectable ( playerid, sm_ptd [ playerid ] , 0 ) ;

for ( new i = 0 ; i < 4 ; i ++ )
{
TextDrawShowForPlayer ( playerid, sm_td [ i ] ) ;
}
PlayerTextDrawShow ( playerid, sm_ptd [ playerid ] ) ;
SelectTextDraw ( playerid, 0xFFDA82FF ) ;

// так получилось, что слот-машины стоят парами, поэтому для вычисления позиции камеры игрока я сделал проверку на чётность игрового автомата, чтобы ничего не придумывать с координатами поворота игрового автомата.
if ( sm & 1 == 0 ) SetPlayerCameraPos(playerid, sm_hand_coord [ sm ] [ 0 ], sm_hand_coord [ sm ] [ 1 ] - 0.65, sm_hand_coord [ sm ] [ 2 ] + 1 ), SetPlayerCameraLookAt ( playerid, sm_hand_coord [ sm ] [ 0 ], sm_hand_coord [ sm ] [ 1 ] + 1, sm_hand_coord [ sm ] [ 2 ] + 0.6 ) ;
else SetPlayerCameraPos(playerid, sm_hand_coord [ sm ] [ 0 ], sm_hand_coord [ sm ] [ 1 ] + 0.65, sm_hand_coord [ sm ] [ 2 ] + 1 ), SetPlayerCameraLookAt ( playerid, sm_hand_coord [ sm ] [ 0 ], sm_hand_coord [ sm ] [ 1 ] - 1, sm_hand_coord [ sm ] [ 2 ] + 0.6 ) ;
break ;
}
}
}


Манипуляции слот-машиной осуществляются на кликабельных текстдравах. В OnPlayerClickTextDraw вставляем следующее:


if ( GetPVarInt ( playerid, "p_sm_used" ) )
{
if(!(_:clickedid ^ 0xFFFF))return SelectTextDraw ( playerid, 0xFFDA82FF ) ;
}
if ( clickedid == sm_td [ 2 ] ) // Выход
{
if ( GetPVarInt ( playerid, "sm_started" ) ) return 1 ; // В момент кручения барабана и движения ручки нельзя выйти
SetCameraBehindPlayer ( playerid ) ;
TogglePlayerControllable ( playerid, true ) ;
CancelSelectTextDraw ( playerid ) ;
PlayerTextDrawDestroy ( playerid, sm_ptd [ playerid ] ) ;
sm_ptd [ playerid ] = PlayerText:INVALID_TEXT_DRAW ;
for ( new i = 0 ; i < 4 ; i ++ )
{
TextDrawHideForPlayer ( playerid, sm_td [ i ] ) ;
}
sm_used { GetPVarInt ( playerid, "p_sm_used" ) - 1 } = 0 ;
DeletePVar ( playerid, "p_sm_used" ) ;
return 1 ;
}
else if ( clickedid == sm_td [ 0 ] )
{
if ( GetPVarInt ( playerid, "sm_started" ) ) return 1 ; // В момент кручения барабана и движения ручки нельзя изменить ставку
ShowPlayerDialog ( playerid, 1, DIALOG_STYLE_INPUT, "{FFFFFF}Размер ставки", "{FFFFFF}Введите размер Вашей ставки:", "Принять", "Отмена" ) ;
return 1 ;
}
else if ( clickedid == sm_td [ 1 ] ) // сброс информации слот-машины
{
if ( GetPVarInt ( playerid, "sm_started" ) ) return 1 ; // В момент кручения барабана и движения ручки нельзя сбросить инфу слот-машины
DeletePVar ( playerid, "sm_bet" ) ;

new i = ( GetPVarInt ( playerid, "p_sm_used" ) * 2 + ( GetPVarInt ( playerid, "p_sm_used" ) - 2 ) ) - 1 ;
MoveDynamicObject ( sm_slot [ i ], sm_slot_coord [ i ] [ 0 ], sm_slot_coord [ i ] [ 1 ], sm_slot_coord [ i ] [ 2 ], 1, sm_slot_coord [ i ] [ 3 ], sm_slot_coord [ i ] [ 4 ], sm_slot_coord [ i ] [ 5 ] ) ;
MoveDynamicObject ( sm_slot [ i + 1 ], sm_slot_coord [ i + 1 ] [ 0 ], sm_slot_coord [ i + 1 ] [ 1 ], sm_slot_coord [ i + 1 ] [ 2 ], 1, sm_slot_coord [ i + 1 ] [ 3 ], sm_slot_coord [ i + 1 ] [ 4 ], sm_slot_coord [ i + 1 ] [ 5 ] ) ;
MoveDynamicObject ( sm_slot [ i + 2 ], sm_slot_coord [ i + 2 ] [ 0 ], sm_slot_coord [ i + 2 ] [ 1 ], sm_slot_coord [ i + 2 ] [ 2 ], 1, sm_slot_coord [ i + 2 ] [ 3 ], sm_slot_coord [ i + 2 ] [ 4 ], sm_slot_coord [ i + 2 ] [ 5 ] ) ;
PlayerTextDrawSetString ( playerid, sm_ptd [ playerid ], "bet: 0$" ) ;
return 1 ;
}
else if ( clickedid == sm_td [ 3 ] ) // Ручка слот-машины.
{
if ( GetPVarInt ( playerid, "sm_started" ) ) return 1 ; // В момент кручения барабана и движения ручки нельзя ещё раз дёрнуть ручку
if ( GetPVarInt ( playerid, "sm_bet" ) == 0 ) return SendClientMessage ( playerid, -1, "* Вы не сделали ставку!" ) ;
SetPVarInt ( playerid, "sm_started", 1 ) ;
new i = GetPVarInt ( playerid, "p_sm_used" ) - 1 ;

if (i & 1 == 0 ) MoveDynamicObject ( sm_hand [ i ], sm_hand_coord [ i ] [ 0 ], sm_hand_coord [ i ] [ 1 ], sm_hand_coord [ i ] [ 2 ] - 0.30, 1, sm_hand_coord [ i ] [ 3 ] + 20, sm_hand_coord [ i ] [ 4 ], sm_hand_coord [ i ] [ 5 ] ) ;
else MoveDynamicObject ( sm_hand [ i ], sm_hand_coord [ i ] [ 0 ], sm_hand_coord [ i ] [ 1 ], sm_hand_coord [ i ] [ 2 ] - 0.30, 1, sm_hand_coord [ i ] [ 3 ] + 20, sm_hand_coord [ i ] [ 4 ], sm_hand_coord [ i ] [ 5 ] ) ;
SetTimerEx ( "BackSmHand", 1000, false, "idd", playerid, sm_hand [ i ], i ) ;

}

Далее следуют таймеры, которые необходимы для корректной работы системы:



forward BackSmHand ( playerid, objectid, i ) ;
public BackSmHand ( playerid, objectid, i )
{
MoveDynamicObject ( objectid, sm_hand_coord [ i ] [ 0 ], sm_hand_coord [ i ] [ 1 ], sm_hand_coord [ i ] [ 2 ], 2, sm_hand_coord [ i ] [ 3 ], sm_hand_coord [ i ] [ 4 ], sm_hand_coord [ i ] [ 5 ] ) ;
i = ( ( i + 1 ) * 2 + ( ( i + 1 ) - 2 ) ) - 1 ;
SetTimerEx ( "MoveSmSlot", 348, false, "id", playerid, i ) ;
return 1 ;
}

forward MoveSmSlot ( playerid, i ) ;
public MoveSmSlot ( playerid, i )
{
new Float: obj_pos_z ;
new sm_move_time ;
GetDynamicObjectPos ( sm_slot [ i ], obj_pos_z, obj_pos_z, obj_pos_z ) ;
if ( sm_slot_coord [ i ] [ 2 ] != obj_pos_z )
{
sm_move_time = MoveDynamicObject ( sm_slot [ i ], sm_slot_coord [ i ] [ 0 ], sm_slot_coord [ i ] [ 1 ], sm_slot_coord [ i ] [ 2 ], 0.04, image_rot [ random ( sizeof ( image_rot ) ) ], sm_slot_coord [ i ] [ 4 ], sm_slot_coord [ i ] [ 5 ] ) ;
MoveDynamicObject ( sm_slot [ i + 1 ], sm_slot_coord [ i + 1 ] [ 0 ], sm_slot_coord [ i + 1 ] [ 1 ], sm_slot_coord [ i + 1 ] [ 2 ], 0.04, image_rot [ random ( sizeof ( image_rot ) ) ], sm_slot_coord [ i + 1 ] [ 4 ], sm_slot_coord [ i + 1 ] [ 5 ] ) ;
MoveDynamicObject ( sm_slot [ i + 2 ], sm_slot_coord [ i + 2 ] [ 0 ], sm_slot_coord [ i + 2 ] [ 1 ], sm_slot_coord [ i + 2 ] [ 2 ], 0.04, image_rot [ random ( sizeof ( image_rot ) ) ], sm_slot_coord [ i + 2 ] [ 4 ], sm_slot_coord [ i + 2 ] [ 5 ] ) ;
}
else
{
sm_move_time = MoveDynamicObject ( sm_slot [ i ], sm_slot_coord [ i ] [ 0 ], sm_slot_coord [ i ] [ 1 ], sm_slot_coord [ i ] [ 2 ] + 0.02, 0.04, image_rot [ random ( sizeof ( image_rot ) ) ], sm_slot_coord [ i ] [ 4 ], sm_slot_coord [ i ] [ 5 ] ) ;
MoveDynamicObject ( sm_slot [ i + 1 ], sm_slot_coord [ i + 1 ] [ 0 ], sm_slot_coord [ i + 1 ] [ 1 ], sm_slot_coord [ i + 1 ] [ 2 ] + 0.02, 0.04, image_rot [ random ( sizeof ( image_rot ) ) ], sm_slot_coord [ i + 1 ] [ 4 ], sm_slot_coord [ i + 1 ] [ 5 ] ) ;
MoveDynamicObject ( sm_slot [ i + 2 ], sm_slot_coord [ i + 2 ] [ 0 ], sm_slot_coord [ i + 2 ] [ 1 ], sm_slot_coord [ i + 2 ] [ 2 ] + 0.02, 0.04, image_rot [ random ( sizeof ( image_rot ) ) ], sm_slot_coord [ i + 2 ] [ 4 ], sm_slot_coord [ i + 2 ] [ 5 ] ) ;
}
SetTimerEx ( "ChechSmResult", sm_move_time + 100, false, "iddd", playerid, sm_slot [ i ], sm_slot [ i + 1 ], sm_slot [ i + 2 ] ) ;
return 1 ;
}

forward ChechSmResult ( playerid, obj_1, obj_2, obj_3 ) ;
public ChechSmResult ( playerid, obj_1, obj_2, obj_3 )
{
if ( GetPVarInt ( playerid, "sm_bet" ) == 0 ) return 1 ;
new result = GetSmResult ( obj_1, obj_2, obj_3 ) ;
if ( ! result )
{
PlayerTextDrawSetString ( playerid, sm_ptd [ playerid ], "bet: 0$" ) ;
GivePlayerMoney ( playerid, - GetPVarInt ( playerid, "sm_bet" ) ) ;
DeletePVar ( playerid, "sm_bet" ) ;
SendClientMessage ( playerid, -1, "* Вы ничего не выиграли!" ) ;
GameTextForPlayer(playerid, "~r~LOSE", 5000, 3 ) ;
}
else
{
new sm_win_cash = GetPVarInt ( playerid, "sm_bet" ) * ( 7 - result ) ;
GivePlayerMoney ( playerid, sm_win_cash ) ;
SendClientMessage ( playerid, -1, "* Вы выиграли!" ) ;
DeletePVar ( playerid, "sm_bet" ) ;
new gt_string [ 18 ] ;
format ( gt_string, 18, "~g~WIN: %d$", sm_win_cash ) ;
GameTextForPlayer(playerid, gt_string, 5000, 3 ) ;

PlayerTextDrawSetString ( playerid, sm_ptd [ playerid ], "bet: 0$" ) ;
}
DeletePVar ( playerid, "sm_started" ) ;
return 1 ;
}

Нельзя обойтись без диалога, в котором указывается размер ставки:



if ( dialogid == 1 )
{
if ( ! response ) return 1 ;
new bet_amount = strval ( inputtext ) ;
if ( bet_amount < 0 || bet_amount > 100000 ) return SendClientMessage ( playerid, -1, "* Размер ставки не может быть меньше 0$ или больше 100000$!" ) ;
if ( GetPlayerMoney ( playerid ) < bet_amount ) return SendClientMessage ( playerid, -1, "* У Вас нет такого количества денег!" ) ;
SetPVarInt ( playerid, "sm_bet", bet_amount ) ;
new td_string [ 14 ] ;
format ( td_string, 14, "bet: %d$", bet_amount ) ;
PlayerTextDrawSetString ( playerid, sm_ptd [ playerid ], td_string ) ;
}


Теперь мы переходим к ключевой функции данной системы. Как-раз она подводит результаты игры в слот-машине.



stock GetSmResult ( obj_1, obj_2, obj_3 )
{
new Float: rot_pos [ 4 ];
GetDynamicObjectRot ( obj_1, rot_pos [ 0 ], rot_pos [ 3 ], rot_pos [ 3 ] ) ;
GetDynamicObjectRot ( obj_2, rot_pos [ 1 ], rot_pos [ 3 ], rot_pos [ 3 ] ) ;
GetDynamicObjectRot ( obj_3, rot_pos [ 2 ], rot_pos [ 3 ], rot_pos [ 3 ] ) ;

if ( rot_pos [ 0 ] == rot_pos [ 1 ] && rot_pos [ 0 ] == rot_pos [ 2 ] && rot_pos [ 0 ] && rot_pos [ 0 ] == 200 ) return COMBO_DOUBLE_GOLD;
new combo_points = 0;

for ( new i = 0; i < sizeof ( cherry_combo ) ; i++ )
{
for ( new f = 0; f < sizeof ( rot_pos ) - 1; f++ )
{
if ( rot_pos [ f ] == cherry_combo [ i ] )combo_points ++ ;
}
}
if ( combo_points == 3 ) return COMBO_CHERRY;
combo_points = 0;
for ( new i = 0; i < sizeof ( gold_combo ) ; i++ )
{
for ( new f = 0; f < sizeof ( rot_pos ) - 1; f++ )
{
if ( rot_pos [ f ] == gold_combo [ i ] )combo_points ++ ;
}
}
if ( combo_points == 3 ) return COMBO_GOLD;
combo_points = 0;
for ( new i = 0; i < sizeof ( bell_combo ) ; i++ )
{
for ( new f = 0; f < sizeof ( rot_pos ) - 1; f++ )
{
if ( rot_pos [ f ] == bell_combo [ i ] )combo_points ++ ;
}
}
if ( combo_points == 3 ) return COMBO_BELL;
combo_points = 0;
for ( new i = 0; i < sizeof ( grapes_combo ) ; i++ )
{
for ( new f = 0; f < sizeof ( rot_pos ) - 1; f++ )
{
if ( rot_pos [ f ] == grapes_combo [ i ] )combo_points ++ ;
}
}
if ( combo_points == 3 ) return COMBO_GRAPES;
combo_points = 0;
for ( new i = 0; i < sizeof ( sn_combo ) ; i++ )
{
for ( new f = 0; f < sizeof ( rot_pos ) - 1; f++ )
{
if ( rot_pos [ f ] == sn_combo [ i ] )combo_points ++ ;
}
}
if ( combo_points == 3 ) return COMBO_69;
return false;
}

Важно не забыть о возможности отключения игрока при игре в слот-машине. В OnPlayerDisconnect:


if ( GetPVarInt ( playerid, "p_sm_used" ) )
{
PlayerTextDrawDestroy ( playerid, sm_ptd [ playerid ] ) ;
sm_ptd [ playerid ] = PlayerText:INVALID_TEXT_DRAW ;
for ( new i = 0 ; i < 4 ; i ++ )
{
TextDrawHideForPlayer ( playerid, sm_td [ i ] ) ;
}
new p_sm = GetPVarInt ( playerid, "p_sm_used" ) ;
new i = ( p_sm * 2 + ( p_sm - 2 ) ) - 1 ;
MoveDynamicObject ( sm_slot [ i ], sm_slot_coord [ i ] [ 0 ], sm_slot_coord [ i ] [ 1 ], sm_slot_coord [ i ] [ 2 ], 1, sm_slot_coord [ i ] [ 3 ], sm_slot_coord [ i ] [ 4 ], sm_slot_coord [ i ] [ 5 ] ) ;
MoveDynamicObject ( sm_slot [ i + 1 ], sm_slot_coord [ i + 1 ] [ 0 ], sm_slot_coord [ i + 1 ] [ 1 ], sm_slot_coord [ i + 1 ] [ 2 ], 1, sm_slot_coord [ i + 1 ] [ 3 ], sm_slot_coord [ i + 1 ] [ 4 ], sm_slot_coord [ i + 1 ] [ 5 ] ) ;
MoveDynamicObject ( sm_slot [ i + 2 ], sm_slot_coord [ i + 2 ] [ 0 ], sm_slot_coord [ i + 2 ] [ 1 ], sm_slot_coord [ i + 2 ] [ 2 ], 1, sm_slot_coord [ i + 2 ] [ 3 ], sm_slot_coord [ i + 2 ] [ 4 ], sm_slot_coord [ i + 2 ] [ 5 ] ) ;

sm_used { p_sm - 1 } = 0 ;
}


Команда для телепортации к слот-машине:


if (strcmp("/gotocasino", cmdtext, true, 10) == 0)
{
SetPlayerPos ( playerid, 2255.3538, 1608.2896, 1006.1860 ) ;
SetPlayerInterior ( playerid, 1 ) ;
return 1;
}



О возможных проблемах:
-- Следует изменить id диалога ставки ( if ( dialogid == 1 ) )
-- Следует заменить все функции денег на свои

Эта система - основа, Вы можете увеличить кол-во слот-машин, добавить ещё различные комбинации слотов и иной интересный функционал. Не ограничивайтесь простым копированием.

Буду рад ответить на все вопросы и выслушать все замечания по коду.

new.pwn, на котором я тестил, можно взять тут: https://gist.github.com/anonymous/96fda674aae88f388013ddff52140a08

Автор: Syme

Syme
01.07.2016, 14:34
Подкорректировал код. Тема вверх.

arzumanov
15.07.2016, 14:31
Отличная работа

Browze
16.07.2016, 21:44
Неплохо, спасибо.

Seviel
04.01.2017, 16:30
Мне кажется это лишняя проверка

if ( GetPlayerState ( playerid ) == PLAYER_STATE_ONFOOT )
Ведь кнопка KEY_WALK только пешком работает.

Vasya_Pupkin
26.01.2017, 20:17
А как сделать чтобы барабан крутился секунд 4-6 ?

Seviel
27.01.2017, 10:37
А как сделать чтобы барабан крутился секунд 4-6 ?


Манипуляции слот-машиной осуществляются на кликабельных текстдравах. В OnPlayerClickTextDraw вставляем следующее:


if ( GetPVarInt ( playerid, "p_sm_used" ) )
{
if(!(_:clickedid ^ 0xFFFF))return SelectTextDraw ( playerid, 0xFFDA82FF ) ;
}
if ( clickedid == sm_td [ 2 ] ) // Выход
{
if ( GetPVarInt ( playerid, "sm_started" ) ) return 1 ; // В момент кручения барабана и движения ручки нельзя выйти
SetCameraBehindPlayer ( playerid ) ;
TogglePlayerControllable ( playerid, true ) ;
CancelSelectTextDraw ( playerid ) ;
PlayerTextDrawDestroy ( playerid, sm_ptd [ playerid ] ) ;
sm_ptd [ playerid ] = PlayerText:INVALID_TEXT_DRAW ;
for ( new i = 0 ; i < 4 ; i ++ )
{
TextDrawHideForPlayer ( playerid, sm_td [ i ] ) ;
}
sm_used { GetPVarInt ( playerid, "p_sm_used" ) - 1 } = 0 ;
DeletePVar ( playerid, "p_sm_used" ) ;
return 1 ;
}
else if ( clickedid == sm_td [ 0 ] )
{
if ( GetPVarInt ( playerid, "sm_started" ) ) return 1 ; // В момент кручения барабана и движения ручки нельзя изменить ставку
ShowPlayerDialog ( playerid, 1, DIALOG_STYLE_INPUT, "{FFFFFF}Размер ставки", "{FFFFFF}Введите размер Вашей ставки:", "Принять", "Отмена" ) ;
return 1 ;
}
else if ( clickedid == sm_td [ 1 ] ) // сброс информации слот-машины
{
if ( GetPVarInt ( playerid, "sm_started" ) ) return 1 ; // В момент кручения барабана и движения ручки нельзя сбросить инфу слот-машины
DeletePVar ( playerid, "sm_bet" ) ;

new i = ( GetPVarInt ( playerid, "p_sm_used" ) * 2 + ( GetPVarInt ( playerid, "p_sm_used" ) - 2 ) ) - 1 ;
MoveDynamicObject ( sm_slot [ i ], sm_slot_coord [ i ] [ 0 ], sm_slot_coord [ i ] [ 1 ], sm_slot_coord [ i ] [ 2 ], 1, sm_slot_coord [ i ] [ 3 ], sm_slot_coord [ i ] [ 4 ], sm_slot_coord [ i ] [ 5 ] ) ;
MoveDynamicObject ( sm_slot [ i + 1 ], sm_slot_coord [ i + 1 ] [ 0 ], sm_slot_coord [ i + 1 ] [ 1 ], sm_slot_coord [ i + 1 ] [ 2 ], 1, sm_slot_coord [ i + 1 ] [ 3 ], sm_slot_coord [ i + 1 ] [ 4 ], sm_slot_coord [ i + 1 ] [ 5 ] ) ;
MoveDynamicObject ( sm_slot [ i + 2 ], sm_slot_coord [ i + 2 ] [ 0 ], sm_slot_coord [ i + 2 ] [ 1 ], sm_slot_coord [ i + 2 ] [ 2 ], 1, sm_slot_coord [ i + 2 ] [ 3 ], sm_slot_coord [ i + 2 ] [ 4 ], sm_slot_coord [ i + 2 ] [ 5 ] ) ;
PlayerTextDrawSetString ( playerid, sm_ptd [ playerid ], "bet: 0$" ) ;
return 1 ;
}
else if ( clickedid == sm_td [ 3 ] ) // Ручка слот-машины.
{
if ( GetPVarInt ( playerid, "sm_started" ) ) return 1 ; // В момент кручения барабана и движения ручки нельзя ещё раз дёрнуть ручку
if ( GetPVarInt ( playerid, "sm_bet" ) == 0 ) return SendClientMessage ( playerid, -1, "* Вы не сделали ставку!" ) ;
SetPVarInt ( playerid, "sm_started", 1 ) ;
new i = GetPVarInt ( playerid, "p_sm_used" ) - 1 ;

if (i & 1 == 0 ) MoveDynamicObject ( sm_hand [ i ], sm_hand_coord [ i ] [ 0 ], sm_hand_coord [ i ] [ 1 ], sm_hand_coord [ i ] [ 2 ] - 0.30, 1, sm_hand_coord [ i ] [ 3 ] + 20, sm_hand_coord [ i ] [ 4 ], sm_hand_coord [ i ] [ 5 ] ) ;
else MoveDynamicObject ( sm_hand [ i ], sm_hand_coord [ i ] [ 0 ], sm_hand_coord [ i ] [ 1 ], sm_hand_coord [ i ] [ 2 ] - 0.30, 1, sm_hand_coord [ i ] [ 3 ] + 20, sm_hand_coord [ i ] [ 4 ], sm_hand_coord [ i ] [ 5 ] ) ;
SetTimerEx ( "BackSmHand", 1000, false, "idd", playerid, sm_hand [ i ], i ) ;

}
Последним идёт таймер(SetTimerEx) вторым параметром которого является интервал(1000 миллисекунд это секунда), тебе необходимо от 4 до 6 секунд, то делай так.


SetTimerEx ( "BackSmHand", 1000*(random(2)+4), false, "idd", playerid, sm_hand [ i ], i ) ;

Nexius_Tailer
27.01.2017, 16:03
Последним идёт таймер(SetTimerEx) вторым параметром которого является интервал(1000 миллисекунд это секунда), тебе необходимо от 4 до 6 секунд, то делай так.


SetTimerEx ( "BackSmHand", 1000*(random(2)+4), false, "idd", playerid, sm_hand [ i ], i ) ;

Поправочка:

1000 * (random(3) + 4)

Seviel
27.01.2017, 16:27
А ну да, спасибо что подправил.

Vasya_Pupkin
27.01.2017, 16:48
Это таймер ручки) а нужно чтобы барабан крутился(ид обьекта 2349) до 6 секунд

Nexius_Tailer
27.01.2017, 17:08
Это таймер ручки) а нужно чтобы барабан крутился(ид обьекта 2349) до 6 секунд
Тогда ищи Move(Dynamic)Object и изменяй аргумент speed (четвёртым стоит, если с нуля их считать)