From 1ba5cc5290b3b69ac51751a9a6f5c32ffbbc495b Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Wed, 12 Sep 2018 08:08:23 +1000 Subject: [PATCH 01/17] pool offsets perfected (walls and holes) --- gamemodes/irresistible/cnr/features/pool.pwn | 197 +++++++++++++++---- gamemodes/sf-cnr.pwn | 2 - 2 files changed, 159 insertions(+), 40 deletions(-) diff --git a/gamemodes/irresistible/cnr/features/pool.pwn b/gamemodes/irresistible/cnr/features/pool.pwn index 1a21a25..e7f5261 100644 --- a/gamemodes/irresistible/cnr/features/pool.pwn +++ b/gamemodes/irresistible/cnr/features/pool.pwn @@ -10,6 +10,8 @@ #include < physics > #include < progress2 > +#define POOL_DEBUG + /* ** Marcos ** */ #define IsPlayerPlayingPool(%0) (p_isPlayingPool{%0}) @@ -22,8 +24,14 @@ #define MAX_TABLES 100 #define COL_POOL "{C0C0C0}" -/* ** Variables ** */ +/* ** Constants ** */ +new Float: g_poolPotOffsetData[ ] [ ] = { + { 0.955, 0.510 }, { 0.955, -0.49 }, + { 0.005, 0.550 }, { 0.007, -0.535 }, + { -0.945, 0.513 }, { -0.945, -0.490 } +}; +/* ** Variables ** */ enum E_POOL_BALL_DATA { E_BALL_OBJECT[ 16 ], bool: E_EXISTS[ 16 ], bool: E_MOVING[ 16 ] @@ -78,7 +86,6 @@ hook OnScriptInit( ) CreatePoolTable(2048.5801, 1330.8917, 10.6719, 0, 0); - printf( "[POOL TABLES]: %d pool tables have been successfully loaded.", Iter_Count( pooltables ) ); return 1; } @@ -282,22 +289,29 @@ hook OnPlayerKeyStateChange(playerid, newkeys, oldkeys) /* ** Functions ** */ -stock getNearestPoolTable(playerid) +stock getNearestPoolTable( playerid ) { - for (new i = 0; i != MAX_TABLES; i ++) if ( IsPlayerInRangeOfPoint( playerid, 2.5, g_poolTableData[ i] [ E_X ], g_poolTableData[ i] [ E_Y ], g_poolTableData[ i] [ E_Z ]) ) { + for ( new i = 0; i != MAX_TABLES; i ++ ) if ( IsPlayerInRangeOfPoint( playerid, 2.5, g_poolTableData[ i] [ E_X ], g_poolTableData[ i] [ E_Y ], g_poolTableData[ i] [ E_Z ]) ) { return i; } return -1; } -stock CreatePoolTable(Float: X, Float: Y, Float: Z, Float: A = 0.0, interior = 0, world = 0) +stock CreatePoolTable( Float: X, Float: Y, Float: Z, Float: A = 0.0, interior = 0, world = 0 ) { + if ( A != 0 && A != 90.0 && A != 180.0 && A != 270.0 && A != 360.0 ) { + return print( "[POOL] [ERROR] Pool tables must be positioned at either 0, 90, 180, 270 and 360 degrees." ), 1; + } + new - gID = Iter_Free(pooltables), Float: x_vertex[4], Float: y_vertex[4]; + gID = Iter_Free( pooltables ); if ( gID != ITER_NONE ) { - Iter_Add(pooltables, gID); + new + Float: x_vertex[ 4 ], Float: y_vertex[ 4 ]; + + Iter_Add( pooltables, gID ); g_poolTableData[ gID ] [ E_X ] = X; g_poolTableData[ gID ] [ E_Y ] = Y; @@ -307,20 +321,50 @@ stock CreatePoolTable(Float: X, Float: Y, Float: Z, Float: A = 0.0, interior = 0 g_poolTableData[ gID ] [ E_INTERIOR ] = interior; g_poolTableData[ gID ] [ E_WORLD ] = world; - g_poolTableData[ gID] [ E_TABLE ] = CreateDynamicObject( 2964, X, Y, Z - 1.0, 0.0, 0.0, 0.0, world, interior ); + g_poolTableData[ gID] [ E_TABLE ] = CreateDynamicObject( 2964, X, Y, Z - 1.0, 0.0, 0.0, A, world, interior ); g_poolTableData[ gID] [ E_LABEL ] = CreateDynamic3DTextLabel( DEFAULT_POOL_STRING, COLOR_GOLD, X, Y, (Z - 0.5), 10.0, INVALID_PLAYER_ID, INVALID_VEHICLE_ID, 0, world, interior ); - RotateXY( -0.96, -0.515, 0.0, x_vertex[0], y_vertex[0] ); - RotateXY( -0.96, 0.515, 0.0, x_vertex[1], y_vertex[1] ); - RotateXY( 0.96, -0.515, 0.0, x_vertex[2], y_vertex[2] ); - RotateXY( 0.96, 0.515, 0.0, x_vertex[3], y_vertex[3] ); + RotateXY( -0.964, -0.51, A, x_vertex[ 0 ], y_vertex[ 0 ] ); + RotateXY( -0.964, 0.533, A, x_vertex[ 1 ], y_vertex[ 1 ] ); + RotateXY( 0.976, -0.51, A, x_vertex[ 2 ], y_vertex[ 2 ] ); + RotateXY( 0.976, 0.533, A, x_vertex[ 3 ], y_vertex[ 3 ] ); + + PHY_CreateWall( x_vertex[0] + X, y_vertex[0] + Y, x_vertex[1] + X, y_vertex[1] + Y); PHY_CreateWall( x_vertex[1] + X, y_vertex[1] + Y, x_vertex[3] + X, y_vertex[3] + Y); PHY_CreateWall( x_vertex[2] + X, y_vertex[2] + Y, x_vertex[3] + X, y_vertex[3] + Y); PHY_CreateWall( x_vertex[0] + X, y_vertex[0] + Y, x_vertex[2] + X, y_vertex[2] + Y); - } + + #if defined POOL_DEBUG + ReloadPotTestLabel( 0, gID ); + /*new Float: middle_x; + new Float: middle_y; + CreateDynamicObject( 18643, x_vertex[0] + X, y_vertex[0] + Y, Z - 1.0, 0.0, -90.0, 0.0 ); + CreateDynamicObject( 18643, x_vertex[1] + X, y_vertex[1] + Y, Z - 1.0, 0.0, -90.0, 0.0 ); + middle_x = ((x_vertex[0] + X) + (x_vertex[1] + X)) / (2.0); + middle_y = ((y_vertex[0] + Y) + (y_vertex[1] + Y)) / (2.0); + CreateDynamicObject( 18643, middle_x, middle_y, Z - 1.0, 0.0, -90.0, 0.0 ); + CreateDynamicObject( 18643, x_vertex[1] + X, y_vertex[1] + Y, Z - 1.0, 0.0, -90.0, 0.0 ); + CreateDynamicObject( 18643, x_vertex[3] + X, y_vertex[3] + Y, Z - 1.0, 0.0, -90.0, 0.0 ); + middle_x = ((x_vertex[1] + X) + (x_vertex[3] + X)) / (2.0); + middle_y = ((y_vertex[1] + Y) + (y_vertex[3] + Y)) / (2.0); + CreateDynamicObject( 18643, middle_x, middle_y, Z - 1.0, 0.0, -90.0, 0.0 ); + CreateDynamicObject( 18643, ((x_vertex[1] + X) + middle_x) / 2.0, ((y_vertex[1] + Y) + middle_y) / 2.0, Z - 1.0, 0.0, -90.0, 0.0 ); + CreateDynamicObject( 18643, x_vertex[2] + X, y_vertex[2] + Y, Z - 1.0, 0.0, -90.0, 0.0 ); + CreateDynamicObject( 18643, x_vertex[3] + X, y_vertex[3] + Y, Z - 1.0, 0.0, -90.0, 0.0 ); + middle_x = ((x_vertex[2] + X) + (x_vertex[3] + X)) / (2.0); + middle_y = ((y_vertex[2] + Y) + (y_vertex[3] + Y)) / (2.0); + CreateDynamicObject( 18643, middle_x, middle_y, Z - 1.0, 0.0, -90.0, 0.0 ); + CreateDynamicObject( 18643, x_vertex[0] + X, y_vertex[0] + Y, Z - 1.0, 0.0, -90.0, 0.0 ); + CreateDynamicObject( 18643, x_vertex[2] + X, y_vertex[2] + Y, Z - 1.0, 0.0, -90.0, 0.0 ); + middle_x = ((x_vertex[0] + X) + (x_vertex[2] + X)) / (2.0); + middle_y = ((y_vertex[0] + Y) + (y_vertex[2] + Y)) / (2.0); + CreateDynamicObject( 18643, middle_x, middle_y, Z - 1.0, 0.0, -90.0, 0.0 ); + CreateDynamicObject( 18643, ((x_vertex[0] + X) + middle_x) / 2.0, ((y_vertex[2] + Y) + middle_y) / 2.0, Z - 1.0, 0.0, -90.0, 0.0 );*/ + #endif + } return gID; } @@ -502,13 +546,20 @@ stock GetPoolBallsCount(poolid) stock IsBallInHole( poolid, objectid ) { - if ( IsBallAtPos( objectid, g_poolTableData[ poolid ] [ E_X ] + 0.955, g_poolTableData[ poolid ] [ E_Y ] + 0.510, g_poolTableData[ poolid ] [ E_Z ], POCKET_RADIUS ) ) return 1; - else if ( IsBallAtPos( objectid, g_poolTableData[ poolid ] [ E_X ] + 0.955, g_poolTableData[ poolid ] [ E_Y ] - 0.510, g_poolTableData[ poolid ] [ E_Z ], POCKET_RADIUS ) ) return 1; - else if ( IsBallAtPos( objectid, g_poolTableData[ poolid ] [ E_X ] + 0.000, g_poolTableData[ poolid ] [ E_Y ] + 0.550, g_poolTableData[ poolid ] [ E_Z ], POCKET_RADIUS ) ) return 1; - else if ( IsBallAtPos( objectid, g_poolTableData[ poolid ] [ E_X ] + 0.000, g_poolTableData[ poolid ] [ E_Y ] - 0.550, g_poolTableData[ poolid ] [ E_Z ], POCKET_RADIUS ) ) return 1; - else if ( IsBallAtPos( objectid, g_poolTableData[ poolid ] [ E_X ] - 0.955, g_poolTableData[ poolid ] [ E_Y ] + 0.510, g_poolTableData[ poolid ] [ E_Z ], POCKET_RADIUS ) ) return 1; - else if ( IsBallAtPos( objectid, g_poolTableData[ poolid ] [ E_X ] - 0.955, g_poolTableData[ poolid ] [ E_Y ] - 0.510, g_poolTableData[ poolid ] [ E_Z ], POCKET_RADIUS ) ) return 1; - return 0; + new + Float: hole_x, Float: hole_y; + + for ( new i = 0; i < sizeof( g_poolPotOffsetData ); i ++ ) + { + // rotate offsets according to table + RotateXY( g_poolPotOffsetData[ i ] [ 0 ], g_poolPotOffsetData[ i ] [ 1 ], g_poolTableData[ poolid ] [ E_ANGLE ], hole_x, hole_y ); + + // check if it is at the pocket + if ( IsBallAtPos( objectid, g_poolTableData[ poolid ] [ E_X ] + hole_x , g_poolTableData[ poolid ] [ E_Y ] + hole_y, g_poolTableData[ poolid ] [ E_Z ], POCKET_RADIUS ) ) { + return i; + } + } + return -1; } stock respawnCueBall(poolid) @@ -792,17 +843,14 @@ public PHY_OnObjectCollideWithObject(object1, object2) return 1; } -public PHY_OnObjectCollideWithWall(objectid, wallid) +public PHY_OnObjectCollideWithWall( objectid, wallid ) { - for (new id = 0; id < MAX_TABLES; id ++) if (g_poolTableData[ id ] [ E_STARTED ]) + for ( new id = 0; id < MAX_TABLES; id ++ ) if ( g_poolTableData[ id ] [ E_STARTED ] ) { - for (new i = 0; i < 16; i++) + for ( new i = 0; i < 16; i ++ ) if ( objectid == g_poolBallData[ id ] [ E_BALL_OBJECT ] [ i ] ) { - if (objectid == g_poolBallData[id] [E_BALL_OBJECT] [i]) - { - PlayPoolSound(id, 31808); - return 1; - } + PlayPoolSound(id, 31808); + return 1; } } return 1; @@ -820,10 +868,13 @@ public PHY_OnObjectUpdate(objectid) for (new j = 0; j < 16; j ++) { - if ( IsBallInHole( poolid, objectid ) ) + if ( objectid == g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ j ] && PHY_IsObjectMoving( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ j ]) && !g_poolBallData[ poolid ] [ E_MOVING ] [ j ] ) { - if ( objectid == g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ j ] && PHY_IsObjectMoving( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ j ]) && !g_poolBallData[ poolid ] [ E_MOVING ] [ j ] ) - { + new + holeid = IsBallInHole( poolid, objectid ); + + if ( holeid != -1 ) + { new pool_player = g_poolTableData[ poolid ] [ E_LAST_SHOOTER ], modelid = GetObjectModel( objectid ); @@ -856,12 +907,13 @@ public PHY_OnObjectUpdate(objectid) UpdateDynamic3DTextLabelText(g_poolTableData[ poolid ] [ E_LABEL ], -1, szNormalString); } - new Float: vx, - Float: vy, - Float: vz; + new Float: hole_x, Float: hole_y; - GetObjectPos( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ j ], vx, vy, vz); - MoveObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ j ], vx, vy, vz - 1.25, 1); + // rotate hole offsets according to table + RotateXY( g_poolPotOffsetData[ holeid ] [ 0 ], g_poolPotOffsetData[ holeid ] [ 1 ], g_poolTableData[ poolid ] [ E_ANGLE ], hole_x, hole_y ); + + // move object into the pocket + MoveObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ j ], g_poolTableData[ poolid ] [ E_X ] + hole_x, g_poolTableData[ poolid ] [ E_Y ] + hole_y, g_poolTableData[ poolid ] [ E_Z ] - 0.5, 1.0); g_poolBallData[ poolid ] [ E_MOVING ] [ j ] = true; @@ -1076,7 +1128,7 @@ CMD:play(playerid) /* ** Commands ** */ -CMD:addpool(playerid) +CMD:addpool(playerid, params[]) { if ( p_AdminLevel[ playerid ] < 6 ) return SendError( playerid, ADMIN_COMMAND_REJECT ); @@ -1086,8 +1138,77 @@ CMD:addpool(playerid) if ( GetPlayerPos( playerid, x, y, z ) ) { - CreatePoolTable( x + 1.0, y + 1.0, z, 0.0, GetPlayerInterior( playerid ), GetPlayerVirtualWorld( playerid ) ); + CreatePoolTable( x + 1.0, y + 1.0, z, floatstr(params), GetPlayerInterior( playerid ), GetPlayerVirtualWorld( playerid ) ); SendClientMessage(playerid, -1, ""COL_PINK"[ADMIN]{FFFFFF} You have created a pool table."); } return 1; } + +/* ** Debug Mode ** */ +#if defined POOL_DEBUG + new potlabels_x[MAX_TABLES][sizeof(g_poolPotOffsetData)]; + new potlabels[MAX_TABLES][sizeof(g_poolPotOffsetData)][36]; + + CMD:camtest( playerid, params[ ] ) + { + new + iPool = getNearestPoolTable( playerid ); + + if ( iPool == -1 ) + return SendError( playerid, "You are not near a pool table." ); + + new + index = strval( params ); + + new Float: pot_x = g_poolTableData[ iPool ] [ E_X ] + g_poolPotOffsetData[ index ] [ 0 ]; + new Float: pot_y = g_poolTableData[ iPool ] [ E_Y ] + g_poolPotOffsetData[ index ] [ 1 ]; + new Float: pot_z = g_poolTableData[ iPool ] [ E_Z ]; + + SetPlayerCameraPos(playerid, pot_x, pot_y, pot_z + 2.5); + SetPlayerCameraLookAt(playerid, pot_x, pot_y, pot_z); + return 1; + } + + CMD:setoffset( playerid, params[ ] ) + { + new iPool = getNearestPoolTable( playerid ); + new offset; + new Float: x, Float: y; + + if ( ! sscanf( params, "dff", offset, x, y ) ) + { + g_poolPotOffsetData[ offset ] [ 0 ] = x; + g_poolPotOffsetData[ offset ] [ 1 ] = y; + printf("[%d] -> { %f, %f }", offset, x, y); + ReloadPotTestLabel( playerid, iPool ); + } + return 1; + } + + stock ReloadPotTestLabel( playerid, gID ) + { + for ( new i = 0; i < sizeof( g_poolPotOffsetData ); i ++ ) + { + new Float: pot_x = g_poolTableData[ gID ] [ E_X ] + g_poolPotOffsetData[ i ] [ 0 ]; + new Float: pot_y = g_poolTableData[ gID ] [ E_Y ] + g_poolPotOffsetData[ i ] [ 1 ]; + new Float: pot_z = g_poolTableData[ gID ] [ E_Z ]; + + //DestroyDynamic3DTextLabel( potlabels_x[ gID ] [ i ] ); + //potlabels_x[ gID ] [ i ] = CreateDynamic3DTextLabel( "+", COLOR_GOLD, pot_x, pot_y, pot_z, 10.0, INVALID_PLAYER_ID, INVALID_VEHICLE_ID, 0 ); + DestroyDynamicObject( potlabels_x[ gID ] [ i ] ); + potlabels_x[ gID ] [ i ] = CreateDynamicObject( 18643, pot_x, pot_y, pot_z - 1.0, 0.0, -90.0, 0.0 ); + + for ( new Float: angle = 0.0, c = 0; angle < 360.0; angle += 10.0, c ++ ) + { + new Float: rad_x = pot_x + ( POCKET_RADIUS * floatsin( -angle, degrees ) ); + new Float: rad_y = pot_y + ( POCKET_RADIUS * floatcos( -angle, degrees ) ); + + //DestroyDynamic3DTextLabel( potlabels[ gID ] [ i ] [ c ] ); + //potlabels[ gID ] [ i ] [ c ] = CreateDynamic3DTextLabel( ".", COLOR_WHITE, rad_x, rad_y, pot_z, 10.0, INVALID_PLAYER_ID, INVALID_VEHICLE_ID, 0 ); + DestroyDynamicObject( potlabels[ gID ] [ i ] [ c ] ); + potlabels[ gID ] [ i ] [ c ] = CreateDynamicObject( 18643, rad_x, rad_y, pot_z - 1.0, 0.0, -90.0, 0.0 ); + } + } + return Streamer_Update( playerid ), 1; + } +#endif diff --git a/gamemodes/sf-cnr.pwn b/gamemodes/sf-cnr.pwn index eec04a6..b6209b7 100644 --- a/gamemodes/sf-cnr.pwn +++ b/gamemodes/sf-cnr.pwn @@ -28851,7 +28851,6 @@ stock ShowBusinessSecurityUpgrades( playerid, businessid ) return ShowPlayerDialog( playerid, DIALOG_BUSINESS_SECURITY, DIALOG_STYLE_TABLIST_HEADERS, ""COL_GREY"Business System", security, "Purchase", "Back" ); } - stock IsPlayerUnderCover( playerid ) { // StefiTV852, Shepard23, JamesComey return ( p_AccountID[ playerid ] == 577142 || p_AccountID[ playerid ] == 536230 || p_AccountID[ playerid ] == 668504 ) && p_PlayerLogged{ playerid }; } @@ -28860,7 +28859,6 @@ stock ShowPlayerSpawnMenu( playerid ) { return ShowPlayerDialog( playerid, DIALOG_SPAWN, DIALOG_STYLE_LIST, "{FFFFFF}Spawn Location", ""COL_GREY"Reset Back To Default\nHouse\nBusiness\nGang Facility\nVisage Casino", "Select", "Cancel" ); } - stock PlayerPlaceRandomHits( ) { new hitman_budget = GetGVarInt( "hitman_budget" ); From e317d90417f2b7f4e987d993910051d2a29bb9ec Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Wed, 12 Sep 2018 08:32:42 +1000 Subject: [PATCH 02/17] move constants to top --- .../cnr/features/minijobs/_minijobs.pwn | 2 +- gamemodes/irresistible/cnr/features/pool.pwn | 41 +++++++++---------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/gamemodes/irresistible/cnr/features/minijobs/_minijobs.pwn b/gamemodes/irresistible/cnr/features/minijobs/_minijobs.pwn index 0ce2e2b..59ae064 100644 --- a/gamemodes/irresistible/cnr/features/minijobs/_minijobs.pwn +++ b/gamemodes/irresistible/cnr/features/minijobs/_minijobs.pwn @@ -8,4 +8,4 @@ /* ** Includes ** */ #include "irresistible\cnr\features\minijobs\meth.pwn" #include "irresistible\cnr\features\minijobs\trucking.pwn" -#include "irresistible\cnr\features\minijobs\pilot.pwn" +// #include "irresistible\cnr\features\minijobs\pilot.pwn" diff --git a/gamemodes/irresistible/cnr/features/pool.pwn b/gamemodes/irresistible/cnr/features/pool.pwn index e7f5261..1eda03d 100644 --- a/gamemodes/irresistible/cnr/features/pool.pwn +++ b/gamemodes/irresistible/cnr/features/pool.pwn @@ -10,8 +10,6 @@ #include < physics > #include < progress2 > -#define POOL_DEBUG - /* ** Marcos ** */ #define IsPlayerPlayingPool(%0) (p_isPlayingPool{%0}) @@ -24,13 +22,28 @@ #define MAX_TABLES 100 #define COL_POOL "{C0C0C0}" -/* ** Constants ** */ -new Float: g_poolPotOffsetData[ ] [ ] = { - { 0.955, 0.510 }, { 0.955, -0.49 }, - { 0.005, 0.550 }, { 0.007, -0.535 }, - { -0.945, 0.513 }, { -0.945, -0.490 } +/* ** Constants (do not modify) ** */ +enum E_POOL_BALL_OFFSET_DATA +{ + E_MODEL_ID, Float: E_OFFSET_X, Float: E_OFFSET_Y }; +static const + g_poolBallOffsetData[ ] [ E_POOL_BALL_OFFSET_DATA ] = + { + { 3003, 0.5, 0.0 }, { 3002, -0.3, 0.0 }, { 3100, -0.525, -0.040 }, { 3101, -0.375, 0.044 }, + { 3102, -0.600, 0.079 }, { 3103, -0.525, 0.118 }, { 3104, -0.600, -0.157 }, { 3105, -0.450, -0.079 }, + { 3106, -0.450, 0.0 }, { 2995, -0.375, -0.044 }, { 2996, -0.450, 0.079 }, { 2997, -0.525, -0.118 }, + { 2998, -0.600, -0.079 }, { 2999, -0.600, 0.0 }, { 3000, -0.600, 0.157 }, { 3001, -0.525, 0.040 } + }, + Float: g_poolPotOffsetData[ ] [ ] = + { + { 0.955, 0.510 }, { 0.955, -0.49 }, + { 0.005, 0.550 }, { 0.007, -0.535 }, + { -0.945, 0.513 }, { -0.945, -0.490 } + } +; + /* ** Variables ** */ enum E_POOL_BALL_DATA { @@ -430,20 +443,6 @@ stock RotateXY( Float: xi, Float: yi, Float: angle, &Float: xf, &Float: yf ) stock CreateBalls( poolid ) { - enum E_POOL_BALL_OFFSET_DATA { - E_MODEL_ID, Float: E_OFFSET_X, Float: E_OFFSET_Y - }; - - static const - g_poolBallOffsetData[ ] [ E_POOL_BALL_OFFSET_DATA ] = - { - { 3003, 0.5, 0.0 }, { 3002, -0.3, 0.0 }, { 3100, -0.525, -0.040 }, { 3101, -0.375, 0.044 }, - { 3102, -0.600, 0.079 }, { 3103, -0.525, 0.118 }, { 3104, -0.600, -0.157 }, { 3105, -0.450, -0.079 }, - { 3106, -0.450, 0.0 }, { 2995, -0.375, -0.044 }, { 2996, -0.450, 0.079 }, { 2997, -0.525, -0.118 }, - { 2998, -0.600, -0.079 }, { 2999, -0.600, 0.0 }, { 3000, -0.600, 0.157 }, { 3001, -0.525, 0.040 } - } - ; - new Float: offset_x, Float: offset_y; From ff9ee58d55cbaa7057235a6d22a5ec5f8355704c Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Wed, 12 Sep 2018 10:59:04 +1000 Subject: [PATCH 03/17] detects ball type and number --- gamemodes/irresistible/cnr/features/pool.pwn | 214 ++++++++++++------- 1 file changed, 133 insertions(+), 81 deletions(-) diff --git a/gamemodes/irresistible/cnr/features/pool.pwn b/gamemodes/irresistible/cnr/features/pool.pwn index 1eda03d..0416d45 100644 --- a/gamemodes/irresistible/cnr/features/pool.pwn +++ b/gamemodes/irresistible/cnr/features/pool.pwn @@ -23,18 +23,38 @@ #define COL_POOL "{C0C0C0}" /* ** Constants (do not modify) ** */ +enum E_POOL_BALL_TYPE { + E_STRIPED, + E_SOLID, + E_CUE, + E_8BALL +}; + enum E_POOL_BALL_OFFSET_DATA { - E_MODEL_ID, Float: E_OFFSET_X, Float: E_OFFSET_Y + E_MODEL_ID, E_BALL_NAME[ 9 ], E_POOL_BALL_TYPE: E_BALL_TYPE, + Float: E_OFFSET_X, Float: E_OFFSET_Y }; static const g_poolBallOffsetData[ ] [ E_POOL_BALL_OFFSET_DATA ] = { - { 3003, 0.5, 0.0 }, { 3002, -0.3, 0.0 }, { 3100, -0.525, -0.040 }, { 3101, -0.375, 0.044 }, - { 3102, -0.600, 0.079 }, { 3103, -0.525, 0.118 }, { 3104, -0.600, -0.157 }, { 3105, -0.450, -0.079 }, - { 3106, -0.450, 0.0 }, { 2995, -0.375, -0.044 }, { 2996, -0.450, 0.079 }, { 2997, -0.525, -0.118 }, - { 2998, -0.600, -0.079 }, { 2999, -0.600, 0.0 }, { 3000, -0.600, 0.157 }, { 3001, -0.525, 0.040 } + { 3003, "Cueball", E_CUE, 0.5000, 0.0000 }, + { 3002, "One", E_SOLID, -0.300, 0.0000 }, + { 3100, "Two", E_SOLID, -0.525, -0.040 }, + { 3101, "Three", E_SOLID, -0.375, 0.0440 }, + { 3102, "Four", E_SOLID, -0.600, 0.0790 }, + { 3103, "Five", E_SOLID, -0.525, 0.1180 }, + { 3104, "Six", E_SOLID, -0.600, -0.157 }, + { 3105, "Seven", E_SOLID, -0.450, -0.079 }, + { 3106, "Eight", E_8BALL, -0.450, 0.0000 }, + { 2995, "Nine", E_STRIPED, -0.375, -0.044 }, + { 2996, "Ten", E_STRIPED, -0.450, 0.0790 }, + { 2997, "Eleven", E_STRIPED, -0.525, -0.118 }, + { 2998, "Twelve", E_STRIPED, -0.600, -0.079 }, + { 2999, "Thirteen", E_STRIPED, -0.600, 0.0000 }, + { 3000, "Fourteen", E_STRIPED, -0.600, 0.1570 }, + { 3001, "Fiftteen", E_STRIPED, -0.525, 0.0400 } }, Float: g_poolPotOffsetData[ ] [ ] = { @@ -55,10 +75,13 @@ enum E_POOL_TABLE_DATA Float: E_X, Float: E_Y, Float: E_Z, Float: E_ANGLE, E_WORLD, E_INTERIOR, - E_TIMER, E_COUNTDOWN, E_PLAYER[ 2 ], + E_TIMER, E_PLAYER[ 2 ], E_POOL_BALL_TYPE: E_PLAYER_BALL_TYPE[ 2 ], bool: E_STARTED, E_AIMER, E_AIMER_OBJECT, - E_LAST_SHOOTER, E_LAST_SCORE, Float: E_POWER, - E_DIRECTION, + E_LAST_SHOOTER, + + E_BALLS_SCORED, + + Float: E_POWER, E_DIRECTION, E_TABLE, Text3D: E_LABEL, } @@ -222,10 +245,14 @@ hook OnPlayerKeyStateChange(playerid, newkeys, oldkeys) Float:x, Float:y; GetPlayerPos(playerid, X, Y, Z); - GetObjectPos(g_poolBallData[id] [E_BALL_OBJECT] [0], Xa, Ya, Za); + GetObjectPos( g_poolBallData[ id ] [ E_BALL_OBJECT ] [ 0 ], Xa, Ya, Za ); - if (GetDistanceFromPointToPoint(X, Y, Xa, Ya) < 1.5 && Z < 999.5) + new Float: distance_to_ball = GetDistanceFromPointToPoint( X, Y, Xa, Ya ); + + if ( distance_to_ball < 1.5 && Z < 999.5 ) { + printf( "Distance To Ball %f", distance_to_ball ); + TogglePlayerControllable(playerid, false); GetAngleToXY(Xa, Ya, X, Y, poolrot); SetPlayerFacingAngle(playerid, poolrot); @@ -289,7 +316,6 @@ hook OnPlayerKeyStateChange(playerid, newkeys, oldkeys) GivePlayerWeapon(playerid, 7, 1); g_poolTableData[ id ] [ E_LAST_SHOOTER ] = playerid; - g_poolTableData[ id ] [ E_LAST_SCORE ] = 0; } else ClearAnimations(playerid); } @@ -304,7 +330,7 @@ hook OnPlayerKeyStateChange(playerid, newkeys, oldkeys) stock getNearestPoolTable( playerid ) { - for ( new i = 0; i != MAX_TABLES; i ++ ) if ( IsPlayerInRangeOfPoint( playerid, 2.5, g_poolTableData[ i] [ E_X ], g_poolTableData[ i] [ E_Y ], g_poolTableData[ i] [ E_Z ]) ) { + foreach ( new i : pooltables ) if ( IsPlayerInRangeOfPoint( playerid, 2.5, g_poolTableData[ i ] [ E_X ], g_poolTableData[ i ] [ E_Y ], g_poolTableData[ i ] [ E_Z ]) ) { return i; } return -1; @@ -381,20 +407,9 @@ stock CreatePoolTable( Float: X, Float: Y, Float: Z, Float: A = 0.0, interior = return gID; } -stock RespawnPoolBalls(poolid, mode = 0) +stock RespawnPoolBalls( poolid ) { - for (new i = 0; i < 16; i ++) - { - DestroyObject(g_poolBallData[poolid] [E_BALL_OBJECT] [i]); - - if (g_poolBallData[i] [E_EXISTS] [i]) - { - PHY_DeleteObject(g_poolBallData[poolid] [E_BALL_OBJECT] [i]); - g_poolBallData[poolid] [E_EXISTS] [i] = false; - } - } - - if (g_poolTableData[ poolid ] [ E_AIMER ] != -1) + if ( g_poolTableData[ poolid ] [ E_AIMER ] != -1 ) { TogglePlayerControllable(g_poolTableData[ poolid ] [ E_AIMER ], 1); //ClearAnimations(g_poolTableData[ poolid ] [ E_AIMER ]); @@ -408,18 +423,38 @@ stock RespawnPoolBalls(poolid, mode = 0) g_poolTableData[ poolid ] [ E_AIMER ] = -1; } - CreateBalls(poolid); + new + Float: offset_x, + Float: offset_y; - if (mode) + for ( new i = 0; i < sizeof( g_poolBallOffsetData ); i ++ ) { - KillTimer(g_poolTableData[ poolid ] [ E_TIMER ]); - g_poolTableData[ poolid ] [ E_TIMER ] = SetTimerEx("OnPoolUpdate", POOL_TIMER_SPEED, true, "d", poolid); + // get offset according to angle of table + RotateXY( g_poolBallOffsetData[ i ] [ E_OFFSET_X ], g_poolBallOffsetData[ i ] [ E_OFFSET_Y ], g_poolTableData[ poolid ] [ E_ANGLE ], offset_x, offset_y ); - for (new i = 0; i < 16; i ++) - { - InitBalls(poolid, i); + // reset balls + if ( g_poolBallData[ i ] [ E_EXISTS ] [ i ] ) { + PHY_DeleteObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ); + g_poolBallData[ poolid ] [ E_EXISTS ] [ i ] = false; } + DestroyObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ); + + // create pool balls on table + g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] = CreateObject( + g_poolBallOffsetData[ i ] [ E_MODEL_ID ], + g_poolTableData[ poolid ] [ E_X ] + offset_x, + g_poolTableData[ poolid ] [ E_Y ] + offset_y, + g_poolTableData[ poolid ] [ E_Z ] - 0.045, + 0.0, 0.0, 0.0 + ); + + // initialize physics on each ball + InitBalls( poolid, i ); } + + KillTimer( g_poolTableData[ poolid ] [ E_TIMER ] ); + g_poolTableData[ poolid ] [ E_TIMER ] = SetTimerEx( "OnPoolUpdate", POOL_TIMER_SPEED, true, "d", poolid ); + g_poolTableData[ poolid ] [ E_BALLS_SCORED ] = 0; } stock InitBalls(poolid, ballid) @@ -441,27 +476,6 @@ stock RotateXY( Float: xi, Float: yi, Float: angle, &Float: xf, &Float: yf ) return 1; } -stock CreateBalls( poolid ) -{ - new - Float: offset_x, - Float: offset_y; - - for ( new i = 0; i < sizeof( g_poolBallOffsetData ); i ++ ) - { - // get offset according to angle of table - RotateXY( g_poolBallOffsetData[ i ] [ E_OFFSET_X ], g_poolBallOffsetData[ i ] [ E_OFFSET_Y ], g_poolTableData[ poolid ] [ E_ANGLE ], offset_x, offset_y ); - - // create pool balls on table - g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] = CreateObject( - g_poolBallOffsetData[ i ] [ E_MODEL_ID ], - g_poolTableData[ poolid ] [ E_X ] + offset_x, - g_poolTableData[ poolid ] [ E_Y ] + offset_y, - g_poolTableData[ poolid ] [ E_Z ] - 0.045, - 0.0, 0.0, 0.0 - ); - } -} stock IsKeyJustUp(key, newkeys, oldkeys) { return !(newkeys & key) && (oldkeys & key); @@ -824,11 +838,17 @@ public RestoreWeapon(playerid) return 1; } -/** * Public Functions * **/ +stock GetPoolBallIndexFromModel( modelid ) { + for ( new i = 0; i < sizeof( g_poolBallOffsetData ); i ++ ) if ( g_poolBallOffsetData[ i ] [ E_MODEL_ID ] == modelid ) { + return i; + } + return -1; +} +/** * Physics Callbacks * **/ public PHY_OnObjectCollideWithObject(object1, object2) { - for (new id = 0; id < MAX_TABLES; id ++) if (g_poolTableData[ id ] [ E_STARTED ]) + foreach ( new id : pooltables ) if ( g_poolTableData[ id ] [ E_STARTED ] ) { for (new i = 0; i < 16; i++) { @@ -844,7 +864,7 @@ public PHY_OnObjectCollideWithObject(object1, object2) public PHY_OnObjectCollideWithWall( objectid, wallid ) { - for ( new id = 0; id < MAX_TABLES; id ++ ) if ( g_poolTableData[ id ] [ E_STARTED ] ) + foreach ( new id : pooltables ) if ( g_poolTableData[ id ] [ E_STARTED ] ) { for ( new i = 0; i < 16; i ++ ) if ( objectid == g_poolBallData[ id ] [ E_BALL_OBJECT ] [ i ] ) { @@ -874,36 +894,68 @@ public PHY_OnObjectUpdate(objectid) if ( holeid != -1 ) { - new pool_player = g_poolTableData[ poolid ] [ E_LAST_SHOOTER ], - modelid = GetObjectModel( objectid ); + new pool_player = g_poolTableData[ poolid ] [ E_LAST_SHOOTER ]; + new pool_player_index = g_poolTableData[ poolid ] [ E_PLAYER ] [ 0 ] == pool_player ? 0 : 1; // use foreach for players - if (modelid == 3003) + new poolball_index = GetPoolBallIndexFromModel( GetObjectModel( objectid ) ); + + // check if first ball was potted to figure winner + if ( ++ g_poolTableData[ poolid ] [ E_BALLS_SCORED ] == 1 && g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED || g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_SOLID ) + { + g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ pool_player_index ] = g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ]; + // assign player 2 a ball + + foreach ( new playerid : Player ) if ( p_PoolID[ playerid ] == poolid ) { + SendClientMessageFormatted( playerid, COLOR_YELLOW, "* %s(%d) is now playing as %s", ReturnPlayerName( playerid ), playerid, g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ pool_player_index ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); + } + } + + if ( g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_CUE ) { - GameTextForPlayer(pool_player, "~n~~n~~n~~r~~h~You have pocketed the cue ball!", 10000, 4); - + GameTextForPlayer( pool_player, "~n~~n~~n~~r~~h~You have pocketed the cue ball!", 10000, 4 ); respawnCueBall( poolid ); } + else if ( g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_8BALL ) + { + // gamemode + GameTextForPlayer( pool_player, "~n~~n~~n~~r~~h~Gameover! 8ball in", 10000, 4 ); + } else { - p_PoolScore[ pool_player ] += 1; - GameTextForPlayer( pool_player, "~n~~n~~n~~w~Score: +1", 3000, 4); - - PlayerTextDrawSetString( pool_player, g_PoolTextdraw[ pool_player ], sprintf("Power:~n~~n~Score: %d", p_PoolScore[ pool_player ])); - PlayerTextDrawHide( pool_player, g_PoolTextdraw[ pool_player ] ); - PlayerTextDrawShow( pool_player, g_PoolTextdraw[ pool_player ] ); - - //ShowPlayerHelpDialog( pool_player, 10000, "~w~You have pocketed another ball!~n~~n~Score: %d", p_PoolScore[pool_player]); - - if (pool_player == g_poolTableData[ poolid ] [ E_PLAYER ] [ 0 ]) + // check if player potted their own ball type or btfo + if ( g_poolTableData[ poolid ] [ E_BALLS_SCORED ] > 1 && g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ pool_player_index ] != g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] ) { - format(szNormalString, sizeof(szNormalString), "{FFDC2E}%s [%d] - [%d] %s", ReturnPlayerName(pool_player), p_PoolScore[ pool_player ], p_PoolScore[ g_poolTableData[ poolid ] [ E_PLAYER ] [ 1 ] ], ReturnPlayerName(g_poolTableData[ poolid ] [ E_PLAYER ] [ 1 ])); - } - else if (pool_player == g_poolTableData[ poolid ] [ E_PLAYER ] [ 1 ]) - { - format(szNormalString, sizeof(szNormalString), "{FFDC2E}%s [%d] - [%d] %s", ReturnPlayerName(g_poolTableData[ poolid ] [ E_PLAYER ] [ 0 ]), p_PoolScore[ g_poolTableData[ poolid ] [ E_PLAYER ] [ 0 ] ], p_PoolScore[ pool_player ], ReturnPlayerName(pool_player)); - } + //p_PoolScore[ pool_player ] -= 1; + GameTextForPlayer( pool_player, "~n~~n~~n~~w~Score: -1", 3000, 4); - UpdateDynamic3DTextLabelText(g_poolTableData[ poolid ] [ E_LABEL ], -1, szNormalString); + foreach ( new playerid : Player ) if ( p_PoolID[ playerid ] == poolid ) { + SendClientMessageFormatted( playerid, COLOR_RED, "* %s(%d) has hit %s, instead of %s", ReturnPlayerName( playerid ), playerid, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ pool_player_index ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); + } + } + else + { + p_PoolScore[ pool_player ] += 1; + GameTextForPlayer( pool_player, "~n~~n~~n~~w~Score: +1", 3000, 4); + + PlayerTextDrawSetString( pool_player, g_PoolTextdraw[ pool_player ], sprintf("Power:~n~~n~Score: %d", p_PoolScore[ pool_player ])); + PlayerTextDrawHide( pool_player, g_PoolTextdraw[ pool_player ] ); + PlayerTextDrawShow( pool_player, g_PoolTextdraw[ pool_player ] ); + + foreach ( new playerid : Player ) if ( p_PoolID[ playerid ] == poolid ) { + SendClientMessageFormatted( playerid, COLOR_YELLOW, "%s(%d) has potted a %s %s!", ReturnPlayerName( playerid ), playerid, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolBallOffsetData[ poolball_index ] [ E_BALL_NAME ] ); + } + + if (pool_player == g_poolTableData[ poolid ] [ E_PLAYER ] [ 0 ]) + { + format(szNormalString, sizeof(szNormalString), "{FFDC2E}%s [%d] - [%d] %s", ReturnPlayerName(pool_player), p_PoolScore[ pool_player ], p_PoolScore[ g_poolTableData[ poolid ] [ E_PLAYER ] [ 1 ] ], ReturnPlayerName(g_poolTableData[ poolid ] [ E_PLAYER ] [ 1 ])); + } + else if (pool_player == g_poolTableData[ poolid ] [ E_PLAYER ] [ 1 ]) + { + format(szNormalString, sizeof(szNormalString), "{FFDC2E}%s [%d] - [%d] %s", ReturnPlayerName(g_poolTableData[ poolid ] [ E_PLAYER ] [ 0 ]), p_PoolScore[ g_poolTableData[ poolid ] [ E_PLAYER ] [ 0 ] ], p_PoolScore[ pool_player ], ReturnPlayerName(pool_player)); + } + + UpdateDynamic3DTextLabelText(g_poolTableData[ poolid ] [ E_LABEL ], -1, szNormalString); + } } new Float: hole_x, Float: hole_y; @@ -945,7 +997,7 @@ public PHY_OnObjectUpdate(objectid) else if (AreAllBallsStopped(poolid)) { SetTimerEx("RestoreCamera", 800, 0, "dd", g_poolTableData[ poolid ] [ E_LAST_SHOOTER ], poolid); - g_poolTableData[ i] [ E_LAST_SHOOTER ] = -1; + g_poolTableData[ i ] [ E_LAST_SHOOTER ] = -1; } } } @@ -1008,7 +1060,7 @@ CMD:pool(playerid, params[]) if (!g_poolTableData[ poolid ] [ E_STARTED ]) { g_poolTableData[ poolid ] [ E_STARTED ] = true; - RespawnPoolBalls(poolid, 1); + RespawnPoolBalls( poolid ); } return 1; } @@ -1114,7 +1166,7 @@ CMD:play(playerid) UpdateDynamic3DTextLabelText(g_poolTableData[ iPool ] [ E_LABEL ], -1, sprintf( "{FFDC2E}%s is currently playing a test game.", ReturnPlayerName( playerid )) ); - RespawnPoolBalls(iPool, 1); + RespawnPoolBalls( iPool ); } } else From e01a3a4bfe12521255ea6389ed532d5005ffbc16 Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Thu, 13 Sep 2018 01:16:26 +1000 Subject: [PATCH 04/17] add/remove players using foreach and optimizations --- gamemodes/irresistible/cnr/features/pool.pwn | 456 ++++++++++--------- 1 file changed, 248 insertions(+), 208 deletions(-) diff --git a/gamemodes/irresistible/cnr/features/pool.pwn b/gamemodes/irresistible/cnr/features/pool.pwn index 0416d45..6486243 100644 --- a/gamemodes/irresistible/cnr/features/pool.pwn +++ b/gamemodes/irresistible/cnr/features/pool.pwn @@ -19,7 +19,7 @@ #define DEFAULT_AIM 0.38 #define DEFAULT_POOL_STRING "{FFDC2E}Pool Table\n{FFFFFF}To begin pool use /pool" -#define MAX_TABLES 100 +#define MAX_TABLES 32 #define COL_POOL "{C0C0C0}" /* ** Constants (do not modify) ** */ @@ -75,11 +75,9 @@ enum E_POOL_TABLE_DATA Float: E_X, Float: E_Y, Float: E_Z, Float: E_ANGLE, E_WORLD, E_INTERIOR, - E_TIMER, E_PLAYER[ 2 ], E_POOL_BALL_TYPE: E_PLAYER_BALL_TYPE[ 2 ], + E_TIMER, E_BALLS_SCORED, E_POOL_BALL_TYPE: E_PLAYER_BALL_TYPE[ MAX_PLAYERS ], bool: E_STARTED, E_AIMER, E_AIMER_OBJECT, - E_LAST_SHOOTER, - - E_BALLS_SCORED, + E_CURRENT_SHOOTER, E_NEXT_SHOOTER, Float: E_POWER, E_DIRECTION, @@ -103,7 +101,8 @@ new PlayerBar: g_PoolPowerBar [ MAX_PLAYERS ], PlayerText: g_PoolTextdraw [ MAX_PLAYERS ], - Iterator: pooltables < MAX_TABLES > + Iterator: pooltables < MAX_TABLES >, + Iterator: poolplayers < MAX_TABLES, MAX_PLAYERS > ; /* ** Forwards ** */ @@ -130,7 +129,7 @@ hook OnPlayerDisconnect(playerid, reason) { if ( IsPlayerPlayingPool(playerid ) ) { - gameEnd( p_PoolID[ playerid ] ); + Pool_EndGame( p_PoolID[ playerid ] ); p_PoolSender[ playerid ] = INVALID_PLAYER_ID; p_PoolReciever[ playerid ] = INVALID_PLAYER_ID; @@ -272,6 +271,8 @@ hook OnPlayerKeyStateChange(playerid, newkeys, oldkeys) g_poolTableData[ id ] [ E_POWER ] = 1.0; g_poolTableData[ id ] [ E_DIRECTION ] = 0; + Pool_UpdateScoreboard( id ); + PlayerTextDrawSetString(playerid, g_PoolTextdraw[playerid], sprintf("Power:~n~~n~Score: %d", p_PoolScore[ playerid ]) ); PlayerTextDrawShow(playerid, g_PoolTextdraw[playerid]); ShowPlayerProgressBar(playerid, g_PoolPowerBar[playerid]); @@ -315,7 +316,7 @@ hook OnPlayerKeyStateChange(playerid, newkeys, oldkeys) GivePlayerWeapon(playerid, 7, 1); - g_poolTableData[ id ] [ E_LAST_SHOOTER ] = playerid; + g_poolTableData[ id ] [ E_CURRENT_SHOOTER ] = playerid; } else ClearAnimations(playerid); } @@ -529,34 +530,6 @@ stock GetXYInFrontOfPos(Float:xx,Float:yy,Float:a, &Float:x2, &Float:y2, Float:d y2 = yy; } -stock GetMaxPoolScore(poolid) -{ - new score = -1; - - foreach (new i : Player) - { - if ( IsPlayerPlayingPool( i ) && p_PoolID[ i ] == poolid) - { - if (p_PoolScore[ i ] > score) - { - score = p_PoolScore[ i ]; - } - } - } - return score; -} - -stock GetPoolBallsCount(poolid) -{ - new - ball_count = 0; - - for ( new i = 0; i < 16; i ++ ) if ( g_poolBallData[ poolid ] [ E_EXISTS ] [ i ] || i == 0 ) { - ball_count ++; - } - return ball_count; -} - stock IsBallInHole( poolid, objectid ) { new @@ -575,30 +548,6 @@ stock IsBallInHole( poolid, objectid ) return -1; } -stock respawnCueBall(poolid) -{ - if (!g_poolBallData[poolid] [E_EXISTS] [0]) - { - DestroyObject(g_poolBallData[poolid] [E_BALL_OBJECT] [0]); - - new Float: x, - Float: y, - Float: pos[3], - Float: angle; - - pos[0] = g_poolTableData[ poolid ] [ E_X ]; - pos[1] = g_poolTableData[ poolid ] [ E_Y ]; - pos[2] = g_poolTableData[ poolid ] [ E_Z ]; - angle = g_poolTableData[ poolid ] [ E_ANGLE ]; - - RotateXY(0.5, 0.0, angle, x, y); - g_poolBallData[poolid] [E_BALL_OBJECT] [0] = CreateObject(3003, x + pos[0], y + pos[1], (pos[2]), 0, 0, 0); - - InitBalls(poolid, 0); - } - return 1; -} - stock removePlayerWeapon(playerid, weaponid) { SetPlayerArmedWeapon(playerid, weaponid); @@ -609,9 +558,45 @@ stock removePlayerWeapon(playerid, weaponid) return 1; } -stock gameEnd(poolid) +stock Pool_UpdateScoreboard( poolid, close = 0 ) { - foreach (new i : Player) + new first_player = Iter_First( poolplayers< poolid > ); + new second_player = Iter_Last( poolplayers< poolid > ); + + foreach ( new playerid : poolplayers< poolid > ) + { + new + is_playing = playerid == first_player ? first_player : ( playerid == second_player ? second_player : -1 ); + + if ( g_poolTableData[ poolid ] [ E_BALLS_SCORED ] && is_playing != -1 ) { + format( + szBigString, sizeof( szBigString ), "You are %s. ", + g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ is_playing ] == E_STRIPED ? ( "striped" ) : ( "solid" ) + ); + } else { + szBigString = ""; + } + + format( szBigString, sizeof( szBigString ), + "%sIt's %s's turn.~n~~n~~r~~h~~h~%s Score:~w~ %d~n~~b~~h~~h~%s Score:~w~ %d", + szBigString, ReturnPlayerName( g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ), + ReturnPlayerName( first_player ), p_PoolScore[ first_player ], + ReturnPlayerName( second_player ), p_PoolScore[ second_player ] + ); + + ShowPlayerHelpDialog( playerid, close, szBigString ); + } + + UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], -1, "" ); +} + +stock Pool_EndGame( poolid ) +{ + // hide scoreboard in 5 seconds + Pool_UpdateScoreboard( poolid, 5000 ); + + // unset pool variables + foreach ( new i : Player ) { if (p_PoolID[ i ] == poolid) { @@ -623,7 +608,10 @@ stock gameEnd(poolid) } } + g_poolTableData[ poolid ] [ E_STARTED ] = false; + g_poolTableData[ poolid ] [ E_AIMER ] = -1; + g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ] = -1; KillTimer(g_poolTableData[ poolid ] [ E_TIMER ]); for (new i = 0; i < 16; i ++) @@ -638,7 +626,6 @@ stock gameEnd(poolid) } UpdateDynamic3DTextLabelText(g_poolTableData[ poolid ] [ E_LABEL ], -1, DEFAULT_POOL_STRING); - return 1; } @@ -678,7 +665,7 @@ stock IsBallAtPos( objectid, Float: x, Float: y, Float: z, Float: radius ) }*/ public PlayPoolSound( poolid, soundid ) { - foreach ( new playerid : Player ) if ( p_PoolID[ playerid ] == poolid ) { + foreach ( new playerid : poolplayers< poolid > ) { PlayerPlaySound( playerid, soundid, 0.0, 0.0, 0.0 ); } return 1; @@ -702,7 +689,7 @@ public OnPoolUpdate(poolid) new Float: X, Float: Y, Float: Z, Float: Xa, Float: Ya, Float: Za, Float: x, Float: y, Float: newrot, Float: dist; GetPlayerPos(playerid, X, Y ,Z); - GetObjectPos(g_poolBallData[poolid] [E_BALL_OBJECT] [0], Xa, Ya, Za); + GetObjectPos(g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], Xa, Ya, Za); newrot = p_PoolAngle[ playerid ] [ 0 ] + (lr > 0 ? 0.9 : -0.9); dist = GetDistanceBetweenPoints( X, Y, 0.0, Xa, Ya, 0.0 ); @@ -713,17 +700,12 @@ public OnPoolUpdate(poolid) { case 0: { - GetXYBehindObjectInAngle(g_poolBallData[poolid] [E_BALL_OBJECT] [0], newrot, x, y, 0.675); + GetXYBehindObjectInAngle(g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], newrot, x, y, 0.675); SetPlayerCameraPos(playerid, x, y, g_poolTableData[ poolid ] [ E_Z ] + DEFAULT_AIM); SetPlayerCameraLookAt(playerid, Xa, Ya, Za + 0.170); } - case 1: - { - SetPlayerCameraPos(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0); - SetPlayerCameraLookAt(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ]); - } - case 2: + case 1, 2: { SetPlayerCameraPos(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0); SetPlayerCameraLookAt(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ]); @@ -774,12 +756,12 @@ public OnPoolUpdate(poolid) } } - if (g_poolTableData[ poolid ] [ E_LAST_SHOOTER ] != -1 && AreAllBallsStopped(poolid)) + if ( g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ] != -1 && AreAllBallsStopped( poolid ) ) { - SetTimerEx("RestoreCamera", 800, 0, "dd", g_poolTableData[ poolid ] [ E_LAST_SHOOTER ], poolid); - g_poolTableData[ poolid ] [ E_LAST_SHOOTER ] = -1; + Pool_QueueNextPlayer( poolid, g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ] ); + SetTimerEx("RestoreCamera", 800, 0, "dd", g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ], poolid); + g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ] = -1; } - return 1; } @@ -787,7 +769,7 @@ public RestoreCamera(playerid, poolid) { if (!g_poolBallData[poolid] [E_EXISTS] [0]) { - DestroyObject(g_poolBallData[poolid] [E_BALL_OBJECT] [0]); + DestroyObject(g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ]); new Float: x, Float: y, Float: pos[3], Float: angle; @@ -797,7 +779,7 @@ public RestoreCamera(playerid, poolid) angle = g_poolTableData[ poolid ] [ E_ANGLE ]; RotateXY(0.5, 0.0, angle, x, y); - g_poolBallData[poolid] [E_BALL_OBJECT] [0] = CreateObject(3003, x + pos[0], y + pos[1], (pos[2] - 0.045), 0, 0, 0); + g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ] = CreateObject(3003, x + pos[0], y + pos[1], (pos[2] - 0.045), 0, 0, 0); InitBalls(poolid, 0); } @@ -875,136 +857,187 @@ public PHY_OnObjectCollideWithWall( objectid, wallid ) return 1; } -public PHY_OnObjectUpdate(objectid) +public PHY_OnObjectUpdate( objectid ) { - foreach (new i : Player) + foreach ( new poolid : pooltables ) if ( g_poolTableData[ poolid ] [ E_STARTED ] ) { - new - poolid = getNearestPoolTable( i ); + for ( new j = 0; j < 16; j ++ ) if ( objectid == g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ j ] && ! g_poolBallData[ poolid ] [ E_MOVING ] [ j ] && PHY_IsObjectMoving( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ j ] ) ) + { + new + holeid = IsBallInHole( poolid, objectid ); - if ( poolid == -1 ) - return 0; + if ( holeid != -1 ) + { + new first_player = Iter_First( poolplayers< poolid > ); + new second_player = Iter_Last( poolplayers< poolid > ); + new current_player = g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ]; + new poolball_index = GetPoolBallIndexFromModel( GetObjectModel( objectid ) ); + printf ("first_player %d, second_player %d, current_player = %d", first_player, second_player, current_player); - for (new j = 0; j < 16; j ++) - { - if ( objectid == g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ j ] && PHY_IsObjectMoving( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ j ]) && !g_poolBallData[ poolid ] [ E_MOVING ] [ j ] ) - { - new - holeid = IsBallInHole( poolid, objectid ); - - if ( holeid != -1 ) + // check if first ball was potted to figure winner + if ( g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED || g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_SOLID ) { - new pool_player = g_poolTableData[ poolid ] [ E_LAST_SHOOTER ]; - new pool_player_index = g_poolTableData[ poolid ] [ E_PLAYER ] [ 0 ] == pool_player ? 0 : 1; // use foreach for players - - new poolball_index = GetPoolBallIndexFromModel( GetObjectModel( objectid ) ); - - // check if first ball was potted to figure winner - if ( ++ g_poolTableData[ poolid ] [ E_BALLS_SCORED ] == 1 && g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED || g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_SOLID ) + if ( ++ g_poolTableData[ poolid ] [ E_BALLS_SCORED ] == 1 ) { - g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ pool_player_index ] = g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ]; - // assign player 2 a ball + // assign first player a type after first one is hit + g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ current_player ] = g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ]; - foreach ( new playerid : Player ) if ( p_PoolID[ playerid ] == poolid ) { - SendClientMessageFormatted( playerid, COLOR_YELLOW, "* %s(%d) is now playing as %s", ReturnPlayerName( playerid ), playerid, g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ pool_player_index ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); + // assign second player + if ( current_player == first_player ) { + g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ second_player ] = g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ first_player ] == E_STRIPED ? E_SOLID : E_STRIPED; + } else if ( current_player == second_player ) { + g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ first_player ] = g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ second_player ] == E_STRIPED ? E_SOLID : E_STRIPED; + } + + // alert players in table + foreach ( new playerid : poolplayers< poolid > ) { + SendClientMessageFormatted( playerid, COLOR_YELLOW, "* %s(%d) is now playing as %s", ReturnPlayerName( first_player ), first_player, g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ first_player ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); + SendClientMessageFormatted( playerid, COLOR_YELLOW, "* %s(%d) is playing as %s", ReturnPlayerName( second_player ), second_player, g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ second_player ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); + } + } + } + + if ( g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_CUE ) + { + GameTextForPlayer( current_player, "~n~~n~~n~~r~~h~You have pocketed the cue ball!", 10000, 4 ); + + // respawn the cue ball + if ( ! g_poolBallData[ poolid ] [ E_EXISTS ] [ 0 ] ) + { + + new + Float: x, Float: y; + + RotateXY( 0.5, 0.0, g_poolTableData[ poolid ] [ E_ANGLE ], x, y ); + + DestroyObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ] ); + g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ] = CreateObject( 3003, g_poolTableData[ poolid ] [ E_X ] + x, g_poolTableData[ poolid ] [ E_Y ] + y, g_poolTableData[ poolid ] [ E_Z ], 0.0, 0.0, 0.0 ); + + InitBalls( poolid, 0 ); + } + } + else if ( g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_8BALL ) + { + g_poolTableData[ poolid ] [ E_BALLS_SCORED ] ++; + + // restore player camera + RestoreCamera( current_player, poolid ); + + // check if valid shot + if ( p_PoolScore[ current_player ] < 7 ) + { + new + winning_player = current_player != first_player ? first_player : second_player; + + foreach ( new playerid : poolplayers< poolid > ) { + SendClientMessageFormatted( playerid, COLOR_YELLOW, "%s(%d) has accidentally potted the Eight Ball ... %s(%d) wins!", ReturnPlayerName( current_player ), current_player, ReturnPlayerName( winning_player ), winning_player ); + } + } + else + { + foreach ( new playerid : poolplayers< poolid > ) { + SendClientMessageFormatted( playerid, COLOR_YELLOW, "%s(%d) has the final potted the Eight Ball and won!", ReturnPlayerName( current_player ), current_player ); + } + } + return Pool_EndGame( current_player ); + } + else + { + // check if player potted their own ball type or btfo + if ( g_poolTableData[ poolid ] [ E_BALLS_SCORED ] > 1 && g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ current_player ] != g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] ) + { + new + opposite_player = current_player == first_player ? second_player : first_player; + + p_PoolScore[ opposite_player ] += 1; + GameTextForPlayer( current_player, "~n~~n~~n~~r~wrong ball", 3000, 4); + + foreach ( new playerid : poolplayers< poolid > ) { + SendClientMessageFormatted( playerid, COLOR_RED, "* %s(%d) has wrongly hit %s, instead of %s!", ReturnPlayerName( playerid ), playerid, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ current_player ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); } } + else + { + p_PoolScore[ current_player ] += 1; + GameTextForPlayer( current_player, "~n~~n~~n~~w~Score: +1", 3000, 4); - if ( g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_CUE ) - { - GameTextForPlayer( pool_player, "~n~~n~~n~~r~~h~You have pocketed the cue ball!", 10000, 4 ); - respawnCueBall( poolid ); - } - else if ( g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_8BALL ) - { - // gamemode - GameTextForPlayer( pool_player, "~n~~n~~n~~r~~h~Gameover! 8ball in", 10000, 4 ); - } - else - { - // check if player potted their own ball type or btfo - if ( g_poolTableData[ poolid ] [ E_BALLS_SCORED ] > 1 && g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ pool_player_index ] != g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] ) - { - //p_PoolScore[ pool_player ] -= 1; - GameTextForPlayer( pool_player, "~n~~n~~n~~w~Score: -1", 3000, 4); + PlayerTextDrawSetString( current_player, g_PoolTextdraw[ current_player ], sprintf("Power:~n~~n~Score: %d", p_PoolScore[ current_player ])); + PlayerTextDrawHide( current_player, g_PoolTextdraw[ current_player ] ); + PlayerTextDrawShow( current_player, g_PoolTextdraw[ current_player ] ); - foreach ( new playerid : Player ) if ( p_PoolID[ playerid ] == poolid ) { - SendClientMessageFormatted( playerid, COLOR_RED, "* %s(%d) has hit %s, instead of %s", ReturnPlayerName( playerid ), playerid, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ pool_player_index ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); - } - } - else - { - p_PoolScore[ pool_player ] += 1; - GameTextForPlayer( pool_player, "~n~~n~~n~~w~Score: +1", 3000, 4); - - PlayerTextDrawSetString( pool_player, g_PoolTextdraw[ pool_player ], sprintf("Power:~n~~n~Score: %d", p_PoolScore[ pool_player ])); - PlayerTextDrawHide( pool_player, g_PoolTextdraw[ pool_player ] ); - PlayerTextDrawShow( pool_player, g_PoolTextdraw[ pool_player ] ); - - foreach ( new playerid : Player ) if ( p_PoolID[ playerid ] == poolid ) { - SendClientMessageFormatted( playerid, COLOR_YELLOW, "%s(%d) has potted a %s %s!", ReturnPlayerName( playerid ), playerid, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolBallOffsetData[ poolball_index ] [ E_BALL_NAME ] ); - } - - if (pool_player == g_poolTableData[ poolid ] [ E_PLAYER ] [ 0 ]) - { - format(szNormalString, sizeof(szNormalString), "{FFDC2E}%s [%d] - [%d] %s", ReturnPlayerName(pool_player), p_PoolScore[ pool_player ], p_PoolScore[ g_poolTableData[ poolid ] [ E_PLAYER ] [ 1 ] ], ReturnPlayerName(g_poolTableData[ poolid ] [ E_PLAYER ] [ 1 ])); - } - else if (pool_player == g_poolTableData[ poolid ] [ E_PLAYER ] [ 1 ]) - { - format(szNormalString, sizeof(szNormalString), "{FFDC2E}%s [%d] - [%d] %s", ReturnPlayerName(g_poolTableData[ poolid ] [ E_PLAYER ] [ 0 ]), p_PoolScore[ g_poolTableData[ poolid ] [ E_PLAYER ] [ 0 ] ], p_PoolScore[ pool_player ], ReturnPlayerName(pool_player)); - } - - UpdateDynamic3DTextLabelText(g_poolTableData[ poolid ] [ E_LABEL ], -1, szNormalString); - } - } - - new Float: hole_x, Float: hole_y; - - // rotate hole offsets according to table - RotateXY( g_poolPotOffsetData[ holeid ] [ 0 ], g_poolPotOffsetData[ holeid ] [ 1 ], g_poolTableData[ poolid ] [ E_ANGLE ], hole_x, hole_y ); - - // move object into the pocket - MoveObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ j ], g_poolTableData[ poolid ] [ E_X ] + hole_x, g_poolTableData[ poolid ] [ E_Y ] + hole_y, g_poolTableData[ poolid ] [ E_Z ] - 0.5, 1.0); - - g_poolBallData[ poolid ] [ E_MOVING ] [ j ] = true; - - SetTimerEx("deleteBall", 500, false, "dd", poolid, j); - - PlayerPlaySound(pool_player, 31803, 0.0, 0.0, 0.0); - - if (( GetPoolBallsCount( poolid ) - 1) <= 1) - { - g_poolTableData[ poolid ] [ E_STARTED ] = false; - g_poolTableData[ poolid ] [ E_AIMER ] = -1; - - new - win_score = GetMaxPoolScore( poolid ); - - RestoreCamera(i, poolid); - g_poolTableData[ poolid ] [ E_LAST_SHOOTER ] = -1; - - if ( IsPlayerPlayingPool( i ) && p_PoolScore[ i ] == win_score) - { - SendClientMessageToAllFormatted( -1, ""COL_POOL"[SERVER]"COL_WHITE" The winner is %s(%d) with %d points.", ReturnPlayerName(i), i, win_score); - - p_isPlayingPool{ i } = false; - p_PoolScore[ i ] = -1; - p_PoolID[ i ] = -1; + foreach ( new playerid : poolplayers< poolid > ) { + SendClientMessageFormatted( playerid, COLOR_YELLOW, "%s(%d) has potted a %s %s!", ReturnPlayerName( playerid ), playerid, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolBallOffsetData[ poolball_index ] [ E_BALL_NAME ] ); } - gameEnd(poolid); - } - else if (AreAllBallsStopped(poolid)) - { - SetTimerEx("RestoreCamera", 800, 0, "dd", g_poolTableData[ poolid ] [ E_LAST_SHOOTER ], poolid); - g_poolTableData[ i ] [ E_LAST_SHOOTER ] = -1; - } - } - } - } + format( szNormalString, sizeof( szNormalString ), "{FFDC2E}%s [%d] - [%d] %s", ReturnPlayerName( first_player ), p_PoolScore[ first_player ], p_PoolScore[ second_player ], ReturnPlayerName( second_player ) ); + UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], -1, szNormalString ); + } + } + + new Float: hole_x, Float: hole_y; + + // rotate hole offsets according to table + RotateXY( g_poolPotOffsetData[ holeid ] [ 0 ], g_poolPotOffsetData[ holeid ] [ 1 ], g_poolTableData[ poolid ] [ E_ANGLE ], hole_x, hole_y ); + + // move object into the pocket + MoveObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ j ], g_poolTableData[ poolid ] [ E_X ] + hole_x, g_poolTableData[ poolid ] [ E_Y ] + hole_y, g_poolTableData[ poolid ] [ E_Z ] - 0.5, 1.0); + + g_poolBallData[ poolid ] [ E_MOVING ] [ j ] = true; + + SetTimerEx("deleteBall", 500, false, "dd", poolid, j); + + PlayerPlaySound( current_player, 31803, 0.0, 0.0, 0.0 ); + + // update scoreboard + Pool_UpdateScoreboard( poolid ); + + // if we scored about all the balls then that wraps it up + if ( p_PoolScore[ first_player ] == 8 || p_PoolScore[ second_player ] == 8 ) + { + new + winning_player = ( p_PoolScore[ first_player ] == 8 ) ? first_player : second_player; + + // restore camera + RestoreCamera( current_player, poolid ); + + // winning player + foreach ( new playerid : poolplayers< poolid > ) { + SendClientMessageFormatted( playerid, COLOR_RED, "**** %s(%d) has won %s", ReturnPlayerName( winning_player ), winning_player ); + } + + return Pool_EndGame( poolid ); + } + else if ( AreAllBallsStopped( poolid ) ) + { + Pool_QueueNextPlayer( poolid, current_player ); + SetTimerEx( "RestoreCamera", 800, false, "dd", g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ], poolid ); + g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ] = -1; + } + } + return 1; + } + } + return 1; +} + +stock Pool_PenaltyShot( poolid, current_player ) +{ + +} + +stock Pool_QueueNextPlayer( poolid, current_player ) +{ + new first_player = Iter_First( poolplayers< poolid > ); + new second_player = Iter_Last( poolplayers< poolid > ); + + g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] = current_player == first_player ? second_player : first_player; + + foreach ( new playerid : poolplayers< poolid > ) { + SendClientMessageFormatted( playerid, COLOR_RED, "%s(%d)'s turn to %s!", ReturnPlayerName( g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ), g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ], ! g_poolTableData[ poolid ] [ E_BALLS_SCORED ] ? ( "break" ) : ( "play" ) ); } - return 1; + // update turn + Pool_UpdateScoreboard( poolid ); } /* ** Commands ** */ @@ -1031,17 +1064,23 @@ CMD:pool(playerid, params[]) new poolid = p_PoolID[ playerid ]; - g_poolTableData[ poolid ] [ E_PLAYER ] [ 0 ] = playerid; - g_poolTableData[ poolid ] [ E_PLAYER ] [ 1 ] = targetid; + Iter_Clear( poolplayers ); + Iter_Add( poolplayers< poolid >, playerid ); + Iter_Add( poolplayers< poolid >, targetid ); - SendClientMessageFormatted(targetid, -1, ""COL_POOL"[SERVER]"COL_WHITE" %s(%d) has accepted your pool game invitation.", ReturnPlayerName(playerid), playerid); - SendClientMessageFormatted(playerid, -1, ""COL_POOL"[SERVER]"COL_WHITE" You have accepted %s(%d)'s pool game invitation.", ReturnPlayerName(targetid), targetid); + SendClientMessageFormatted( targetid, -1, ""COL_POOL"[SERVER]"COL_WHITE" %s(%d) has accepted your pool game invitation.", ReturnPlayerName(playerid), playerid ); + SendClientMessageFormatted( playerid, -1, ""COL_POOL"[SERVER]"COL_WHITE" You have accepted %s(%d)'s pool game invitation.", ReturnPlayerName(targetid), targetid ); + + // find a random person to break + new random_cuer = Iter_Random( poolplayers< poolid > ); + + g_poolTableData[ poolid ] [ E_BALLS_SCORED ] = 0; + g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ] = random_cuer; + + Pool_QueueNextPlayer( poolid, random_cuer ); - SendClientMessageFormatted(playerid, -1, ""COL_POOL"[SERVER]"COL_WHITE" %s(%d) will be breaking!", ReturnPlayerName(playerid), playerid); //UpdateDynamicLabel(poolid, 10000, "{C0C0C0}Pool Table\n{FFFFFF}%s(%d) will be breaking!", ReturnPlayerName(g_poolTableData[ poolid ] [poolPlayer] [startid]), g_poolTableData[ poolid ] [poolPlayer] [startid]); - format(szNormalString, sizeof(szNormalString), "{FFDC2E}%s [0] - [0] %s", ReturnPlayerName(playerid), ReturnPlayerName(targetid)); - UpdateDynamic3DTextLabelText(g_poolTableData[ poolid ] [ E_LABEL ], -1, szNormalString); p_isPlayingPool{ playerid } = true; p_PoolID[ playerid ] = poolid; @@ -1057,11 +1096,9 @@ CMD:pool(playerid, params[]) GivePlayerWeapon(targetid, 7, 1); GivePlayerWeapon(playerid, 7, 1); - if (!g_poolTableData[ poolid ] [ E_STARTED ]) - { - g_poolTableData[ poolid ] [ E_STARTED ] = true; - RespawnPoolBalls( poolid ); - } + g_poolTableData[ poolid ] [ E_STARTED ] = true; + Pool_UpdateScoreboard( poolid ); + RespawnPoolBalls( poolid ); return 1; } else if ( strmatch( selection, "decline") ) @@ -1136,7 +1173,7 @@ CMD:endgame(playerid) if ( iPool == -1 ) return SendError( playerid, "You must be near a pool table to use this command." ); - gameEnd( iPool ); + Pool_EndGame( iPool ); SendClientMessage(playerid, -1, ""COL_PINK"[ADMIN]"COL_WHITE" You have force ended the pool game!"); return 1; @@ -1164,6 +1201,10 @@ CMD:play(playerid) { g_poolTableData[ iPool ] [ E_STARTED ] = true; + Iter_Clear( poolplayers< iPool > ); + Iter_Add( poolplayers< iPool >, playerid ); + Iter_Add( poolplayers< iPool >, playerid ); + UpdateDynamic3DTextLabelText(g_poolTableData[ iPool ] [ E_LABEL ], -1, sprintf( "{FFDC2E}%s is currently playing a test game.", ReturnPlayerName( playerid )) ); RespawnPoolBalls( iPool ); @@ -1171,9 +1212,8 @@ CMD:play(playerid) } else { - gameEnd(iPool); + Pool_EndGame( iPool ); } - return 1; } From 21aeeed9655ae68a02ed7faf3ad8adce3a327085 Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Thu, 13 Sep 2018 02:52:39 +1000 Subject: [PATCH 05/17] add penalities for pocketing white / opposition + chalk as soon as you press key fire --- gamemodes/irresistible/cnr/features/pool.pwn | 217 ++++++++++--------- 1 file changed, 113 insertions(+), 104 deletions(-) diff --git a/gamemodes/irresistible/cnr/features/pool.pwn b/gamemodes/irresistible/cnr/features/pool.pwn index 6486243..e6e0c80 100644 --- a/gamemodes/irresistible/cnr/features/pool.pwn +++ b/gamemodes/irresistible/cnr/features/pool.pwn @@ -79,6 +79,8 @@ enum E_POOL_TABLE_DATA bool: E_STARTED, E_AIMER, E_AIMER_OBJECT, E_CURRENT_SHOOTER, E_NEXT_SHOOTER, + E_SHOTS_LEFT, E_CURRENT_PENALTIES, + Float: E_POWER, E_DIRECTION, E_TABLE, Text3D: E_LABEL, @@ -92,8 +94,8 @@ new p_PoolSender [ MAX_PLAYERS ], p_PoolID [ MAX_PLAYERS ], - bool: p_isPlayingPool [ MAX_PLAYERS char], - bool: p_PoolChalk [ MAX_PLAYERS ], + bool: p_isPlayingPool [ MAX_PLAYERS char ], + bool: p_PoolChalking [ MAX_PLAYERS char ], p_PoolCamera [ MAX_PLAYERS ], p_PoolScore [ MAX_PLAYERS ], Float: p_PoolAngle [ MAX_PLAYERS ] [ 2 ], @@ -166,37 +168,42 @@ hook OnPlayerSpawn(playerid) return 1; } -hook OnPlayerKeyStateChange(playerid, newkeys, oldkeys) +hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) { - new id = -1; + new Float: pooltable_distance = 99999.99; + new id = GetClosestPoolTable( playerid, pooltable_distance ); - if ((id = getNearestPoolTable(playerid)) != -1) + if ( id != -1 && pooltable_distance < 2.5 ) { - if (g_poolTableData[ id ] [ E_STARTED ] && IsPlayerPlayingPool( playerid ) && p_PoolID[ playerid ] == id) + if ( g_poolTableData[ id ] [ E_STARTED ] ) { - if (PRESSED(KEY_FIRE)) + // make pressing key fire annoying + if ( IsKeyJustUp( KEY_FIRE, newkeys, oldkeys ) && g_poolTableData[ id ] [ E_AIMER ] != playerid && ! p_PoolChalking{ playerid } ) { - ClearAnimations(playerid); - return 0; - } - else - { - // Not the players turn detection (player 1 and/or player 2) - if (IsKeyJustUp(KEY_SECONDARY_ATTACK, newkeys, oldkeys)) + if ( IsPlayerPlayingPool( playerid ) ) { - if (IsPlayerPlayingPool( playerid ) && g_poolTableData[ id ] [ E_AIMER ] != playerid && !p_PoolChalk[ playerid ]) - { - SetTimerEx("PlayPoolSound", 1400, false, "dd", id, 31807); - SetPlayerArmedWeapon(playerid, 0); - SetPlayerAttachedObject(playerid, 0, 338, 6, 0, 0.07, -0.85, 0, 0, 0); - ApplyAnimation(playerid, "POOL", "POOL_ChalkCue", 3.0, 0, 0, 0, 0, 0, 1); + print("Chalking"); - p_PoolChalk[ playerid ] = true; + p_PoolChalking{ playerid } = true; - SetTimerEx("RestoreWeapon", 3500, false, "d", playerid); - } + SetPlayerArmedWeapon( playerid, 0 ); + SetPlayerAttachedObject( playerid, 0, 338, 6, 0, 0.07, -0.85, 0, 0, 0 ); + ApplyAnimation( playerid, "POOL", "POOL_ChalkCue", 3.0, 0, 0, 0, 0, 0, 1 ); + + SetTimerEx( "PlayPoolSound", 1400, false, "dd", playerid, 31807 ); + SetTimerEx( "RestoreWeapon", 3500, false, "d", playerid ); } + else + { + print( "Why u clearning" ); + ClearAnimations( playerid ); + } + return 1; + } + // begin gameplay stuff + if ( IsPlayerPlayingPool( playerid ) && p_PoolID[ playerid ] == id ) + { if (IsKeyJustUp(KEY_JUMP, newkeys, oldkeys)) { if (g_poolTableData[ id ] [ E_AIMER ] == playerid) @@ -232,18 +239,18 @@ hook OnPlayerKeyStateChange(playerid, newkeys, oldkeys) if (IsKeyJustUp(KEY_HANDBRAKE, newkeys, oldkeys)) { - if (AreAllBallsStopped(id)) + if ( AreAllBallsStopped( id ) ) { if (g_poolTableData[ id ] [ E_AIMER ] != playerid) { - if (!p_PoolChalk[ playerid ] && g_poolTableData[ id ] [ E_AIMER ] == -1) + if ( ! p_PoolChalking{ playerid } && g_poolTableData[ id ] [ E_AIMER ] == -1 ) { new Float:poolrot, Float:X, Float:Y, Float:Z, Float:Xa, Float:Ya, Float:Za, Float:x, Float:y; - GetPlayerPos(playerid, X, Y, Z); + GetPlayerPos( playerid, X, Y, Z ); GetObjectPos( g_poolBallData[ id ] [ E_BALL_OBJECT ] [ 0 ], Xa, Ya, Za ); new Float: distance_to_ball = GetDistanceFromPointToPoint( X, Y, Xa, Ya ); @@ -296,13 +303,18 @@ hook OnPlayerKeyStateChange(playerid, newkeys, oldkeys) } } - if (IsKeyJustUp(KEY_FIRE, newkeys, oldkeys)) + if ( IsKeyJustUp( KEY_FIRE, newkeys, oldkeys ) ) { - if (g_poolTableData[ id ] [ E_AIMER ] == playerid) + if ( g_poolTableData[ id ] [ E_AIMER ] == playerid ) { - new Float: speed; + new + Float: speed; - ApplyAnimation(playerid, "POOL", "POOL_Med_Shot", 3.0, 0, 0, 0, 0, 0, 1); + g_poolTableData[ id ] [ E_SHOTS_LEFT ] --; + g_poolTableData[ id ] [ E_CURRENT_SHOOTER ] = playerid; + + Pool_UpdateScoreboard( id ); + ApplyAnimation( playerid, "POOL", "POOL_Med_Shot", 3.0, 0, 0, 0, 0, 0, 1 ); speed = 0.4 + (g_poolTableData[ id ] [ E_POWER ] * 2.0) / 100.0; PHY_SetObjectVelocity(g_poolBallData[id] [E_BALL_OBJECT] [0], speed * floatsin(-p_PoolAngle[ playerid ] [ 0 ], degrees), speed * floatcos(-p_PoolAngle[ playerid ] [ 0 ], degrees)); @@ -312,29 +324,36 @@ hook OnPlayerKeyStateChange(playerid, newkeys, oldkeys) PlayPoolSound(id, 31810); g_poolTableData[ id ] [ E_AIMER ] = -1; - DestroyObject(g_poolTableData[ id ] [ E_AIMER_OBJECT ]); + DestroyObject( g_poolTableData[ id ] [ E_AIMER_OBJECT ] ); - GivePlayerWeapon(playerid, 7, 1); - - g_poolTableData[ id ] [ E_CURRENT_SHOOTER ] = playerid; + GivePlayerWeapon( playerid, 7, 1 ); } else ClearAnimations(playerid); } } } } - return 1; } /* ** Functions ** */ - -stock getNearestPoolTable( playerid ) +stock GetClosestPoolTable( playerid, &Float: dis = 99999.99 ) { - foreach ( new i : pooltables ) if ( IsPlayerInRangeOfPoint( playerid, 2.5, g_poolTableData[ i ] [ E_X ], g_poolTableData[ i ] [ E_Y ], g_poolTableData[ i ] [ E_Z ]) ) { - return i; + new + pooltable = -1; + + foreach ( new i : pooltables ) + { + new + Float: dis2 = GetPlayerDistanceFromPoint( playerid, g_poolTableData[ i ] [ E_X ], g_poolTableData[ i ] [ E_Y ], g_poolTableData[ i ] [ E_Z ] ); + + if ( dis2 < dis && dis2 != -1.00 ) + { + dis = dis2; + pooltable = i; + } } - return -1; + return pooltable; } stock CreatePoolTable( Float: X, Float: Y, Float: Z, Float: A = 0.0, interior = 0, world = 0 ) @@ -491,22 +510,17 @@ stock GetXYBehindObjectInAngle(objectid, Float:a, &Float:x2, &Float:y2, Float:di y2 += (distance * floatcos(-a+180, degrees)); } -stock AreAllBallsStopped(poolid) +stock AreAllBallsStopped( poolid ) { new - Float: x, - Float: y, - Float: z; + Float: x, Float: y, Float: z; - for (new i = 0; i < 16; i ++) + for ( new i = 0; i < 16; i ++ ) if ( g_poolBallData[ poolid ] [ E_EXISTS ] [ i ] ) { - if (g_poolBallData[poolid] [E_EXISTS] [i]) - { - PHY_GetObjectVelocity(g_poolBallData[poolid] [E_BALL_OBJECT] [i], x, y, z); + PHY_GetObjectVelocity( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ], x, y, z ); - if (x != 0.0 || y != 0.0) - return 0; - } + if ( x != 0.0 || y != 0.0 ) + return 0; } return 1; } @@ -578,10 +592,11 @@ stock Pool_UpdateScoreboard( poolid, close = 0 ) } format( szBigString, sizeof( szBigString ), - "%sIt's %s's turn.~n~~n~~r~~h~~h~%s Score:~w~ %d~n~~b~~h~~h~%s Score:~w~ %d", + "%sIt's %s's turn.~n~~n~~r~~h~~h~%s Score:~w~ %d~n~~b~~h~~h~%s Score:~w~ %d~n~~n~%d shots remaining", szBigString, ReturnPlayerName( g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ), ReturnPlayerName( first_player ), p_PoolScore[ first_player ], - ReturnPlayerName( second_player ), p_PoolScore[ second_player ] + ReturnPlayerName( second_player ), p_PoolScore[ second_player ], + g_poolTableData[ poolid ] [ E_CURRENT_PENALTIES ] ? 0 : g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] ); ShowPlayerHelpDialog( playerid, close, szBigString ); @@ -647,23 +662,6 @@ stock IsBallAtPos( objectid, Float: x, Float: y, Float: z, Float: radius ) return distance < radius; } -/*stock IsBallNearSide(poolid, objectid) -{ - new Float: x_vertex[4], - Float: y_vertex[4]; - - RotateXY(-0.96, -0.515, 0.0, x_vertex[0], y_vertex[0]); - RotateXY(-0.96, 0.515, 0.0, x_vertex[1], y_vertex[1]); - RotateXY(0.96, -0.515, 0.0, x_vertex[2], y_vertex[2]); - RotateXY(0.96, 0.515, 0.0, x_vertex[3], y_vertex[3]); - - if (IsBallAtPos(objectid, x_vertex[0] + g_poolTableData[ poolid ] [ E_X ], y_vertex[0] + g_poolTableData[ poolid ] [ E_Y ], x_vertex[1] + g_poolTableData[ poolid ] [ E_X ], y_vertex[1] + g_poolTableData[ poolid ] [ E_Y ])) return 1; - if (IsBallAtPos(objectid, x_vertex[1] + g_poolTableData[ poolid ] [ E_X ], y_vertex[1] + g_poolTableData[ poolid ] [ E_Y ], x_vertex[3] + g_poolTableData[ poolid ] [ E_X ], y_vertex[3] + g_poolTableData[ poolid ] [ E_Y ])) return 1; - if (IsBallAtPos(objectid, x_vertex[2] + g_poolTableData[ poolid ] [ E_X ], y_vertex[2] + g_poolTableData[ poolid ] [ E_Y ], x_vertex[3] + g_poolTableData[ poolid ] [ E_X ], y_vertex[3] + g_poolTableData[ poolid ] [ E_Y ])) return 1; - if (IsBallAtPos(objectid, x_vertex[0] + g_poolTableData[ poolid ] [ E_X ], y_vertex[0] + g_poolTableData[ poolid ] [ E_Y ], x_vertex[2] + g_poolTableData[ poolid ] [ E_X ], y_vertex[2] + g_poolTableData[ poolid ] [ E_Y ])) return 1; - return 0; -}*/ - public PlayPoolSound( poolid, soundid ) { foreach ( new playerid : poolplayers< poolid > ) { PlayerPlaySound( playerid, soundid, 0.0, 0.0, 0.0 ); @@ -758,7 +756,7 @@ public OnPoolUpdate(poolid) if ( g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ] != -1 && AreAllBallsStopped( poolid ) ) { - Pool_QueueNextPlayer( poolid, g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ] ); + Pool_QueueNextPlayer( poolid, g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ], g_poolTableData[ poolid ] [ E_CURRENT_PENALTIES ] ? 2 : 1 ); SetTimerEx("RestoreCamera", 800, 0, "dd", g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ], poolid); g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ] = -1; } @@ -808,15 +806,12 @@ public deleteBall(poolid, ballid) return 1; } -public RestoreWeapon(playerid) +public RestoreWeapon( playerid ) { - RemovePlayerAttachedObject(playerid, 0); - - p_PoolChalk[ playerid ] = false; - - GivePlayerWeapon(playerid, 7, 1); - - ApplyAnimation(playerid, "CARRY", "crry_prtial", 1.0, 0, 0, 0, 0, 0, 1); + RemovePlayerAttachedObject( playerid, 0 ); + p_PoolChalking{ playerid } = false; + GivePlayerWeapon( playerid, 7, 1 ); + ClearAnimations( playerid ); return 1; } @@ -915,6 +910,9 @@ public PHY_OnObjectUpdate( objectid ) InitBalls( poolid, 0 ); } + + // penalty + g_poolTableData[ poolid ] [ E_CURRENT_PENALTIES ] ++; } else if ( g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_8BALL ) { @@ -938,6 +936,7 @@ public PHY_OnObjectUpdate( objectid ) foreach ( new playerid : poolplayers< poolid > ) { SendClientMessageFormatted( playerid, COLOR_YELLOW, "%s(%d) has the final potted the Eight Ball and won!", ReturnPlayerName( current_player ), current_player ); } + p_PoolScore[ current_player ] ++; // shows on the end result if we do it anyway here } return Pool_EndGame( current_player ); } @@ -953,12 +952,15 @@ public PHY_OnObjectUpdate( objectid ) GameTextForPlayer( current_player, "~n~~n~~n~~r~wrong ball", 3000, 4); foreach ( new playerid : poolplayers< poolid > ) { - SendClientMessageFormatted( playerid, COLOR_RED, "* %s(%d) has wrongly hit %s, instead of %s!", ReturnPlayerName( playerid ), playerid, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ current_player ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); + SendClientMessageFormatted( playerid, COLOR_RED, "* %s(%d) has wrongly hit %s, instead of %s!", ReturnPlayerName( current_player ), current_player, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ current_player ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); } + + // penalty + g_poolTableData[ poolid ] [ E_CURRENT_PENALTIES ] ++; } else { - p_PoolScore[ current_player ] += 1; + p_PoolScore[ current_player ] ++; GameTextForPlayer( current_player, "~n~~n~~n~~w~Score: +1", 3000, 4); PlayerTextDrawSetString( current_player, g_PoolTextdraw[ current_player ], sprintf("Power:~n~~n~Score: %d", p_PoolScore[ current_player ])); @@ -966,11 +968,14 @@ public PHY_OnObjectUpdate( objectid ) PlayerTextDrawShow( current_player, g_PoolTextdraw[ current_player ] ); foreach ( new playerid : poolplayers< poolid > ) { - SendClientMessageFormatted( playerid, COLOR_YELLOW, "%s(%d) has potted a %s %s!", ReturnPlayerName( playerid ), playerid, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolBallOffsetData[ poolball_index ] [ E_BALL_NAME ] ); + SendClientMessageFormatted( playerid, COLOR_YELLOW, "%s(%d) has potted a %s %s!", ReturnPlayerName( current_player ), current_player, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolBallOffsetData[ poolball_index ] [ E_BALL_NAME ] ); } format( szNormalString, sizeof( szNormalString ), "{FFDC2E}%s [%d] - [%d] %s", ReturnPlayerName( first_player ), p_PoolScore[ first_player ], p_PoolScore[ second_player ], ReturnPlayerName( second_player ) ); UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], -1, szNormalString ); + + // extra shot for scoring one's own + g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] ++; } } @@ -1004,15 +1009,15 @@ public PHY_OnObjectUpdate( objectid ) foreach ( new playerid : poolplayers< poolid > ) { SendClientMessageFormatted( playerid, COLOR_RED, "**** %s(%d) has won %s", ReturnPlayerName( winning_player ), winning_player ); } - return Pool_EndGame( poolid ); } - else if ( AreAllBallsStopped( poolid ) ) + /*else if ( AreAllBallsStopped( poolid ) ) { - Pool_QueueNextPlayer( poolid, current_player ); + print( "Pool_QueueNextPlayer( %d, %d, %d )", poolid, current_player, next_player_shots ); + Pool_QueueNextPlayer( poolid, current_player, next_player_shots ); SetTimerEx( "RestoreCamera", 800, false, "dd", g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ], poolid ); g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ] = -1; - } + }*/ } return 1; } @@ -1020,20 +1025,26 @@ public PHY_OnObjectUpdate( objectid ) return 1; } -stock Pool_PenaltyShot( poolid, current_player ) +stock Pool_QueueNextPlayer( poolid, current_player, next_player_shots = 1 ) { + if ( g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] > 0 && g_poolTableData[ poolid ] [ E_CURRENT_PENALTIES ] < 1 ) + { + foreach ( new playerid : poolplayers< poolid > ) { + SendClientMessageFormatted( playerid, COLOR_RED, "%s(%d) has %d shots remaining!", ReturnPlayerName( current_player ), current_player, g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] ); + } + } + else + { + new first_player = Iter_First( poolplayers< poolid > ); + new second_player = Iter_Last( poolplayers< poolid > ); -} + g_poolTableData[ poolid ] [ E_CURRENT_PENALTIES ] = 0; + g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] = next_player_shots; + g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] = current_player == first_player ? second_player : first_player; -stock Pool_QueueNextPlayer( poolid, current_player ) -{ - new first_player = Iter_First( poolplayers< poolid > ); - new second_player = Iter_Last( poolplayers< poolid > ); - - g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] = current_player == first_player ? second_player : first_player; - - foreach ( new playerid : poolplayers< poolid > ) { - SendClientMessageFormatted( playerid, COLOR_RED, "%s(%d)'s turn to %s!", ReturnPlayerName( g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ), g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ], ! g_poolTableData[ poolid ] [ E_BALLS_SCORED ] ? ( "break" ) : ( "play" ) ); + foreach ( new playerid : poolplayers< poolid > ) { + SendClientMessageFormatted( playerid, COLOR_RED, "%s(%d)'s turn to %s!", ReturnPlayerName( g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ), g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ], ! g_poolTableData[ poolid ] [ E_BALLS_SCORED ] ? ( "break" ) : ( "play" ) ); + } } // update turn @@ -1115,9 +1126,7 @@ CMD:pool(playerid, params[]) } else if (strmatch(selection, "invite")) { - new id = -1, targetid; - - id = getNearestPoolTable(playerid); + new id = GetClosestPoolTable(playerid), targetid; if (id == -1) return SendError(playerid, "You are not close enough to a pool table."); @@ -1168,7 +1177,7 @@ CMD:endgame(playerid) if ( ! IsPlayerAdmin( playerid ) ) return 0; - new iPool = getNearestPoolTable( playerid ); + new iPool = GetClosestPoolTable( playerid ); if ( iPool == -1 ) return SendError( playerid, "You must be near a pool table to use this command." ); @@ -1182,7 +1191,7 @@ CMD:endgame(playerid) CMD:play(playerid) { new - iPool = getNearestPoolTable( playerid ); + iPool = GetClosestPoolTable( playerid ); if ( iPool == -1 ) return SendError( playerid, "You are not near a pool table." ); @@ -1243,7 +1252,7 @@ CMD:addpool(playerid, params[]) CMD:camtest( playerid, params[ ] ) { new - iPool = getNearestPoolTable( playerid ); + iPool = GetClosestPoolTable( playerid ); if ( iPool == -1 ) return SendError( playerid, "You are not near a pool table." ); @@ -1262,7 +1271,7 @@ CMD:addpool(playerid, params[]) CMD:setoffset( playerid, params[ ] ) { - new iPool = getNearestPoolTable( playerid ); + new iPool = GetClosestPoolTable( playerid ); new offset; new Float: x, Float: y; From 60c098abd2dfbd619be5368e433a15b8f05dbf0b Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Thu, 13 Sep 2018 04:03:16 +1000 Subject: [PATCH 06/17] move clearchat feature to helpers --- gamemodes/irresistible/cnr/features/visage/poker.pwn | 7 ------- gamemodes/irresistible/helpers.pwn | 10 ++++++++++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/gamemodes/irresistible/cnr/features/visage/poker.pwn b/gamemodes/irresistible/cnr/features/visage/poker.pwn index 6aa8a59..40ed5af 100644 --- a/gamemodes/irresistible/cnr/features/visage/poker.pwn +++ b/gamemodes/irresistible/cnr/features/visage/poker.pwn @@ -1147,13 +1147,6 @@ stock UpdateInfoTextdrawsForPlayer(playerid) return 1; } -stock Player_Clearchat(playerid) -{ - for(new j = 0; j < 30; j++) - SendClientMessage(playerid, -1, " "); - return 1; -} - public Poker_StartGame(handle, dealer) { TableData[handle][E_TABLE_STING_NEW_GAME] = false; diff --git a/gamemodes/irresistible/helpers.pwn b/gamemodes/irresistible/helpers.pwn index 964e8a9..91fa43e 100644 --- a/gamemodes/irresistible/helpers.pwn +++ b/gamemodes/irresistible/helpers.pwn @@ -13,6 +13,7 @@ #define RandomEx(%0,%1) (random((%1) - (%0)) + (%0)) #define HOLDING(%0) ((newkeys & (%0)) == (%0)) #define PRESSED(%0) (((newkeys & (%0)) == (%0)) && ((oldkeys & (%0)) != (%0))) +#define RELEASED(%0) (((newkeys & (%0)) != (%0)) && ((oldkeys & (%0)) == (%0))) #define SendUsage(%0,%1) (SendClientMessageFormatted(%0,-1,"{FFAF00}[USAGE]{FFFFFF} " # %1)) #define SendError(%0,%1) (SendClientMessageFormatted(%0,-1,"{F81414}[ERROR]{FFFFFF} " # %1)) #define SendServerMessage(%0,%1) (SendClientMessageFormatted(%0,-1,"{C0C0C0}[SERVER]{FFFFFF} " # %1)) @@ -88,6 +89,15 @@ stock trimString( strSrc[ ] ) strdel( strSrc, 0, strPos ); } +// purpose: clear chat for player +stock Player_Clearchat( playerid ) +{ + for ( new j = 0; j < 30; j ++ ) { + SendClientMessage( playerid, -1, " " ); + } + return 1; +} + // purpose: get distance between players stock Float: GetDistanceBetweenPlayers( iPlayer1, iPlayer2, &Float: fDistance = Float: 0x7F800000, bool: bAllowNpc = false ) { From 5445f069682a9ac33153018e22aa23726c8ee436 Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Thu, 13 Sep 2018 07:38:47 +1000 Subject: [PATCH 07/17] removes pool cmd ... simply enter to join pool table, laser placed for where 8ball should go towards ending a game --- gamemodes/irresistible/cnr/features/pool.pwn | 650 ++++++++++--------- 1 file changed, 334 insertions(+), 316 deletions(-) diff --git a/gamemodes/irresistible/cnr/features/pool.pwn b/gamemodes/irresistible/cnr/features/pool.pwn index e6e0c80..16b7f69 100644 --- a/gamemodes/irresistible/cnr/features/pool.pwn +++ b/gamemodes/irresistible/cnr/features/pool.pwn @@ -17,11 +17,16 @@ #define POCKET_RADIUS 0.09 #define POOL_TIMER_SPEED 30 #define DEFAULT_AIM 0.38 -#define DEFAULT_POOL_STRING "{FFDC2E}Pool Table\n{FFFFFF}To begin pool use /pool" +#define DEFAULT_POOL_STRING "Pool Table\n{FFFFFF}Press ENTER To Play" #define MAX_TABLES 32 #define COL_POOL "{C0C0C0}" +/* ** Macros ** */ +#define SendPoolMessage(%0,%1) \ + SendClientMessageFormatted(%0, -1, "{4B8774}[POOL] {E5861A}" # %1) + + /* ** Constants (do not modify) ** */ enum E_POOL_BALL_TYPE { E_STRIPED, @@ -61,7 +66,8 @@ static const { 0.955, 0.510 }, { 0.955, -0.49 }, { 0.005, 0.550 }, { 0.007, -0.535 }, { -0.945, 0.513 }, { -0.945, -0.490 } - } + }, + g_poolHoleOpposite[ sizeof( g_poolPotOffsetData ) ] = { 5, 4, 3, 2, 1, 0 } ; /* ** Variables ** */ @@ -77,9 +83,9 @@ enum E_POOL_TABLE_DATA E_TIMER, E_BALLS_SCORED, E_POOL_BALL_TYPE: E_PLAYER_BALL_TYPE[ MAX_PLAYERS ], bool: E_STARTED, E_AIMER, E_AIMER_OBJECT, - E_CURRENT_SHOOTER, E_NEXT_SHOOTER, + E_NEXT_SHOOTER, - E_SHOTS_LEFT, E_CURRENT_PENALTIES, + E_SHOTS_LEFT, E_FOULS, E_PLAYER_8BALL_TARGET[ MAX_PLAYERS ], Float: E_POWER, E_DIRECTION, @@ -90,18 +96,17 @@ new g_poolTableData [ MAX_TABLES ] [ E_POOL_TABLE_DATA ], g_poolBallData [ MAX_TABLES ] [ E_POOL_BALL_DATA ], - p_PoolReciever [ MAX_PLAYERS ], - p_PoolSender [ MAX_PLAYERS ], - p_PoolID [ MAX_PLAYERS ], + p_PoolID [ MAX_PLAYERS ] = { -1, ... }, bool: p_isPlayingPool [ MAX_PLAYERS char ], bool: p_PoolChalking [ MAX_PLAYERS char ], p_PoolCamera [ MAX_PLAYERS ], p_PoolScore [ MAX_PLAYERS ], + p_PoolHoleGuide [ MAX_PLAYERS ] = { -1, ... }, Float: p_PoolAngle [ MAX_PLAYERS ] [ 2 ], PlayerBar: g_PoolPowerBar [ MAX_PLAYERS ], - PlayerText: g_PoolTextdraw [ MAX_PLAYERS ], + Text: g_PoolTextdraw = Text: INVALID_TEXT_DRAW, Iterator: pooltables < MAX_TABLES >, Iterator: poolplayers < MAX_TABLES, MAX_PLAYERS > @@ -119,71 +124,60 @@ forward PlayPoolSound ( poolid, soundid ); hook OnScriptInit( ) { - //stock CreatePoolTable(Float: X, Float: Y, Float: Z, Float: A = 0.0, interior = 0, world = 0) + // textdraws + g_PoolTextdraw = TextDrawCreate(529.000000, 218.000000, "Power"); + TextDrawBackgroundColor(g_PoolTextdraw, 255); + TextDrawFont(g_PoolTextdraw, 1); + TextDrawLetterSize(g_PoolTextdraw, 0.300000, 1.299998); + TextDrawColor(g_PoolTextdraw, -1); + TextDrawSetOutline(g_PoolTextdraw, 1); + TextDrawSetProportional(g_PoolTextdraw, 1); + TextDrawSetSelectable(g_PoolTextdraw, 0); - CreatePoolTable(2048.5801, 1330.8917, 10.6719, 0, 0); + // create static pooltables + CreatePoolTable( 2048.5801, 1330.8917, 10.6719, 0, 0 ); + // CreatePoolTable(Float: X, Float: Y, Float: Z, Float: A = 0.0, interior = 0, world = 0) printf( "[POOL TABLES]: %d pool tables have been successfully loaded.", Iter_Count( pooltables ) ); return 1; } -hook OnPlayerDisconnect(playerid, reason) +hook OnPlayerDisconnect( playerid, reason ) { - if ( IsPlayerPlayingPool(playerid ) ) - { - Pool_EndGame( p_PoolID[ playerid ] ); - - p_PoolSender[ playerid ] = INVALID_PLAYER_ID; - p_PoolReciever[ playerid ] = INVALID_PLAYER_ID; - p_isPlayingPool{ playerid } = false; - p_PoolID[ playerid ] = -1; - - p_PoolScore[ playerid ] = 0; - } + Pool_RemovePlayer( playerid ); return 1; } -hook OnPlayerConnect(playerid) +#if defined AC_INCLUDED +hook OnPlayerDeathEx( playerid, killerid, reason, Float: damage, bodypart ) +#else +hook OnPlayerDeath( playerid, killerid, reason ) +#endif { - g_PoolPowerBar[playerid] = CreatePlayerProgressBar(playerid, 530.000000, 233.000000, 61.000000, 6.199999, -1429936641, 100.0000, 0); - - g_PoolTextdraw[playerid] = CreatePlayerTextDraw(playerid, 529.000000, 218.000000, "Power~n~~n~Score: 0"); - PlayerTextDrawBackgroundColor(playerid, g_PoolTextdraw[playerid], 255); - PlayerTextDrawFont(playerid, g_PoolTextdraw[playerid], 1); - PlayerTextDrawLetterSize(playerid, g_PoolTextdraw[playerid], 0.300000, 1.299998); - PlayerTextDrawColor(playerid, g_PoolTextdraw[playerid], -1); - PlayerTextDrawSetOutline(playerid, g_PoolTextdraw[playerid], 1); - PlayerTextDrawSetProportional(playerid, g_PoolTextdraw[playerid], 1); - PlayerTextDrawSetSelectable(playerid, g_PoolTextdraw[playerid], 0); + Pool_RemovePlayer( playerid ); return 1; } -hook OnPlayerSpawn(playerid) +hook OnPlayerConnect( playerid ) { - p_PoolSender[ playerid ] = INVALID_PLAYER_ID; - p_PoolReciever[ playerid ] = INVALID_PLAYER_ID; - p_isPlayingPool{ playerid } = false; - p_PoolID[ playerid ] = -1; - p_PoolScore[ playerid ] = 0; + g_PoolPowerBar[ playerid ] = CreatePlayerProgressBar( playerid, 530.000000, 233.000000, 61.000000, 6.199999, -1429936641, 100.0000, 0 ); return 1; } hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) { new Float: pooltable_distance = 99999.99; - new id = GetClosestPoolTable( playerid, pooltable_distance ); + new poolid = GetClosestPoolTable( playerid, pooltable_distance ); - if ( id != -1 && pooltable_distance < 2.5 ) + if ( poolid != -1 && pooltable_distance < 2.5 ) { - if ( g_poolTableData[ id ] [ E_STARTED ] ) + if ( g_poolTableData[ poolid ] [ E_STARTED ] ) { // make pressing key fire annoying - if ( IsKeyJustUp( KEY_FIRE, newkeys, oldkeys ) && g_poolTableData[ id ] [ E_AIMER ] != playerid && ! p_PoolChalking{ playerid } ) + if ( RELEASED( KEY_FIRE ) && g_poolTableData[ poolid ] [ E_AIMER ] != playerid && ! p_PoolChalking{ playerid } ) { if ( IsPlayerPlayingPool( playerid ) ) { - print("Chalking"); - p_PoolChalking{ playerid } = true; SetPlayerArmedWeapon( playerid, 0 ); @@ -195,18 +189,17 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) } else { - print( "Why u clearning" ); ClearAnimations( playerid ); } return 1; } // begin gameplay stuff - if ( IsPlayerPlayingPool( playerid ) && p_PoolID[ playerid ] == id ) + if ( IsPlayerPlayingPool( playerid ) && p_PoolID[ playerid ] == poolid ) { - if (IsKeyJustUp(KEY_JUMP, newkeys, oldkeys)) + if ( RELEASED( KEY_JUMP ) ) { - if (g_poolTableData[ id ] [ E_AIMER ] == playerid) + if (g_poolTableData[ poolid ] [ E_AIMER ] == playerid) { if (p_PoolCamera[ playerid ] < 2) p_PoolCamera[ playerid ] ++; else p_PoolCamera[ playerid ] = 0; @@ -218,32 +211,36 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) Float:x, Float:y; - GetObjectPos(g_poolBallData[ id ] [ E_BALL_OBJECT ] [ 0 ], Xa, Ya, Za); + GetObjectPos(g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], Xa, Ya, Za); switch (p_PoolCamera[ playerid ]) { case 0: { - GetXYBehindObjectInAngle(g_poolBallData[ id ] [ E_BALL_OBJECT ] [ 0 ], poolrot, x, y, 0.675); - SetPlayerCameraPos(playerid, x, y, g_poolTableData[ id ] [ E_Z ] + DEFAULT_AIM); + GetXYBehindObjectInAngle(g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], poolrot, x, y, 0.675); + SetPlayerCameraPos(playerid, x, y, g_poolTableData[ poolid ] [ E_Z ] + DEFAULT_AIM); SetPlayerCameraLookAt(playerid, Xa, Ya, Za + 0.170); } - case 1..2: + case 1 .. 2: { - SetPlayerCameraPos(playerid, g_poolTableData[ id ] [ E_X ], g_poolTableData[ id ] [ E_Y ], g_poolTableData[ id ] [ E_Z ] + 2.0); - SetPlayerCameraLookAt(playerid, g_poolTableData[ id ] [ E_X ], g_poolTableData[ id ] [ E_Y ], g_poolTableData[ id ] [ E_Z ]); + SetPlayerCameraPos(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0); + SetPlayerCameraLookAt(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ]); } } } } - if (IsKeyJustUp(KEY_HANDBRAKE, newkeys, oldkeys)) + if ( RELEASED( KEY_HANDBRAKE ) ) { - if ( AreAllBallsStopped( id ) ) + if ( AreAllBallsStopped( poolid ) ) { - if (g_poolTableData[ id ] [ E_AIMER ] != playerid) + if ( g_poolTableData[ poolid ] [ E_AIMER ] != playerid ) { - if ( ! p_PoolChalking{ playerid } && g_poolTableData[ id ] [ E_AIMER ] == -1 ) + if ( g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] != playerid ) { + return SendError( playerid, "It is not your turn. Please wait." ); + } + + if ( ! p_PoolChalking{ playerid } && g_poolTableData[ poolid ] [ E_AIMER ] == -1 ) { new Float:poolrot, Float:X, Float:Y, Float:Z, @@ -251,7 +248,7 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) Float:x, Float:y; GetPlayerPos( playerid, X, Y, Z ); - GetObjectPos( g_poolBallData[ id ] [ E_BALL_OBJECT ] [ 0 ], Xa, Ya, Za ); + GetObjectPos( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], Xa, Ya, Za ); new Float: distance_to_ball = GetDistanceFromPointToPoint( X, Y, Xa, Ya ); @@ -268,21 +265,20 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) SetPlayerArmedWeapon(playerid, 0); GetXYInFrontOfPos(Xa, Ya, poolrot + 180, x, y, 0.085); - g_poolTableData[ id ] [ E_AIMER_OBJECT ] = CreateObject(3004, x, y, Za, 7.0, 0, poolrot + 180); + g_poolTableData[ poolid ] [ E_AIMER_OBJECT ] = CreateObject(3004, x, y, Za, 7.0, 0, poolrot + 180); - SetPlayerCameraPos(playerid, g_poolTableData[ id ] [ E_X ], g_poolTableData[ id ] [ E_Y ], g_poolTableData[ id ] [ E_Z ] + 2.0); + SetPlayerCameraPos(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0); ApplyAnimation(playerid, "POOL", "POOL_Med_Start", 50.0, 0, 0, 0, 1, 1, 1); - g_poolTableData[ id ] [ E_AIMER ] = playerid; - g_poolTableData[ id ] [ E_POWER ] = 1.0; - g_poolTableData[ id ] [ E_DIRECTION ] = 0; + g_poolTableData[ poolid ] [ E_AIMER ] = playerid; + g_poolTableData[ poolid ] [ E_POWER ] = 1.0; + g_poolTableData[ poolid ] [ E_DIRECTION ] = 0; - Pool_UpdateScoreboard( id ); + Pool_UpdateScoreboard( poolid ); - PlayerTextDrawSetString(playerid, g_PoolTextdraw[playerid], sprintf("Power:~n~~n~Score: %d", p_PoolScore[ playerid ]) ); - PlayerTextDrawShow(playerid, g_PoolTextdraw[playerid]); - ShowPlayerProgressBar(playerid, g_PoolPowerBar[playerid]); + TextDrawShowForPlayer( playerid, g_PoolTextdraw ); + ShowPlayerProgressBar( playerid, g_PoolPowerBar[playerid] ); } } } @@ -294,37 +290,33 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) ApplyAnimation(playerid, "CARRY", "crry_prtial", 1.0, 0, 0, 0, 0, 0, 1); SetCameraBehindPlayer(playerid); - g_poolTableData[ id ] [ E_AIMER ] = -1; - DestroyObject(g_poolTableData[ id ] [ E_AIMER_OBJECT ]); - - //TextDrawHideForPlayer(playerid, gPoolTD); - //HidePlayerProgressBar(playerid, g_PoolPowerBar[playerid]); + g_poolTableData[ poolid ] [ E_AIMER ] = -1; + DestroyObject(g_poolTableData[ poolid ] [ E_AIMER_OBJECT ]); } } } - if ( IsKeyJustUp( KEY_FIRE, newkeys, oldkeys ) ) + if ( RELEASED( KEY_FIRE ) ) { - if ( g_poolTableData[ id ] [ E_AIMER ] == playerid ) + if ( g_poolTableData[ poolid ] [ E_AIMER ] == playerid ) { new Float: speed; - g_poolTableData[ id ] [ E_SHOTS_LEFT ] --; - g_poolTableData[ id ] [ E_CURRENT_SHOOTER ] = playerid; + g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] --; - Pool_UpdateScoreboard( id ); + Pool_UpdateScoreboard( poolid ); ApplyAnimation( playerid, "POOL", "POOL_Med_Shot", 3.0, 0, 0, 0, 0, 0, 1 ); - speed = 0.4 + (g_poolTableData[ id ] [ E_POWER ] * 2.0) / 100.0; - PHY_SetObjectVelocity(g_poolBallData[id] [E_BALL_OBJECT] [0], speed * floatsin(-p_PoolAngle[ playerid ] [ 0 ], degrees), speed * floatcos(-p_PoolAngle[ playerid ] [ 0 ], degrees)); + speed = 0.4 + (g_poolTableData[ poolid ] [ E_POWER ] * 2.0) / 100.0; + PHY_SetObjectVelocity(g_poolBallData[poolid] [E_BALL_OBJECT] [0], speed * floatsin(-p_PoolAngle[ playerid ] [ 0 ], degrees), speed * floatcos(-p_PoolAngle[ playerid ] [ 0 ], degrees)); - SetPlayerCameraPos(playerid, g_poolTableData[ id ] [ E_X ], g_poolTableData[ id ] [ E_Y ], g_poolTableData[ id ] [ E_Z ] + 2.0); - SetPlayerCameraLookAt(playerid, g_poolTableData[ id ] [ E_X ], g_poolTableData[ id ] [ E_Y ], g_poolTableData[ id ] [ E_Z ]); + SetPlayerCameraPos(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0); + SetPlayerCameraLookAt(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ]); - PlayPoolSound(id, 31810); - g_poolTableData[ id ] [ E_AIMER ] = -1; - DestroyObject( g_poolTableData[ id ] [ E_AIMER_OBJECT ] ); + PlayPoolSound(poolid, 31810); + g_poolTableData[ poolid ] [ E_AIMER ] = -1; + DestroyObject( g_poolTableData[ poolid ] [ E_AIMER_OBJECT ] ); GivePlayerWeapon( playerid, 7, 1 ); } @@ -332,30 +324,99 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) } } } + else + { + if ( PRESSED( KEY_SECONDARY_ATTACK ) ) + { + if ( IsPlayerPlayingPool( playerid ) ) { + Pool_SendTableMessage( poolid, COLOR_GREY, "*** %s(%d) has left the table", ReturnPlayerName( playerid ), playerid ); + return Pool_RemovePlayer( playerid ); + } + + new + pool_player_count = Iter_Count( poolplayers< poolid > ); + + if ( pool_player_count >= 2 ) { + return SendError( playerid, "This pool table is currently full." ); + } + + // ensure this player isn't already joined + if ( ! IsPlayerPlayingPool( playerid ) && ! Iter_Contains( poolplayers< poolid >, playerid ) ) + { + Iter_Add( poolplayers< poolid >, playerid ); + + // reset variables + p_isPlayingPool{ playerid } = true; + p_PoolID[ playerid ] = poolid; + + // start the game if there's two players + if ( pool_player_count + 1 >= 2 ) + { + new + random_cuer = Iter_Random( poolplayers< poolid > ); + + Pool_SendTableMessage( poolid, COLOR_GREY, "*** %s(%d) has joined the table (2/2)", ReturnPlayerName( playerid ), playerid ); + Pool_QueueNextPlayer( poolid, random_cuer ); + + foreach ( new i : poolplayers< poolid > ) { + p_PoolScore[ i ] = 0; + PlayerPlaySound( i, 1085, 0.0, 0.0, 0.0 ); + GivePlayerWeapon( i, 7, 1 ); + } + + g_poolTableData[ poolid ] [ E_STARTED ] = true; + Pool_UpdateScoreboard( poolid ); + RespawnPoolBalls( poolid ); + } + else + { + UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], -1, sprintf( "" # COL_GREY "Pool Table\n{FFFFFF}Press ENTER To Join %s(%d)", ReturnPlayerName( playerid ), playerid ) ); + Pool_SendTableMessage( poolid, COLOR_GREY, "*** %s(%d) has joined the table (1/2)", ReturnPlayerName( playerid ), playerid ); + } + return 1; + } + } + } + } + return 1; +} + +stock Pool_RemovePlayer( playerid ) +{ + new + poolid = p_PoolID[ playerid ]; + + // reset player variables + p_isPlayingPool{ playerid } = false; + p_PoolScore[ playerid ] = 0; + p_PoolID[ playerid ] = -1; + DestroyDynamicObject( p_PoolHoleGuide[ playerid ] ); + p_PoolHoleGuide[ playerid ] = -1; + + // check if the player is even in the table + if ( poolid != -1 && Iter_Contains( poolplayers< poolid >, playerid ) ) + { + // remove them from the table + Iter_Remove( poolplayers< poolid >, playerid ); + + // forfeit player + if ( g_poolTableData[ poolid ] [ E_STARTED ] ) + { + new + replacement_winner = Iter_First( poolplayers< poolid > ); // there's only 1 guy in the table + + Pool_OnPlayerWin( poolid, replacement_winner ); + return Pool_EndGame( poolid ); + } + else + { + UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], COLOR_GREY, DEFAULT_POOL_STRING ); + } } return 1; } /* ** Functions ** */ -stock GetClosestPoolTable( playerid, &Float: dis = 99999.99 ) -{ - new - pooltable = -1; - - foreach ( new i : pooltables ) - { - new - Float: dis2 = GetPlayerDistanceFromPoint( playerid, g_poolTableData[ i ] [ E_X ], g_poolTableData[ i ] [ E_Y ], g_poolTableData[ i ] [ E_Z ] ); - - if ( dis2 < dis && dis2 != -1.00 ) - { - dis = dis2; - pooltable = i; - } - } - return pooltable; -} - stock CreatePoolTable( Float: X, Float: Y, Float: Z, Float: A = 0.0, interior = 0, world = 0 ) { if ( A != 0 && A != 90.0 && A != 180.0 && A != 270.0 && A != 360.0 ) { @@ -381,21 +442,18 @@ stock CreatePoolTable( Float: X, Float: Y, Float: Z, Float: A = 0.0, interior = g_poolTableData[ gID ] [ E_WORLD ] = world; g_poolTableData[ gID] [ E_TABLE ] = CreateDynamicObject( 2964, X, Y, Z - 1.0, 0.0, 0.0, A, world, interior ); - g_poolTableData[ gID] [ E_LABEL ] = CreateDynamic3DTextLabel( DEFAULT_POOL_STRING, COLOR_GOLD, X, Y, (Z - 0.5), 10.0, INVALID_PLAYER_ID, INVALID_VEHICLE_ID, 0, world, interior ); + g_poolTableData[ gID] [ E_LABEL ] = CreateDynamic3DTextLabel( DEFAULT_POOL_STRING, COLOR_GREY, X, Y, Z, 10.0, INVALID_PLAYER_ID, INVALID_VEHICLE_ID, 0, world, interior ); RotateXY( -0.964, -0.51, A, x_vertex[ 0 ], y_vertex[ 0 ] ); RotateXY( -0.964, 0.533, A, x_vertex[ 1 ], y_vertex[ 1 ] ); RotateXY( 0.976, -0.51, A, x_vertex[ 2 ], y_vertex[ 2 ] ); RotateXY( 0.976, 0.533, A, x_vertex[ 3 ], y_vertex[ 3 ] ); - - PHY_CreateWall( x_vertex[0] + X, y_vertex[0] + Y, x_vertex[1] + X, y_vertex[1] + Y); PHY_CreateWall( x_vertex[1] + X, y_vertex[1] + Y, x_vertex[3] + X, y_vertex[3] + Y); PHY_CreateWall( x_vertex[2] + X, y_vertex[2] + Y, x_vertex[3] + X, y_vertex[3] + Y); PHY_CreateWall( x_vertex[0] + X, y_vertex[0] + Y, x_vertex[2] + X, y_vertex[2] + Y); - #if defined POOL_DEBUG ReloadPotTestLabel( 0, gID ); /*new Float: middle_x; @@ -427,6 +485,25 @@ stock CreatePoolTable( Float: X, Float: Y, Float: Z, Float: A = 0.0, interior = return gID; } +stock GetClosestPoolTable( playerid, &Float: dis = 99999.99 ) +{ + new + pooltable = -1; + + foreach ( new i : pooltables ) + { + new + Float: dis2 = GetPlayerDistanceFromPoint( playerid, g_poolTableData[ i ] [ E_X ], g_poolTableData[ i ] [ E_Y ], g_poolTableData[ i ] [ E_Z ] ); + + if ( dis2 < dis && dis2 != -1.00 ) + { + dis = dis2; + pooltable = i; + } + } + return pooltable; +} + stock RespawnPoolBalls( poolid ) { if ( g_poolTableData[ poolid ] [ E_AIMER ] != -1 ) @@ -453,7 +530,7 @@ stock RespawnPoolBalls( poolid ) RotateXY( g_poolBallOffsetData[ i ] [ E_OFFSET_X ], g_poolBallOffsetData[ i ] [ E_OFFSET_Y ], g_poolTableData[ poolid ] [ E_ANGLE ], offset_x, offset_y ); // reset balls - if ( g_poolBallData[ i ] [ E_EXISTS ] [ i ] ) { + if ( g_poolBallData[ poolid ] [ E_EXISTS ] [ i ] ) { PHY_DeleteObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ); g_poolBallData[ poolid ] [ E_EXISTS ] [ i ] = false; } @@ -486,7 +563,7 @@ stock InitBalls(poolid, ballid) PHY_SetObjectAirResistance(g_poolBallData[poolid] [E_BALL_OBJECT] [ballid], 0.2); PHY_RollObject(g_poolBallData[poolid] [E_BALL_OBJECT] [ballid]); - g_poolBallData[poolid] [E_EXISTS] [ballid] = true; + g_poolBallData[ poolid ] [ E_EXISTS ] [ ballid ] = true; } stock RotateXY( Float: xi, Float: yi, Float: angle, &Float: xf, &Float: yf ) @@ -496,11 +573,6 @@ stock RotateXY( Float: xi, Float: yi, Float: angle, &Float: xf, &Float: yf ) return 1; } - -stock IsKeyJustUp(key, newkeys, oldkeys) { - return !(newkeys & key) && (oldkeys & key); -} - stock GetXYBehindObjectInAngle(objectid, Float:a, &Float:x2, &Float:y2, Float:distance) { new Float:z; @@ -592,11 +664,10 @@ stock Pool_UpdateScoreboard( poolid, close = 0 ) } format( szBigString, sizeof( szBigString ), - "%sIt's %s's turn.~n~~n~~r~~h~~h~%s Score:~w~ %d~n~~b~~h~~h~%s Score:~w~ %d~n~~n~%d shots remaining", + "%sIt's %s's turn.~n~~n~~r~~h~~h~%s Score:~w~ %d~n~~b~~h~~h~%s Score:~w~ %d", szBigString, ReturnPlayerName( g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ), ReturnPlayerName( first_player ), p_PoolScore[ first_player ], - ReturnPlayerName( second_player ), p_PoolScore[ second_player ], - g_poolTableData[ poolid ] [ E_CURRENT_PENALTIES ] ? 0 : g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] + ReturnPlayerName( second_player ), p_PoolScore[ second_player ] ); ShowPlayerHelpDialog( playerid, close, szBigString ); @@ -611,22 +682,22 @@ stock Pool_EndGame( poolid ) Pool_UpdateScoreboard( poolid, 5000 ); // unset pool variables - foreach ( new i : Player ) + foreach ( new i : poolplayers< poolid > ) { - if (p_PoolID[ i ] == poolid) - { - p_isPlayingPool{ i } = false; - p_PoolScore[ i ] = -1; - p_PoolID[ i ] = -1; - - removePlayerWeapon(i, 7); - } + DestroyDynamicObject( p_PoolHoleGuide[ i ] ); + p_PoolHoleGuide[ i ] = -1; + p_isPlayingPool{ i } = false; + p_PoolScore[ i ] = -1; + p_PoolID[ i ] = -1; + removePlayerWeapon( i, 7 ); } + Iter_Clear( poolplayers< poolid > ); g_poolTableData[ poolid ] [ E_STARTED ] = false; g_poolTableData[ poolid ] [ E_AIMER ] = -1; - g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ] = -1; + g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] = 0; + g_poolTableData[ poolid ] [ E_FOULS ] = 0; KillTimer(g_poolTableData[ poolid ] [ E_TIMER ]); for (new i = 0; i < 16; i ++) @@ -640,7 +711,7 @@ stock Pool_EndGame( poolid ) } } - UpdateDynamic3DTextLabelText(g_poolTableData[ poolid ] [ E_LABEL ], -1, DEFAULT_POOL_STRING); + UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], COLOR_GREY, DEFAULT_POOL_STRING ); return 1; } @@ -738,7 +809,7 @@ public OnPoolUpdate(poolid) else if (g_poolTableData[ poolid ] [ E_POWER ] > 100.0) { g_poolTableData[ poolid ] [ E_DIRECTION ] = 1; - g_poolTableData[ poolid ] [ E_POWER ] = 98.0; + g_poolTableData[ poolid ] [ E_POWER ] = 100.0; } // TextDrawTextSize(g_PoolTextdraw[2], 501.0 + ((67.0 * g_poolTableData[ poolid ] [ E_POWER ])/100.0), 0.0); @@ -750,15 +821,18 @@ public OnPoolUpdate(poolid) SetPlayerProgressBarValue(playerid, g_PoolPowerBar[playerid], ((67.0 * g_poolTableData[ poolid ] [ E_POWER ])/100.0)); ShowPlayerProgressBar(playerid, g_PoolPowerBar[playerid]); - PlayerTextDrawShow(playerid, g_PoolTextdraw[playerid]); + TextDrawShowForPlayer(playerid, g_PoolTextdraw); } } - if ( g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ] != -1 && AreAllBallsStopped( poolid ) ) + new + current_player = g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ]; + + if ( ! g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] && AreAllBallsStopped( poolid ) ) { - Pool_QueueNextPlayer( poolid, g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ], g_poolTableData[ poolid ] [ E_CURRENT_PENALTIES ] ? 2 : 1 ); - SetTimerEx("RestoreCamera", 800, 0, "dd", g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ], poolid); - g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ] = -1; + Pool_ResetBallPositions( poolid ); + Pool_QueueNextPlayer( poolid, current_player ); + SetTimerEx( "RestoreCamera", 800, 0, "dd", current_player, poolid ); } return 1; } @@ -785,7 +859,7 @@ public RestoreCamera(playerid, poolid) if (g_poolTableData[ poolid ] [ E_AIMER ] == playerid) return 0; - PlayerTextDrawHide(playerid, g_PoolTextdraw[playerid]); + TextDrawHideForPlayer(playerid, g_PoolTextdraw); HidePlayerProgressBar(playerid, g_PoolPowerBar[playerid]); TogglePlayerControllable(playerid, 1); @@ -799,10 +873,8 @@ public deleteBall(poolid, ballid) g_poolBallData[poolid] [E_EXISTS] [ballid] = false; DestroyObject(g_poolBallData[poolid] [E_BALL_OBJECT] [ballid]); PHY_DeleteObject(g_poolBallData[poolid] [E_BALL_OBJECT] [ballid]); - g_poolBallData[poolid] [E_MOVING] [ballid] = false; } - return 1; } @@ -865,11 +937,12 @@ public PHY_OnObjectUpdate( objectid ) { new first_player = Iter_First( poolplayers< poolid > ); new second_player = Iter_Last( poolplayers< poolid > ); - new current_player = g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ]; + new current_player = g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ]; new poolball_index = GetPoolBallIndexFromModel( GetObjectModel( objectid ) ); - printf ("first_player %d, second_player %d, current_player = %d", first_player, second_player, current_player); - // check if first ball was potted to figure winner + // printf ("first_player %d, second_player %d, current_player = %d", first_player, second_player, current_player); + + // check if first ball was pocketed to figure winner if ( g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED || g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_SOLID ) { if ( ++ g_poolTableData[ poolid ] [ E_BALLS_SCORED ] == 1 ) @@ -886,12 +959,16 @@ public PHY_OnObjectUpdate( objectid ) // alert players in table foreach ( new playerid : poolplayers< poolid > ) { + Player_Clearchat( playerid ); SendClientMessageFormatted( playerid, COLOR_YELLOW, "* %s(%d) is now playing as %s", ReturnPlayerName( first_player ), first_player, g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ first_player ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); SendClientMessageFormatted( playerid, COLOR_YELLOW, "* %s(%d) is playing as %s", ReturnPlayerName( second_player ), second_player, g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ second_player ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); } } } + new Float: hole_x, Float: hole_y; + + // check what was pocketed if ( g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_CUE ) { GameTextForPlayer( current_player, "~n~~n~~n~~r~~h~You have pocketed the cue ball!", 10000, 4 ); @@ -911,11 +988,15 @@ public PHY_OnObjectUpdate( objectid ) InitBalls( poolid, 0 ); } - // penalty - g_poolTableData[ poolid ] [ E_CURRENT_PENALTIES ] ++; + // penalty for that + g_poolTableData[ poolid ] [ E_FOULS ] ++; + g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] = 0; } else if ( g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_8BALL ) { + new + opposite_player = current_player != first_player ? first_player : second_player; + g_poolTableData[ poolid ] [ E_BALLS_SCORED ] ++; // restore player camera @@ -924,25 +1005,22 @@ public PHY_OnObjectUpdate( objectid ) // check if valid shot if ( p_PoolScore[ current_player ] < 7 ) { - new - winning_player = current_player != first_player ? first_player : second_player; - - foreach ( new playerid : poolplayers< poolid > ) { - SendClientMessageFormatted( playerid, COLOR_YELLOW, "%s(%d) has accidentally potted the Eight Ball ... %s(%d) wins!", ReturnPlayerName( current_player ), current_player, ReturnPlayerName( winning_player ), winning_player ); - } + Pool_SendTableMessage( poolid, COLOR_YELLOW, "%s(%d) has accidentally pocketed the 8-Ball ... %s(%d) wins!", ReturnPlayerName( current_player ), current_player, ReturnPlayerName( opposite_player ), opposite_player ); + } + else if ( g_poolTableData[ poolid ] [ E_PLAYER_8BALL_TARGET ] [ current_player ] != holeid ) + { + Pool_SendTableMessage( poolid, COLOR_YELLOW, "%s(%d) has put the 8-Ball in the wrong pocket ... %s(%d) wins!", ReturnPlayerName( current_player ), current_player, ReturnPlayerName( opposite_player ), opposite_player ); } else { - foreach ( new playerid : poolplayers< poolid > ) { - SendClientMessageFormatted( playerid, COLOR_YELLOW, "%s(%d) has the final potted the Eight Ball and won!", ReturnPlayerName( current_player ), current_player ); - } p_PoolScore[ current_player ] ++; // shows on the end result if we do it anyway here + Pool_OnPlayerWin( poolid, current_player ); } - return Pool_EndGame( current_player ); + return Pool_EndGame( poolid ); } else { - // check if player potted their own ball type or btfo + // check if player pocketed their own ball type or btfo if ( g_poolTableData[ poolid ] [ E_BALLS_SCORED ] > 1 && g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ current_player ] != g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] ) { new @@ -952,35 +1030,47 @@ public PHY_OnObjectUpdate( objectid ) GameTextForPlayer( current_player, "~n~~n~~n~~r~wrong ball", 3000, 4); foreach ( new playerid : poolplayers< poolid > ) { - SendClientMessageFormatted( playerid, COLOR_RED, "* %s(%d) has wrongly hit %s, instead of %s!", ReturnPlayerName( current_player ), current_player, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ current_player ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); + SendClientMessageFormatted( playerid, COLOR_RED, "* %s(%d) has wrongly pocketed %s, instead of %s!", ReturnPlayerName( current_player ), current_player, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ current_player ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); } - // penalty - g_poolTableData[ poolid ] [ E_CURRENT_PENALTIES ] ++; + // penalty for that + g_poolTableData[ poolid ] [ E_FOULS ] ++; + g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] = 0; } else { p_PoolScore[ current_player ] ++; GameTextForPlayer( current_player, "~n~~n~~n~~w~Score: +1", 3000, 4); - PlayerTextDrawSetString( current_player, g_PoolTextdraw[ current_player ], sprintf("Power:~n~~n~Score: %d", p_PoolScore[ current_player ])); - PlayerTextDrawHide( current_player, g_PoolTextdraw[ current_player ] ); - PlayerTextDrawShow( current_player, g_PoolTextdraw[ current_player ] ); - foreach ( new playerid : poolplayers< poolid > ) { - SendClientMessageFormatted( playerid, COLOR_YELLOW, "%s(%d) has potted a %s %s!", ReturnPlayerName( current_player ), current_player, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolBallOffsetData[ poolball_index ] [ E_BALL_NAME ] ); + SendClientMessageFormatted( playerid, COLOR_YELLOW, "%s(%d) has pocketed a %s %s!", ReturnPlayerName( current_player ), current_player, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolBallOffsetData[ poolball_index ] [ E_BALL_NAME ] ); } - format( szNormalString, sizeof( szNormalString ), "{FFDC2E}%s [%d] - [%d] %s", ReturnPlayerName( first_player ), p_PoolScore[ first_player ], p_PoolScore[ second_player ], ReturnPlayerName( second_player ) ); - UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], -1, szNormalString ); - // extra shot for scoring one's own - g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] ++; + if ( ! g_poolTableData[ poolid ] [ E_FOULS ] ) { + g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] = 1; + } + } + + // mark final target hole + if ( p_PoolScore[ first_player ] == 7 || p_PoolScore[ second_player ] == 7 ) + { + new + player_being_marked = p_PoolScore[ first_player ] == 7 ? first_player : second_player; + + if ( ! IsValidDynamicObject( p_PoolHoleGuide[ player_being_marked ] ) ) + { + new + opposite_holeid = g_poolHoleOpposite[ holeid ]; + + RotateXY( g_poolPotOffsetData[ opposite_holeid ] [ 0 ], g_poolPotOffsetData[ opposite_holeid ] [ 1 ], g_poolTableData[ poolid ] [ E_ANGLE ], hole_x, hole_y ); + p_PoolHoleGuide[ player_being_marked ] = CreateDynamicObject( 18643, g_poolTableData[ poolid ] [ E_X ] + hole_x, g_poolTableData[ poolid ] [ E_Y ] + hole_y, g_poolTableData[ poolid ] [ E_Z ] - 0.5, 0.0, -90.0, 0.0, .playerid = player_being_marked ); + g_poolTableData[ poolid ] [ E_PLAYER_8BALL_TARGET ] [ player_being_marked ] = opposite_holeid; + SendPoolMessage( player_being_marked, "You are now required to put the 8-Ball in the designated pocket." ); + } } } - new Float: hole_x, Float: hole_y; - // rotate hole offsets according to table RotateXY( g_poolPotOffsetData[ holeid ] [ 0 ], g_poolPotOffsetData[ holeid ] [ 1 ], g_poolTableData[ poolid ] [ E_ANGLE ], hole_x, hole_y ); @@ -989,35 +1079,16 @@ public PHY_OnObjectUpdate( objectid ) g_poolBallData[ poolid ] [ E_MOVING ] [ j ] = true; - SetTimerEx("deleteBall", 500, false, "dd", poolid, j); + SetTimerEx( "deleteBall", 500, false, "dd", poolid, j ); PlayerPlaySound( current_player, 31803, 0.0, 0.0, 0.0 ); // update scoreboard Pool_UpdateScoreboard( poolid ); - // if we scored about all the balls then that wraps it up - if ( p_PoolScore[ first_player ] == 8 || p_PoolScore[ second_player ] == 8 ) - { - new - winning_player = ( p_PoolScore[ first_player ] == 8 ) ? first_player : second_player; - - // restore camera - RestoreCamera( current_player, poolid ); - - // winning player - foreach ( new playerid : poolplayers< poolid > ) { - SendClientMessageFormatted( playerid, COLOR_RED, "**** %s(%d) has won %s", ReturnPlayerName( winning_player ), winning_player ); - } - return Pool_EndGame( poolid ); - } - /*else if ( AreAllBallsStopped( poolid ) ) - { - print( "Pool_QueueNextPlayer( %d, %d, %d )", poolid, current_player, next_player_shots ); - Pool_QueueNextPlayer( poolid, current_player, next_player_shots ); - SetTimerEx( "RestoreCamera", 800, false, "dd", g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ], poolid ); - g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ] = -1; - }*/ + // reset cam + Pool_QueueNextPlayer( poolid, current_player ); + SetTimerEx( "RestoreCamera", 800, 0, "dd", current_player, poolid ); } return 1; } @@ -1025,153 +1096,100 @@ public PHY_OnObjectUpdate( objectid ) return 1; } -stock Pool_QueueNextPlayer( poolid, current_player, next_player_shots = 1 ) +CMD:fakescore( playerid, params [ ]) { + p_PoolScore[ playerid ] = 6; + Pool_UpdateScoreboard(GetClosestPoolTable(playerid )); + return 1; +} + +stock Pool_OnPlayerWin( poolid, winning_player ) { - if ( g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] > 0 && g_poolTableData[ poolid ] [ E_CURRENT_PENALTIES ] < 1 ) + // restore camera + RestoreCamera( winning_player, poolid ); + + // winning player + foreach ( new playerid : poolplayers< poolid > ) { + SendClientMessageFormatted( playerid, COLOR_RED, "**** %s(%d) has won %s", ReturnPlayerName( winning_player ), winning_player ); + } + return 1; +} + +stock Pool_QueueNextPlayer( poolid, current_player ) +{ + if ( g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] > 0 && g_poolTableData[ poolid ] [ E_FOULS ] < 1 ) { - foreach ( new playerid : poolplayers< poolid > ) { - SendClientMessageFormatted( playerid, COLOR_RED, "%s(%d) has %d shots remaining!", ReturnPlayerName( current_player ), current_player, g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] ); - } + Pool_SendTableMessage( poolid, COLOR_RED, "%s(%d) has %d shots remaining!", ReturnPlayerName( current_player ), current_player, g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] ); } else { new first_player = Iter_First( poolplayers< poolid > ); new second_player = Iter_Last( poolplayers< poolid > ); - g_poolTableData[ poolid ] [ E_CURRENT_PENALTIES ] = 0; - g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] = next_player_shots; + g_poolTableData[ poolid ] [ E_FOULS ] = 0; + g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] = 1; g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] = current_player == first_player ? second_player : first_player; - foreach ( new playerid : poolplayers< poolid > ) { - SendClientMessageFormatted( playerid, COLOR_RED, "%s(%d)'s turn to %s!", ReturnPlayerName( g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ), g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ], ! g_poolTableData[ poolid ] [ E_BALLS_SCORED ] ? ( "break" ) : ( "play" ) ); - } + // reset ball positions just incase + Pool_SendTableMessage( poolid, COLOR_RED, "%s(%d)'s turn to play!", ReturnPlayerName( g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ), g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ); } // update turn Pool_UpdateScoreboard( poolid ); } -/* ** Commands ** */ - -CMD:pool(playerid, params[]) +stock Pool_SendTableMessage( poolid, colour, format[ ], va_args<> ) // Conversion to foreach 14 stuffed the define, not sure how... { - new selection[32]; + static + out[ 144 ]; - if ( sscanf( params, "s[32] ", selection) ) - return SendUsage(playerid, "/pool [INVITE/ACCEPT/DECLINE]" ); + va_format( out, sizeof( out ), format, va_start<3> ); - if ( strmatch( selection, "accept") ) - { - if ( !IsPlayerConnected(p_PoolSender[ playerid ]) ) - return SendError(playerid, "You do not have any pool game invitations to accept." ); - - if ( IsPlayerPlayingPool( playerid )) - return SendError(playerid, "You are already playing pool." ); - - new targetid = p_PoolSender[ playerid ]; - - if (GetDistanceBetweenPlayers(playerid, targetid) > 10.0) - return SendError(playerid, "You must be within 10.0 meters of your opponent!"); - - new poolid = p_PoolID[ playerid ]; - - Iter_Clear( poolplayers ); - Iter_Add( poolplayers< poolid >, playerid ); - Iter_Add( poolplayers< poolid >, targetid ); - - SendClientMessageFormatted( targetid, -1, ""COL_POOL"[SERVER]"COL_WHITE" %s(%d) has accepted your pool game invitation.", ReturnPlayerName(playerid), playerid ); - SendClientMessageFormatted( playerid, -1, ""COL_POOL"[SERVER]"COL_WHITE" You have accepted %s(%d)'s pool game invitation.", ReturnPlayerName(targetid), targetid ); - - // find a random person to break - new random_cuer = Iter_Random( poolplayers< poolid > ); - - g_poolTableData[ poolid ] [ E_BALLS_SCORED ] = 0; - g_poolTableData[ poolid ] [ E_CURRENT_SHOOTER ] = random_cuer; - - Pool_QueueNextPlayer( poolid, random_cuer ); - - //UpdateDynamicLabel(poolid, 10000, "{C0C0C0}Pool Table\n{FFFFFF}%s(%d) will be breaking!", ReturnPlayerName(g_poolTableData[ poolid ] [poolPlayer] [startid]), g_poolTableData[ poolid ] [poolPlayer] [startid]); - - - p_isPlayingPool{ playerid } = true; - p_PoolID[ playerid ] = poolid; - p_PoolScore[ playerid ] = 0; - - p_isPlayingPool{ targetid } = true; - p_PoolID[ targetid ] = poolid; - p_PoolScore[ targetid ] = 0; - - PlayerPlaySound(playerid, 1085, 0.0, 0.0, 0.0); - PlayerPlaySound(targetid, 1085, 0.0, 0.0, 0.0); - - GivePlayerWeapon(targetid, 7, 1); - GivePlayerWeapon(playerid, 7, 1); - - g_poolTableData[ poolid ] [ E_STARTED ] = true; - Pool_UpdateScoreboard( poolid ); - RespawnPoolBalls( poolid ); - return 1; + foreach ( new i : poolplayers< poolid > ) { + SendClientMessage( i, colour, out ); } - else if ( strmatch( selection, "decline") ) - { - if ( !IsPlayerConnected( p_PoolSender[ playerid ]) ) - return SendError( playerid, "You do not have any pool game invitations to decline." ); - - new targetid = p_PoolSender[ playerid ]; - - SendClientMessageFormatted( targetid, -1, ""COL_POOL"[SERVER]{FFFFFF} %s(%d) has declined your pool game invitation.", ReturnPlayerName(playerid), playerid ); - SendClientMessageFormatted( playerid, -1, ""COL_POOL"[SERVER]{FFFFFF} You have declined %s(%d)'s pool game invitation.", ReturnPlayerName(targetid), targetid ); - - return 1; - } - else if (strmatch(selection, "invite")) - { - new id = GetClosestPoolTable(playerid), targetid; - - if (id == -1) - return SendError(playerid, "You are not close enough to a pool table."); - - if (g_poolTableData[ id ] [ E_STARTED ]) - return SendError(playerid, "You cannot invite anyone to this table, since there is already a game in progress."); - - if (sscanf(params, "s[32] u", selection, targetid)) - return SendUsage(playerid, "/pool invite [PLAYER_ID]"); - - if (targetid == playerid) - return SendError(playerid, "You cannot play pool with yourself!"); - - if (targetid == INVALID_PLAYER_ID || !IsPlayerConnected(targetid)) - return SendError(playerid, "Invalid Player ID."); - - if ( IsPlayerPlayingPool( targetid )) - return SendError(playerid, "This player is already playing pool!"); - - //if (GetDistanceBetweenPlayers(playerid, targetid) > 10.0) - //return SendError(playerid, "The player you wish to play pool with is not near you."); - - if (GetPlayerWantedLevel(playerid)) - return SendError(playerid, "You can't play pool with this person right now, they are wanted"); - - // if (IsPlayerJailed(targetid)) - // return SendError(playerid, "You can't play pool with this person right now, they are currently in jail."); - - p_PoolSender[ targetid ] = playerid; - p_PoolReciever[ playerid ] = targetid; - p_PoolID[ targetid ] = id; - - SendClientMessageFormatted(playerid, -1, ""COL_POOL"[SERVER]{FFFFFF} You have sent a pool game invitation to %s(%d)!", ReturnPlayerName(targetid), targetid); - - SendClientMessageFormatted(targetid, -1, ""COL_POOL"[SERVER]{FFFFFF} You have recieved a pool game invitation by %s(%d)!", ReturnPlayerName(playerid), playerid); - SendClientMessageFormatted(targetid, -1, ""COL_POOL"[SERVER]{FFFFFF} To accept or decline the invite, use /pool [ACCEPT/DECLINE]"); - } - else - { - SendUsage(playerid, "/pool [INVITE/ACCEPT/DECLINE]"); - } - return 1; } +stock Pool_ResetBallPositions( poolid ) +{ + static Float: last_x, Float: last_y, Float: last_z; + static Float: last_rx, Float: last_ry, Float: last_rz; + + for ( new i = 0; i < sizeof( g_poolBallOffsetData ); i ++ ) if ( g_poolBallData[ poolid ] [ E_EXISTS ] [ i ] ) + { + if ( ! IsValidObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ) ) { + continue; + } + + new + modelid = GetObjectModel( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ); + + // get current position + GetObjectPos( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ], last_x, last_y, last_z ); + GetObjectRot( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ], last_rx, last_ry, last_rz ); + + // destroy object + PHY_DeleteObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ); + DestroyObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ); + + // create pool balls on table + g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] = CreateObject( modelid, last_x, last_y, last_z, last_rx, last_ry, last_rz ); + + // initialize physics on each ball + InitBalls( poolid, i ); + } +} + +/*hook OnPlayerWeaponShot( playerid, weaponid, hittype, hitid, Float: fX, Float: fY, Float: fZ ) +{ + if ( hittype == BULLET_HIT_TYPE_OBJECT ) + { + + } + return 1; +}*/ + +/* ** Commands ** */ CMD:endgame(playerid) { if ( ! IsPlayerAdmin( playerid ) ) From 3323e7f39e0f1cd776d4742be4f3b4aaad95b35d Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Fri, 14 Sep 2018 07:42:15 +1000 Subject: [PATCH 08/17] fixes turn issue when you pocket several balls --- gamemodes/irresistible/cnr/features/pool.pwn | 295 ++++++++++--------- 1 file changed, 149 insertions(+), 146 deletions(-) diff --git a/gamemodes/irresistible/cnr/features/pool.pwn b/gamemodes/irresistible/cnr/features/pool.pwn index 16b7f69..b231658 100644 --- a/gamemodes/irresistible/cnr/features/pool.pwn +++ b/gamemodes/irresistible/cnr/features/pool.pwn @@ -42,7 +42,7 @@ enum E_POOL_BALL_OFFSET_DATA }; static const - g_poolBallOffsetData[ ] [ E_POOL_BALL_OFFSET_DATA ] = + g_poolBallOffsetData[ 16 ] [ E_POOL_BALL_OFFSET_DATA ] = { { 3003, "Cueball", E_CUE, 0.5000, 0.0000 }, { 3002, "One", E_SOLID, -0.300, 0.0000 }, @@ -73,7 +73,7 @@ static const /* ** Variables ** */ enum E_POOL_BALL_DATA { - E_BALL_OBJECT[ 16 ], bool: E_EXISTS[ 16 ], bool: E_MOVING[ 16 ] + E_BALL_OBJECT[ 16 ], bool: E_POCKETED[ 16 ] }; enum E_POOL_TABLE_DATA @@ -86,6 +86,7 @@ enum E_POOL_TABLE_DATA E_NEXT_SHOOTER, E_SHOTS_LEFT, E_FOULS, E_PLAYER_8BALL_TARGET[ MAX_PLAYERS ], + bool: E_EXTRA_SHOT, Float: E_POWER, E_DIRECTION, @@ -100,7 +101,7 @@ new bool: p_isPlayingPool [ MAX_PLAYERS char ], bool: p_PoolChalking [ MAX_PLAYERS char ], - p_PoolCamera [ MAX_PLAYERS ], + bool: p_PoolCameraBirdsEye [ MAX_PLAYERS char ], p_PoolScore [ MAX_PLAYERS ], p_PoolHoleGuide [ MAX_PLAYERS ] = { -1, ... }, Float: p_PoolAngle [ MAX_PLAYERS ] [ 2 ], @@ -113,7 +114,6 @@ new ; /* ** Forwards ** */ - forward deleteBall ( poolid, ballid ); forward RestoreWeapon ( playerid ); forward RestoreCamera ( playerid, poolid ); @@ -121,7 +121,6 @@ forward OnPoolUpdate ( poolid ); forward PlayPoolSound ( poolid, soundid ); /* ** Hooks ** */ - hook OnScriptInit( ) { // textdraws @@ -201,8 +200,6 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) { if (g_poolTableData[ poolid ] [ E_AIMER ] == playerid) { - if (p_PoolCamera[ playerid ] < 2) p_PoolCamera[ playerid ] ++; - else p_PoolCamera[ playerid ] = 0; new Float:poolrot = p_PoolAngle[ playerid ] [ 0 ], Float:Xa, @@ -213,19 +210,16 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) GetObjectPos(g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], Xa, Ya, Za); - switch (p_PoolCamera[ playerid ]) + if ( ( p_PoolCameraBirdsEye{ playerid } = ! p_PoolCameraBirdsEye{ playerid } ) == false ) { - case 0: - { - GetXYBehindObjectInAngle(g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], poolrot, x, y, 0.675); - SetPlayerCameraPos(playerid, x, y, g_poolTableData[ poolid ] [ E_Z ] + DEFAULT_AIM); - SetPlayerCameraLookAt(playerid, Xa, Ya, Za + 0.170); - } - case 1 .. 2: - { - SetPlayerCameraPos(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0); - SetPlayerCameraLookAt(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ]); - } + GetXYBehindObjectInAngle(g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], poolrot, x, y, 0.675); + SetPlayerCameraPos(playerid, x, y, g_poolTableData[ poolid ] [ E_Z ] + DEFAULT_AIM); + SetPlayerCameraLookAt(playerid, Xa, Ya, Za + 0.170); + } + else + { + SetPlayerCameraPos(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0); + SetPlayerCameraLookAt(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ]); } } } @@ -250,7 +244,8 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) GetPlayerPos( playerid, X, Y, Z ); GetObjectPos( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], Xa, Ya, Za ); - new Float: distance_to_ball = GetDistanceFromPointToPoint( X, Y, Xa, Ya ); + new + Float: distance_to_ball = GetDistanceFromPointToPoint( X, Y, Xa, Ya ); if ( distance_to_ball < 1.5 && Z < 999.5 ) { @@ -264,12 +259,12 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) p_PoolAngle[ playerid ] [ 1 ] = poolrot; SetPlayerArmedWeapon(playerid, 0); - GetXYInFrontOfPos(Xa, Ya, poolrot + 180, x, y, 0.085); - g_poolTableData[ poolid ] [ E_AIMER_OBJECT ] = CreateObject(3004, x, y, Za, 7.0, 0, poolrot + 180); + GetXYInFrontOfPos( Xa, Ya, poolrot + 180, x, y, 0.085 ); + g_poolTableData[ poolid ] [ E_AIMER_OBJECT ] = CreateObject( 3004, x, y, Za, 7.0, 0, poolrot + 180 ); SetPlayerCameraPos(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0); - ApplyAnimation(playerid, "POOL", "POOL_Med_Start", 50.0, 0, 0, 0, 1, 1, 1); + ApplyAnimation( playerid, "POOL", "POOL_Med_Start", 4.1, 0, 1, 1, 0, 0, 1 ); g_poolTableData[ poolid ] [ E_AIMER ] = playerid; g_poolTableData[ poolid ] [ E_POWER ] = 1.0; @@ -287,11 +282,12 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) TogglePlayerControllable(playerid, true); GivePlayerWeapon(playerid, 7, 1); - ApplyAnimation(playerid, "CARRY", "crry_prtial", 1.0, 0, 0, 0, 0, 0, 1); - SetCameraBehindPlayer(playerid); + ClearAnimations( playerid ); + SetCameraBehindPlayer( playerid ); g_poolTableData[ poolid ] [ E_AIMER ] = -1; - DestroyObject(g_poolTableData[ poolid ] [ E_AIMER_OBJECT ]); + DestroyObject( g_poolTableData[ poolid ] [ E_AIMER_OBJECT ] ); + g_poolTableData[ poolid ] [ E_AIMER_OBJECT ] = -1; } } } @@ -300,15 +296,18 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) { if ( g_poolTableData[ poolid ] [ E_AIMER ] == playerid ) { - new - Float: speed; + new Float: ball_x, Float: ball_y, Float: ball_z; + new Float: speed; g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] --; Pool_UpdateScoreboard( poolid ); - ApplyAnimation( playerid, "POOL", "POOL_Med_Shot", 3.0, 0, 0, 0, 0, 0, 1 ); - speed = 0.4 + (g_poolTableData[ poolid ] [ E_POWER ] * 2.0) / 100.0; + GetObjectPos( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], ball_x, ball_y, ball_z ); + + ApplyAnimation( playerid, "POOL", "POOL_Med_Shot", 4.1, 0, 1, 1, 0, 0, 1); + + speed = 0.4 + ( g_poolTableData[ poolid ] [ E_POWER ] * 2.0 ) / 100.0; PHY_SetObjectVelocity(g_poolBallData[poolid] [E_BALL_OBJECT] [0], speed * floatsin(-p_PoolAngle[ playerid ] [ 0 ], degrees), speed * floatcos(-p_PoolAngle[ playerid ] [ 0 ], degrees)); SetPlayerCameraPos(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0); @@ -317,6 +316,7 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) PlayPoolSound(poolid, 31810); g_poolTableData[ poolid ] [ E_AIMER ] = -1; DestroyObject( g_poolTableData[ poolid ] [ E_AIMER_OBJECT ] ); + g_poolTableData[ poolid ] [ E_AIMER_OBJECT ] = -1; GivePlayerWeapon( playerid, 7, 1 ); } @@ -512,8 +512,9 @@ stock RespawnPoolBalls( poolid ) //ClearAnimations(g_poolTableData[ poolid ] [ E_AIMER ]); //ApplyAnimation(g_poolTableData[ poolid ] [ E_AIMER ], "CARRY", "crry_prtial", 1.0, 0, 0, 0, 0, 0); - SetCameraBehindPlayer(g_poolTableData[ poolid ] [ E_AIMER ]); - DestroyObject(g_poolTableData[ poolid ] [ E_AIMER_OBJECT ]); + SetCameraBehindPlayer( g_poolTableData[ poolid ] [ E_AIMER ] ); + DestroyObject( g_poolTableData[ poolid ] [ E_AIMER_OBJECT ] ); + g_poolTableData[ poolid ] [ E_AIMER_OBJECT ] = -1; //TextDrawHideForPlayer(g_poolTableData[ poolid ] [ E_AIMER ], gPoolTD); //HidePlayerProgressBar(g_poolTableData[ poolid ] [ E_AIMER ], g_PoolPowerBar[g_poolTableData[ poolid ] [ E_AIMER ]]); @@ -530,11 +531,10 @@ stock RespawnPoolBalls( poolid ) RotateXY( g_poolBallOffsetData[ i ] [ E_OFFSET_X ], g_poolBallOffsetData[ i ] [ E_OFFSET_Y ], g_poolTableData[ poolid ] [ E_ANGLE ], offset_x, offset_y ); // reset balls - if ( g_poolBallData[ poolid ] [ E_EXISTS ] [ i ] ) { + if ( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] != -1 ) { PHY_DeleteObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ); - g_poolBallData[ poolid ] [ E_EXISTS ] [ i ] = false; + DestroyObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ); } - DestroyObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ); // create pool balls on table g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] = CreateObject( @@ -563,7 +563,7 @@ stock InitBalls(poolid, ballid) PHY_SetObjectAirResistance(g_poolBallData[poolid] [E_BALL_OBJECT] [ballid], 0.2); PHY_RollObject(g_poolBallData[poolid] [E_BALL_OBJECT] [ballid]); - g_poolBallData[ poolid ] [ E_EXISTS ] [ ballid ] = true; + g_poolBallData[ poolid ] [ E_POCKETED ] [ ballid ] = false; } stock RotateXY( Float: xi, Float: yi, Float: angle, &Float: xf, &Float: yf ) @@ -585,16 +585,22 @@ stock GetXYBehindObjectInAngle(objectid, Float:a, &Float:x2, &Float:y2, Float:di stock AreAllBallsStopped( poolid ) { new - Float: x, Float: y, Float: z; + balls_not_moving = 0; - for ( new i = 0; i < 16; i ++ ) if ( g_poolBallData[ poolid ] [ E_EXISTS ] [ i ] ) - { - PHY_GetObjectVelocity( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ], x, y, z ); + new bool: checklist[ 16]; - if ( x != 0.0 || y != 0.0 ) - return 0; + for ( new i = 0; i < 16; i ++ ) if ( g_poolBallData[ poolid ] [ E_POCKETED ] [ i ] || ! PHY_IsObjectMoving( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ) ) { + balls_not_moving ++; + checklist[i] = true; } - return 1; + + szBigString = ""; + for ( new i = 0; i < 16; i++ ) { + if ( checklist[i] == false ) format( szBigString, sizeof(szBigString), "%s%s(%d), ", szBigString, g_poolBallOffsetData[i][E_BALL_NAME], i); + } + printf("not stopped: %s", szBigString); + + return balls_not_moving >= 16; } stock GetAngleToXY(Float:X, Float:Y, Float:CurrX, Float:CurrY, &Float:angle) @@ -695,20 +701,17 @@ stock Pool_EndGame( poolid ) Iter_Clear( poolplayers< poolid > ); g_poolTableData[ poolid ] [ E_STARTED ] = false; - g_poolTableData[ poolid ] [ E_AIMER ] = -1; + g_poolTableData[ poolid ] [ E_AIMER ] = -1; g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] = 0; g_poolTableData[ poolid ] [ E_FOULS ] = 0; + g_poolTableData[ poolid ] [ E_EXTRA_SHOT ] = false; KillTimer(g_poolTableData[ poolid ] [ E_TIMER ]); - for (new i = 0; i < 16; i ++) - { - DestroyObject(g_poolBallData[poolid] [E_BALL_OBJECT] [i]); - if (g_poolBallData[poolid] [E_EXISTS] [i]) - { - PHY_DeleteObject(g_poolBallData[poolid] [E_BALL_OBJECT] [i]); - g_poolBallData[poolid] [E_EXISTS] [i] = false; - } + for ( new i = 0; i < 16; i ++ ) if ( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] != -1 ) { + PHY_DeleteObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ); + DestroyObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ); + g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] = -1; } UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], COLOR_GREY, DEFAULT_POOL_STRING ); @@ -742,10 +745,10 @@ public PlayPoolSound( poolid, soundid ) { public OnPoolUpdate(poolid) { - if (!g_poolTableData[ poolid ] [ E_STARTED ]) + if ( ! g_poolTableData[ poolid ] [ E_STARTED ] ) return 0; - if (g_poolTableData[ poolid ] [ E_AIMER ] != -1) + if ( g_poolTableData[ poolid ] [ E_AIMER ] != -1 ) { new playerid = g_poolTableData[ poolid ] [ E_AIMER ], keys, ud, lr; @@ -762,23 +765,25 @@ public OnPoolUpdate(poolid) newrot = p_PoolAngle[ playerid ] [ 0 ] + (lr > 0 ? 0.9 : -0.9); dist = GetDistanceBetweenPoints( X, Y, 0.0, Xa, Ya, 0.0 ); + printf("%f", dist); + if ( dist < 0.85 ) { + dist = 0.85; + } + if (AngleInRangeOfAngle(p_PoolAngle[ playerid ] [ 1 ], newrot, 30.0)) { p_PoolAngle[ playerid ] [ 0 ] = newrot; - switch (p_PoolCamera[ playerid ]) - { - case 0: - { - GetXYBehindObjectInAngle(g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], newrot, x, y, 0.675); - SetPlayerCameraPos(playerid, x, y, g_poolTableData[ poolid ] [ E_Z ] + DEFAULT_AIM); - SetPlayerCameraLookAt(playerid, Xa, Ya, Za + 0.170); - } - case 1, 2: - { - SetPlayerCameraPos(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0); - SetPlayerCameraLookAt(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ]); - } + if ( ! p_PoolCameraBirdsEye{ playerid } ) + { + GetXYBehindObjectInAngle(g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], newrot, x, y, 0.675); + SetPlayerCameraPos(playerid, x, y, g_poolTableData[ poolid ] [ E_Z ] + DEFAULT_AIM); + SetPlayerCameraLookAt(playerid, Xa, Ya, Za + 0.170); + } + else + { + SetPlayerCameraPos(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0); + SetPlayerCameraLookAt(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ]); } GetXYInFrontOfPos(Xa, Ya, newrot + 180, x, y, 0.085); @@ -812,9 +817,6 @@ public OnPoolUpdate(poolid) g_poolTableData[ poolid ] [ E_POWER ] = 100.0; } - // TextDrawTextSize(g_PoolTextdraw[2], 501.0 + ((67.0 * g_poolTableData[ poolid ] [ E_POWER ])/100.0), 0.0); - // TextDrawShowForPlayer(playerid, g_PoolTextdraw[2]); - // ShowPlayerPoolTextdraw(playerid); SetPlayerProgressBarMaxValue(playerid, g_PoolPowerBar[playerid], 67.0); @@ -828,9 +830,8 @@ public OnPoolUpdate(poolid) new current_player = g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ]; - if ( ! g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] && AreAllBallsStopped( poolid ) ) + if ( ( ! g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] || g_poolTableData[ poolid ] [ E_FOULS ] || g_poolTableData[ poolid ] [ E_EXTRA_SHOT ] ) && AreAllBallsStopped( poolid ) ) { - Pool_ResetBallPositions( poolid ); Pool_QueueNextPlayer( poolid, current_player ); SetTimerEx( "RestoreCamera", 800, 0, "dd", current_player, poolid ); } @@ -839,24 +840,7 @@ public OnPoolUpdate(poolid) public RestoreCamera(playerid, poolid) { - if (!g_poolBallData[poolid] [E_EXISTS] [0]) - { - DestroyObject(g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ]); - - new Float: x, Float: y, Float: pos[3], Float: angle; - - pos[0] = g_poolTableData[ poolid ] [ E_X ]; - pos[1] = g_poolTableData[ poolid ] [ E_Y ]; - pos[2] = g_poolTableData[ poolid ] [ E_Z ]; - angle = g_poolTableData[ poolid ] [ E_ANGLE ]; - - RotateXY(0.5, 0.0, angle, x, y); - g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ] = CreateObject(3003, x + pos[0], y + pos[1], (pos[2] - 0.045), 0, 0, 0); - - InitBalls(poolid, 0); - } - - if (g_poolTableData[ poolid ] [ E_AIMER ] == playerid) + if ( g_poolTableData[ poolid ] [ E_AIMER ] == playerid ) return 0; TextDrawHideForPlayer(playerid, g_PoolTextdraw); @@ -866,14 +850,13 @@ public RestoreCamera(playerid, poolid) return SetCameraBehindPlayer(playerid); } -public deleteBall(poolid, ballid) +public deleteBall( poolid, ballid ) { - if (g_poolBallData[poolid] [E_MOVING] [ballid]) + if ( g_poolBallData[ poolid ] [ E_POCKETED ] [ ballid ] && g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ ballid ] != -1 ) { - g_poolBallData[poolid] [E_EXISTS] [ballid] = false; - DestroyObject(g_poolBallData[poolid] [E_BALL_OBJECT] [ballid]); - PHY_DeleteObject(g_poolBallData[poolid] [E_BALL_OBJECT] [ballid]); - g_poolBallData[poolid] [E_MOVING] [ballid] = false; + PHY_DeleteObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ ballid ] ); + DestroyObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ ballid ] ); + g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ ballid ] = -1; } return 1; } @@ -895,15 +878,15 @@ stock GetPoolBallIndexFromModel( modelid ) { } /** * Physics Callbacks * **/ -public PHY_OnObjectCollideWithObject(object1, object2) +public PHY_OnObjectCollideWithObject( object1, object2 ) { foreach ( new id : pooltables ) if ( g_poolTableData[ id ] [ E_STARTED ] ) { - for (new i = 0; i < 16; i++) + for ( new i = 0; i < 16; i ++ ) { - if (object1 == g_poolBallData[id] [E_BALL_OBJECT] [i]) + if ( object1 == g_poolBallData[ id ] [ E_BALL_OBJECT ] [ i ] ) { - PlayPoolSound(id, 31800 + random(3)); + PlayPoolSound( id, 31800 + random( 3 ) ); return 1; } } @@ -917,7 +900,7 @@ public PHY_OnObjectCollideWithWall( objectid, wallid ) { for ( new i = 0; i < 16; i ++ ) if ( objectid == g_poolBallData[ id ] [ E_BALL_OBJECT ] [ i ] ) { - PlayPoolSound(id, 31808); + PlayPoolSound( id, 31808 ); return 1; } } @@ -926,9 +909,16 @@ public PHY_OnObjectCollideWithWall( objectid, wallid ) public PHY_OnObjectUpdate( objectid ) { + new + poolball_index = GetPoolBallIndexFromModel( GetObjectModel( objectid ) ); + + if ( poolball_index == -1 ) { + return 1; + } + foreach ( new poolid : pooltables ) if ( g_poolTableData[ poolid ] [ E_STARTED ] ) { - for ( new j = 0; j < 16; j ++ ) if ( objectid == g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ j ] && ! g_poolBallData[ poolid ] [ E_MOVING ] [ j ] && PHY_IsObjectMoving( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ j ] ) ) + if ( objectid == g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ poolball_index ] && ! g_poolBallData[ poolid ] [ E_POCKETED ] [ poolball_index ] && PHY_IsObjectMoving( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ poolball_index ] ) ) { new holeid = IsBallInHole( poolid, objectid ); @@ -938,7 +928,6 @@ public PHY_OnObjectUpdate( objectid ) new first_player = Iter_First( poolplayers< poolid > ); new second_player = Iter_Last( poolplayers< poolid > ); new current_player = g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ]; - new poolball_index = GetPoolBallIndexFromModel( GetObjectModel( objectid ) ); // printf ("first_player %d, second_player %d, current_player = %d", first_player, second_player, current_player); @@ -973,24 +962,10 @@ public PHY_OnObjectUpdate( objectid ) { GameTextForPlayer( current_player, "~n~~n~~n~~r~~h~You have pocketed the cue ball!", 10000, 4 ); - // respawn the cue ball - if ( ! g_poolBallData[ poolid ] [ E_EXISTS ] [ 0 ] ) - { - - new - Float: x, Float: y; - - RotateXY( 0.5, 0.0, g_poolTableData[ poolid ] [ E_ANGLE ], x, y ); - - DestroyObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ] ); - g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ] = CreateObject( 3003, g_poolTableData[ poolid ] [ E_X ] + x, g_poolTableData[ poolid ] [ E_Y ] + y, g_poolTableData[ poolid ] [ E_Z ], 0.0, 0.0, 0.0 ); - - InitBalls( poolid, 0 ); - } - // penalty for that g_poolTableData[ poolid ] [ E_FOULS ] ++; g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] = 0; + g_poolTableData[ poolid ] [ E_EXTRA_SHOT ] = false; } else if ( g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_8BALL ) { @@ -1005,15 +980,17 @@ public PHY_OnObjectUpdate( objectid ) // check if valid shot if ( p_PoolScore[ current_player ] < 7 ) { + p_PoolScore[ opposite_player ] ++; Pool_SendTableMessage( poolid, COLOR_YELLOW, "%s(%d) has accidentally pocketed the 8-Ball ... %s(%d) wins!", ReturnPlayerName( current_player ), current_player, ReturnPlayerName( opposite_player ), opposite_player ); } else if ( g_poolTableData[ poolid ] [ E_PLAYER_8BALL_TARGET ] [ current_player ] != holeid ) { + p_PoolScore[ opposite_player ] ++; Pool_SendTableMessage( poolid, COLOR_YELLOW, "%s(%d) has put the 8-Ball in the wrong pocket ... %s(%d) wins!", ReturnPlayerName( current_player ), current_player, ReturnPlayerName( opposite_player ), opposite_player ); } else { - p_PoolScore[ current_player ] ++; // shows on the end result if we do it anyway here + p_PoolScore[ current_player ] ++; Pool_OnPlayerWin( poolid, current_player ); } return Pool_EndGame( poolid ); @@ -1030,12 +1007,13 @@ public PHY_OnObjectUpdate( objectid ) GameTextForPlayer( current_player, "~n~~n~~n~~r~wrong ball", 3000, 4); foreach ( new playerid : poolplayers< poolid > ) { - SendClientMessageFormatted( playerid, COLOR_RED, "* %s(%d) has wrongly pocketed %s, instead of %s!", ReturnPlayerName( current_player ), current_player, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ current_player ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); + SendClientMessageFormatted( playerid, COLOR_RED, "* %s(%d) has wrongly pocketed %s %s, instead of %s!", ReturnPlayerName( current_player ), current_player, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolBallOffsetData[ poolball_index ] [ E_BALL_NAME ], g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ current_player ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); } // penalty for that g_poolTableData[ poolid ] [ E_FOULS ] ++; g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] = 0; + g_poolTableData[ poolid ] [ E_EXTRA_SHOT ] = false; } else { @@ -1047,9 +1025,8 @@ public PHY_OnObjectUpdate( objectid ) } // extra shot for scoring one's own - if ( ! g_poolTableData[ poolid ] [ E_FOULS ] ) { - g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] = 1; - } + g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] = g_poolTableData[ poolid ] [ E_FOULS ] > 0 ? 0 : 1; + g_poolTableData[ poolid ] [ E_EXTRA_SHOT ] = true; } // mark final target hole @@ -1067,6 +1044,7 @@ public PHY_OnObjectUpdate( objectid ) p_PoolHoleGuide[ player_being_marked ] = CreateDynamicObject( 18643, g_poolTableData[ poolid ] [ E_X ] + hole_x, g_poolTableData[ poolid ] [ E_Y ] + hole_y, g_poolTableData[ poolid ] [ E_Z ] - 0.5, 0.0, -90.0, 0.0, .playerid = player_being_marked ); g_poolTableData[ poolid ] [ E_PLAYER_8BALL_TARGET ] [ player_being_marked ] = opposite_holeid; SendPoolMessage( player_being_marked, "You are now required to put the 8-Ball in the designated pocket." ); + Streamer_Update( player_being_marked ); } } } @@ -1075,20 +1053,24 @@ public PHY_OnObjectUpdate( objectid ) RotateXY( g_poolPotOffsetData[ holeid ] [ 0 ], g_poolPotOffsetData[ holeid ] [ 1 ], g_poolTableData[ poolid ] [ E_ANGLE ], hole_x, hole_y ); // move object into the pocket - MoveObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ j ], g_poolTableData[ poolid ] [ E_X ] + hole_x, g_poolTableData[ poolid ] [ E_Y ] + hole_y, g_poolTableData[ poolid ] [ E_Z ] - 0.5, 1.0); + new move_speed = MoveObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ poolball_index ], g_poolTableData[ poolid ] [ E_X ] + hole_x, g_poolTableData[ poolid ] [ E_Y ] + hole_y, g_poolTableData[ poolid ] [ E_Z ] - 0.5, 1.0); - g_poolBallData[ poolid ] [ E_MOVING ] [ j ] = true; + // mark ball as pocketed + g_poolBallData[ poolid ] [ E_POCKETED ] [ poolball_index ] = true; - SetTimerEx( "deleteBall", 500, false, "dd", poolid, j ); - - PlayerPlaySound( current_player, 31803, 0.0, 0.0, 0.0 ); + // delete it anyway + SetTimerEx( "deleteBall", move_speed + 100, false, "dd", poolid, poolball_index ); // update scoreboard Pool_UpdateScoreboard( poolid ); + PlayerPlaySound( current_player, 31803, 0.0, 0.0, 0.0 ); // reset cam - Pool_QueueNextPlayer( poolid, current_player ); - SetTimerEx( "RestoreCamera", 800, 0, "dd", current_player, poolid ); + /*if ( AreAllBallsStopped( poolid ) ) { + printf ( "Second %d" , g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] ); + Pool_QueueNextPlayer( poolid, g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ); + SetTimerEx( "RestoreCamera", 800, 0, "dd", current_player, poolid ); + }*/ } return 1; } @@ -1096,14 +1078,11 @@ public PHY_OnObjectUpdate( objectid ) return 1; } -CMD:fakescore( playerid, params [ ]) { - p_PoolScore[ playerid ] = 6; - Pool_UpdateScoreboard(GetClosestPoolTable(playerid )); - return 1; -} - stock Pool_OnPlayerWin( poolid, winning_player ) { + if ( ! IsPlayerConnected( winning_player ) ) + return 0; + // restore camera RestoreCamera( winning_player, poolid ); @@ -1116,9 +1095,10 @@ stock Pool_OnPlayerWin( poolid, winning_player ) stock Pool_QueueNextPlayer( poolid, current_player ) { - if ( g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] > 0 && g_poolTableData[ poolid ] [ E_FOULS ] < 1 ) + if ( g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] && g_poolTableData[ poolid ] [ E_FOULS ] < 1 ) { - Pool_SendTableMessage( poolid, COLOR_RED, "%s(%d) has %d shots remaining!", ReturnPlayerName( current_player ), current_player, g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] ); + g_poolTableData[ poolid ] [ E_EXTRA_SHOT ] = false; + Pool_SendTableMessage( poolid, COLOR_RED, "%s(%d) has %d shot remaining!", ReturnPlayerName( current_player ), current_player, g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] ); } else { @@ -1127,14 +1107,36 @@ stock Pool_QueueNextPlayer( poolid, current_player ) g_poolTableData[ poolid ] [ E_FOULS ] = 0; g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] = 1; + g_poolTableData[ poolid ] [ E_EXTRA_SHOT ] = false; g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] = current_player == first_player ? second_player : first_player; // reset ball positions just incase Pool_SendTableMessage( poolid, COLOR_RED, "%s(%d)'s turn to play!", ReturnPlayerName( g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ), g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ); } + // respawn the cue ball if it has been pocketed + if ( g_poolBallData[ poolid ] [ E_POCKETED ] [ 0 ] ) + { + new + Float: x, Float: y; + + RotateXY( 0.5, 0.0, g_poolTableData[ poolid ] [ E_ANGLE ], x, y ); + + // make sure object dont exist + if ( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ] != -1 ) { + PHY_DeleteObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ] ); + DestroyObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ] ); + } + + // recreate cueball + g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ] = CreateObject( 3003, g_poolTableData[ poolid ] [ E_X ] + x, g_poolTableData[ poolid ] [ E_Y ] + y, g_poolTableData[ poolid ] [ E_Z ] - 0.045, 0.0, 0.0, 0.0 ); + + InitBalls( poolid, 0 ); + } + // update turn Pool_UpdateScoreboard( poolid ); + Pool_ResetBallPositions( poolid ); } stock Pool_SendTableMessage( poolid, colour, format[ ], va_args<> ) // Conversion to foreach 14 stuffed the define, not sure how... @@ -1155,11 +1157,10 @@ stock Pool_ResetBallPositions( poolid ) static Float: last_x, Float: last_y, Float: last_z; static Float: last_rx, Float: last_ry, Float: last_rz; - for ( new i = 0; i < sizeof( g_poolBallOffsetData ); i ++ ) if ( g_poolBallData[ poolid ] [ E_EXISTS ] [ i ] ) + for ( new i = 0; i < sizeof( g_poolBallOffsetData ); i ++ ) if ( ! g_poolBallData[ poolid ] [ E_POCKETED ] [ i ] ) { - if ( ! IsValidObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ) ) { + if ( ! IsValidObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ) ) continue; - } new modelid = GetObjectModel( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ); @@ -1169,8 +1170,10 @@ stock Pool_ResetBallPositions( poolid ) GetObjectRot( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ], last_rx, last_ry, last_rz ); // destroy object - PHY_DeleteObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ); - DestroyObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ); + if ( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] != -1 ) { + PHY_DeleteObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ); + DestroyObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ); + } // create pool balls on table g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] = CreateObject( modelid, last_x, last_y, last_z, last_rx, last_ry, last_rz ); @@ -1180,14 +1183,14 @@ stock Pool_ResetBallPositions( poolid ) } } -/*hook OnPlayerWeaponShot( playerid, weaponid, hittype, hitid, Float: fX, Float: fY, Float: fZ ) +hook OnPlayerWeaponShot( playerid, weaponid, hittype, hitid, Float: fX, Float: fY, Float: fZ ) { if ( hittype == BULLET_HIT_TYPE_OBJECT ) { } return 1; -}*/ +} /* ** Commands ** */ CMD:endgame(playerid) @@ -1224,7 +1227,7 @@ CMD:play(playerid) p_PoolScore[ playerid ] = 0; - if (!g_poolTableData[ iPool ] [ E_STARTED ]) + if ( ! g_poolTableData[ iPool ] [ E_STARTED ] ) { g_poolTableData[ iPool ] [ E_STARTED ] = true; From 1301f7ef0aeb56e10d543c0000912c9b07d66aa1 Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Fri, 14 Sep 2018 07:42:26 +1000 Subject: [PATCH 09/17] remove pool table from player home (panther) --- gamemodes/irresistible/cnr/static/player_objects.pwn | 2 -- 1 file changed, 2 deletions(-) diff --git a/gamemodes/irresistible/cnr/static/player_objects.pwn b/gamemodes/irresistible/cnr/static/player_objects.pwn index 84d93fe..bbc63cf 100644 --- a/gamemodes/irresistible/cnr/static/player_objects.pwn +++ b/gamemodes/irresistible/cnr/static/player_objects.pwn @@ -10102,8 +10102,6 @@ stock initializeObjects( ) SetDynamicObjectMaterial( CreateDynamicObject( 19454, -1016.496459, 1044.522705, 4.096351, 0.000000, 90.000000, 90.000000 ), 0, 9495, "vict_sfw", "newall10_seamless", 0 ); SetDynamicObjectMaterial( CreateDynamicObject( 19454, -1021.718627, 1047.973510, 5.768362, 0.000000, 0.000000, 90.000000 ), 0, 9495, "vict_sfw", "newall10_seamless", 0 ); SetDynamicObjectMaterial( CreateDynamicObject( 19454, -1015.137634, 1047.953491, 5.768362, 0.000000, 0.000000, 90.000000 ), 0, 9495, "vict_sfw", "newall10_seamless", 0 ); - CreateDynamicObject( 14651, -1015.541442, 1046.419067, 2.917308, 0.000000, 0.000000, 90.000000 ); - CreateDynamicObject( 14651, -1021.812072, 1046.419067, 2.917308, 0.000000, 0.000000, 90.000000 ); CreateDynamicObject( 948, -1007.720397, 1060.881591, 0.792823, 0.000000, 0.000000, 0.000000 ); CreateDynamicObject( 948, -1007.720397, 1048.316772, 0.792823, 0.000000, 0.000000, 0.000000 ); CreateDynamicObject( 1827, -1010.351501, 1054.650146, 0.757999, 0.000000, 0.000000, 0.000000 ); From c8b143f65bedab07975c083f773460897567aa9a Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Fri, 14 Sep 2018 07:57:25 +1000 Subject: [PATCH 10/17] if a player shoots a pool ball, restore the ball's position and desync the shot --- gamemodes/irresistible/cnr/features/pool.pwn | 35 +++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/gamemodes/irresistible/cnr/features/pool.pwn b/gamemodes/irresistible/cnr/features/pool.pwn index b231658..cf455f4 100644 --- a/gamemodes/irresistible/cnr/features/pool.pwn +++ b/gamemodes/irresistible/cnr/features/pool.pwn @@ -19,7 +19,9 @@ #define DEFAULT_AIM 0.38 #define DEFAULT_POOL_STRING "Pool Table\n{FFFFFF}Press ENTER To Play" -#define MAX_TABLES 32 +#define MAX_POOL_TABLES 32 +#define MAX_POOL_BALLS 16 // do not modify + #define COL_POOL "{C0C0C0}" /* ** Macros ** */ @@ -42,7 +44,7 @@ enum E_POOL_BALL_OFFSET_DATA }; static const - g_poolBallOffsetData[ 16 ] [ E_POOL_BALL_OFFSET_DATA ] = + g_poolBallOffsetData[ MAX_POOL_BALLS ] [ E_POOL_BALL_OFFSET_DATA ] = { { 3003, "Cueball", E_CUE, 0.5000, 0.0000 }, { 3002, "One", E_SOLID, -0.300, 0.0000 }, @@ -94,8 +96,8 @@ enum E_POOL_TABLE_DATA } new - g_poolTableData [ MAX_TABLES ] [ E_POOL_TABLE_DATA ], - g_poolBallData [ MAX_TABLES ] [ E_POOL_BALL_DATA ], + g_poolTableData [ MAX_POOL_TABLES ] [ E_POOL_TABLE_DATA ], + g_poolBallData [ MAX_POOL_TABLES ] [ E_POOL_BALL_DATA ], p_PoolID [ MAX_PLAYERS ] = { -1, ... }, @@ -109,8 +111,8 @@ new PlayerBar: g_PoolPowerBar [ MAX_PLAYERS ], Text: g_PoolTextdraw = Text: INVALID_TEXT_DRAW, - Iterator: pooltables < MAX_TABLES >, - Iterator: poolplayers < MAX_TABLES, MAX_PLAYERS > + Iterator: pooltables < MAX_POOL_TABLES >, + Iterator: poolplayers < MAX_POOL_TABLES, MAX_PLAYERS > ; /* ** Forwards ** */ @@ -1152,12 +1154,12 @@ stock Pool_SendTableMessage( poolid, colour, format[ ], va_args<> ) // Conversio return 1; } -stock Pool_ResetBallPositions( poolid ) +stock Pool_ResetBallPositions( poolid, begining_ball = 0, last_ball = MAX_POOL_BALLS ) { static Float: last_x, Float: last_y, Float: last_z; static Float: last_rx, Float: last_ry, Float: last_rz; - for ( new i = 0; i < sizeof( g_poolBallOffsetData ); i ++ ) if ( ! g_poolBallData[ poolid ] [ E_POCKETED ] [ i ] ) + for ( new i = begining_ball; i < last_ball; i ++ ) if ( ! g_poolBallData[ poolid ] [ E_POCKETED ] [ i ] ) { if ( ! IsValidObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ) ) continue; @@ -1185,9 +1187,18 @@ stock Pool_ResetBallPositions( poolid ) hook OnPlayerWeaponShot( playerid, weaponid, hittype, hitid, Float: fX, Float: fY, Float: fZ ) { - if ( hittype == BULLET_HIT_TYPE_OBJECT ) - { + // check if a player shot a pool ball and restore it + if ( hittype == BULLET_HIT_TYPE_OBJECT ) { + new + poolball_index = GetPoolBallIndexFromModel( GetObjectModel( hitid ) ); + if ( poolball_index != -1 ) { + foreach ( new poolid : pooltables ) if ( g_poolTableData[ poolid ] [ E_STARTED ] ) { + Pool_ResetBallPositions( poolid, poolball_index, poolball_index + 1 ); + break; + } + return 0; // desync the shot + } } return 1; } @@ -1267,8 +1278,8 @@ CMD:addpool(playerid, params[]) /* ** Debug Mode ** */ #if defined POOL_DEBUG - new potlabels_x[MAX_TABLES][sizeof(g_poolPotOffsetData)]; - new potlabels[MAX_TABLES][sizeof(g_poolPotOffsetData)][36]; + new potlabels_x[MAX_POOL_TABLES][sizeof(g_poolPotOffsetData)]; + new potlabels[MAX_POOL_TABLES][sizeof(g_poolPotOffsetData)][36]; CMD:camtest( playerid, params[ ] ) { From a8c06186a45b69669ee16d2bfe90907253844b65 Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Fri, 14 Sep 2018 08:38:40 +1000 Subject: [PATCH 11/17] format messages and let him keep the pool cue --- gamemodes/irresistible/cnr/features/pool.pwn | 73 +++++++------------- 1 file changed, 25 insertions(+), 48 deletions(-) diff --git a/gamemodes/irresistible/cnr/features/pool.pwn b/gamemodes/irresistible/cnr/features/pool.pwn index cf455f4..c2e235f 100644 --- a/gamemodes/irresistible/cnr/features/pool.pwn +++ b/gamemodes/irresistible/cnr/features/pool.pwn @@ -118,7 +118,7 @@ new /* ** Forwards ** */ forward deleteBall ( poolid, ballid ); forward RestoreWeapon ( playerid ); -forward RestoreCamera ( playerid, poolid ); +forward RestoreCamera ( playerid ); forward OnPoolUpdate ( poolid ); forward PlayPoolSound ( poolid, soundid ); @@ -200,7 +200,7 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) { if ( RELEASED( KEY_JUMP ) ) { - if (g_poolTableData[ poolid ] [ E_AIMER ] == playerid) + if ( g_poolTableData[ poolid ] [ E_AIMER ] == playerid ) { new Float:poolrot = p_PoolAngle[ playerid ] [ 0 ], @@ -233,7 +233,7 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) if ( g_poolTableData[ poolid ] [ E_AIMER ] != playerid ) { if ( g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] != playerid ) { - return SendError( playerid, "It is not your turn. Please wait." ); + return SendPoolMessage( playerid, "It is not your turn. Please wait." ); } if ( ! p_PoolChalking{ playerid } && g_poolTableData[ poolid ] [ E_AIMER ] == -1 ) @@ -331,7 +331,7 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) if ( PRESSED( KEY_SECONDARY_ATTACK ) ) { if ( IsPlayerPlayingPool( playerid ) ) { - Pool_SendTableMessage( poolid, COLOR_GREY, "*** %s(%d) has left the table", ReturnPlayerName( playerid ), playerid ); + Pool_SendTableMessage( poolid, COLOR_GREY, "-- "COL_WHITE" %s(%d) has left the table", ReturnPlayerName( playerid ), playerid ); return Pool_RemovePlayer( playerid ); } @@ -357,7 +357,7 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) new random_cuer = Iter_Random( poolplayers< poolid > ); - Pool_SendTableMessage( poolid, COLOR_GREY, "*** %s(%d) has joined the table (2/2)", ReturnPlayerName( playerid ), playerid ); + Pool_SendTableMessage( poolid, COLOR_GREY, "-- "COL_WHITE" %s(%d) has joined the table (2/2)", ReturnPlayerName( playerid ), playerid ); Pool_QueueNextPlayer( poolid, random_cuer ); foreach ( new i : poolplayers< poolid > ) { @@ -373,7 +373,7 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) else { UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], -1, sprintf( "" # COL_GREY "Pool Table\n{FFFFFF}Press ENTER To Join %s(%d)", ReturnPlayerName( playerid ), playerid ) ); - Pool_SendTableMessage( poolid, COLOR_GREY, "*** %s(%d) has joined the table (1/2)", ReturnPlayerName( playerid ), playerid ); + Pool_SendTableMessage( poolid, COLOR_GREY, "-- "COL_WHITE" %s(%d) has joined the table (1/2)", ReturnPlayerName( playerid ), playerid ); } return 1; } @@ -642,16 +642,6 @@ stock IsBallInHole( poolid, objectid ) return -1; } -stock removePlayerWeapon(playerid, weaponid) -{ - SetPlayerArmedWeapon(playerid, weaponid); - - if (GetPlayerWeapon(playerid) != 0) - GivePlayerWeapon(playerid, weaponid, 0); - - return 1; -} - stock Pool_UpdateScoreboard( poolid, close = 0 ) { new first_player = Iter_First( poolplayers< poolid > ); @@ -697,7 +687,7 @@ stock Pool_EndGame( poolid ) p_isPlayingPool{ i } = false; p_PoolScore[ i ] = -1; p_PoolID[ i ] = -1; - removePlayerWeapon( i, 7 ); + RestoreCamera( i ); } Iter_Clear( poolplayers< poolid > ); @@ -835,16 +825,13 @@ public OnPoolUpdate(poolid) if ( ( ! g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] || g_poolTableData[ poolid ] [ E_FOULS ] || g_poolTableData[ poolid ] [ E_EXTRA_SHOT ] ) && AreAllBallsStopped( poolid ) ) { Pool_QueueNextPlayer( poolid, current_player ); - SetTimerEx( "RestoreCamera", 800, 0, "dd", current_player, poolid ); + SetTimerEx( "RestoreCamera", 800, 0, "d", current_player ); } return 1; } -public RestoreCamera(playerid, poolid) +public RestoreCamera( playerid ) { - if ( g_poolTableData[ poolid ] [ E_AIMER ] == playerid ) - return 0; - TextDrawHideForPlayer(playerid, g_PoolTextdraw); HidePlayerProgressBar(playerid, g_PoolPowerBar[playerid]); @@ -951,8 +938,8 @@ public PHY_OnObjectUpdate( objectid ) // alert players in table foreach ( new playerid : poolplayers< poolid > ) { Player_Clearchat( playerid ); - SendClientMessageFormatted( playerid, COLOR_YELLOW, "* %s(%d) is now playing as %s", ReturnPlayerName( first_player ), first_player, g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ first_player ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); - SendClientMessageFormatted( playerid, COLOR_YELLOW, "* %s(%d) is playing as %s", ReturnPlayerName( second_player ), second_player, g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ second_player ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); + SendClientMessageFormatted( playerid, -1, ""COL_GREY"-- "COL_WHITE" %s(%d) is now playing as %s", ReturnPlayerName( first_player ), first_player, g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ first_player ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); + SendClientMessageFormatted( playerid, -1, ""COL_GREY"-- "COL_WHITE" %s(%d) is playing as %s", ReturnPlayerName( second_player ), second_player, g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ second_player ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); } } } @@ -977,18 +964,20 @@ public PHY_OnObjectUpdate( objectid ) g_poolTableData[ poolid ] [ E_BALLS_SCORED ] ++; // restore player camera - RestoreCamera( current_player, poolid ); + RestoreCamera( current_player ); // check if valid shot if ( p_PoolScore[ current_player ] < 7 ) { p_PoolScore[ opposite_player ] ++; - Pool_SendTableMessage( poolid, COLOR_YELLOW, "%s(%d) has accidentally pocketed the 8-Ball ... %s(%d) wins!", ReturnPlayerName( current_player ), current_player, ReturnPlayerName( opposite_player ), opposite_player ); + Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has accidentally pocketed the 8-Ball ... %s(%d) wins!", ReturnPlayerName( current_player ), current_player, ReturnPlayerName( opposite_player ), opposite_player ); + Pool_OnPlayerWin( poolid, opposite_player ); } else if ( g_poolTableData[ poolid ] [ E_PLAYER_8BALL_TARGET ] [ current_player ] != holeid ) { p_PoolScore[ opposite_player ] ++; - Pool_SendTableMessage( poolid, COLOR_YELLOW, "%s(%d) has put the 8-Ball in the wrong pocket ... %s(%d) wins!", ReturnPlayerName( current_player ), current_player, ReturnPlayerName( opposite_player ), opposite_player ); + Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has put the 8-Ball in the wrong pocket ... %s(%d) wins!", ReturnPlayerName( current_player ), current_player, ReturnPlayerName( opposite_player ), opposite_player ); + Pool_OnPlayerWin( poolid, opposite_player ); } else { @@ -1007,10 +996,7 @@ public PHY_OnObjectUpdate( objectid ) p_PoolScore[ opposite_player ] += 1; GameTextForPlayer( current_player, "~n~~n~~n~~r~wrong ball", 3000, 4); - - foreach ( new playerid : poolplayers< poolid > ) { - SendClientMessageFormatted( playerid, COLOR_RED, "* %s(%d) has wrongly pocketed %s %s, instead of %s!", ReturnPlayerName( current_player ), current_player, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolBallOffsetData[ poolball_index ] [ E_BALL_NAME ], g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ current_player ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); - } + Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has wrongly pocketed %s %s, instead of %s!", ReturnPlayerName( current_player ), current_player, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolBallOffsetData[ poolball_index ] [ E_BALL_NAME ], g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ current_player ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); // penalty for that g_poolTableData[ poolid ] [ E_FOULS ] ++; @@ -1021,10 +1007,7 @@ public PHY_OnObjectUpdate( objectid ) { p_PoolScore[ current_player ] ++; GameTextForPlayer( current_player, "~n~~n~~n~~w~Score: +1", 3000, 4); - - foreach ( new playerid : poolplayers< poolid > ) { - SendClientMessageFormatted( playerid, COLOR_YELLOW, "%s(%d) has pocketed a %s %s!", ReturnPlayerName( current_player ), current_player, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolBallOffsetData[ poolball_index ] [ E_BALL_NAME ] ); - } + Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has pocketed a %s %s!", ReturnPlayerName( current_player ), current_player, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolBallOffsetData[ poolball_index ] [ E_BALL_NAME ] ); // extra shot for scoring one's own g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] = g_poolTableData[ poolid ] [ E_FOULS ] > 0 ? 0 : 1; @@ -1066,13 +1049,6 @@ public PHY_OnObjectUpdate( objectid ) // update scoreboard Pool_UpdateScoreboard( poolid ); PlayerPlaySound( current_player, 31803, 0.0, 0.0, 0.0 ); - - // reset cam - /*if ( AreAllBallsStopped( poolid ) ) { - printf ( "Second %d" , g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] ); - Pool_QueueNextPlayer( poolid, g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ); - SetTimerEx( "RestoreCamera", 800, 0, "dd", current_player, poolid ); - }*/ } return 1; } @@ -1086,12 +1062,13 @@ stock Pool_OnPlayerWin( poolid, winning_player ) return 0; // restore camera - RestoreCamera( winning_player, poolid ); + RestoreCamera( winning_player ); // winning player - foreach ( new playerid : poolplayers< poolid > ) { - SendClientMessageFormatted( playerid, COLOR_RED, "**** %s(%d) has won %s", ReturnPlayerName( winning_player ), winning_player ); - } + Pool_SendTableMessage( poolid, -1, "{9FCF30}****************************************************************************************"); + Pool_SendTableMessage( poolid, -1, "{9FCF30}Player {FF8000}%s {9FCF30}has won the game!", ReturnPlayerName( winning_player ) ); + // Pool_SendTableMessage( poolid, "{9FCF30}Prize: {377CC8}%s | -%0.0f%s percent fee", number_format(w_chips), T_POT_FEE_RATE * 100.0, "%%"); + Pool_SendTableMessage( poolid, -1, "{9FCF30}****************************************************************************************"); return 1; } @@ -1100,7 +1077,7 @@ stock Pool_QueueNextPlayer( poolid, current_player ) if ( g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] && g_poolTableData[ poolid ] [ E_FOULS ] < 1 ) { g_poolTableData[ poolid ] [ E_EXTRA_SHOT ] = false; - Pool_SendTableMessage( poolid, COLOR_RED, "%s(%d) has %d shot remaining!", ReturnPlayerName( current_player ), current_player, g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] ); + Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has an extra shot remaining!", ReturnPlayerName( current_player ), current_player ); } else { @@ -1113,7 +1090,7 @@ stock Pool_QueueNextPlayer( poolid, current_player ) g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] = current_player == first_player ? second_player : first_player; // reset ball positions just incase - Pool_SendTableMessage( poolid, COLOR_RED, "%s(%d)'s turn to play!", ReturnPlayerName( g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ), g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ); + Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d)'s turn to play!", ReturnPlayerName( g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ), g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ); } // respawn the cue ball if it has been pocketed From f9d2262b587eb0238e5caea5207262418fc9ee38 Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Fri, 14 Sep 2018 18:00:41 +1000 Subject: [PATCH 12/17] animation fixes for pool --- gamemodes/irresistible/cnr/features/pool.pwn | 114 ++++++++++++------- 1 file changed, 74 insertions(+), 40 deletions(-) diff --git a/gamemodes/irresistible/cnr/features/pool.pwn b/gamemodes/irresistible/cnr/features/pool.pwn index c2e235f..abb805d 100644 --- a/gamemodes/irresistible/cnr/features/pool.pwn +++ b/gamemodes/irresistible/cnr/features/pool.pwn @@ -174,6 +174,12 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) { if ( g_poolTableData[ poolid ] [ E_STARTED ] ) { + // quit table + if ( HOLDING( KEY_SECONDARY_ATTACK ) ) { + Pool_SendTableMessage( poolid, COLOR_GREY, "-- "COL_WHITE" %s(%d) has left the table", ReturnPlayerName( playerid ), playerid ); + return Pool_RemovePlayer( playerid ); + } + // make pressing key fire annoying if ( RELEASED( KEY_FIRE ) && g_poolTableData[ poolid ] [ E_AIMER ] != playerid && ! p_PoolChalking{ playerid } ) { @@ -249,24 +255,36 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) new Float: distance_to_ball = GetDistanceFromPointToPoint( X, Y, Xa, Ya ); - if ( distance_to_ball < 1.5 && Z < 999.5 ) + if ( distance_to_ball < 1.8 && Z < 999.5 ) { printf( "Distance To Ball %f", distance_to_ball ); - TogglePlayerControllable(playerid, false); - GetAngleToXY(Xa, Ya, X, Y, poolrot); - SetPlayerFacingAngle(playerid, poolrot); + TogglePlayerControllable( playerid, false ); + GetAngleToXY( Xa, Ya, X, Y, poolrot ); p_PoolAngle[ playerid ] [ 0 ] = poolrot; p_PoolAngle[ playerid ] [ 1 ] = poolrot; - SetPlayerArmedWeapon(playerid, 0); + SetPlayerArmedWeapon( playerid, 0 ); GetXYInFrontOfPos( Xa, Ya, poolrot + 180, x, y, 0.085 ); g_poolTableData[ poolid ] [ E_AIMER_OBJECT ] = CreateObject( 3004, x, y, Za, 7.0, 0, poolrot + 180 ); - SetPlayerCameraPos(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0); + SetPlayerCameraPos( playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0 ); - ApplyAnimation( playerid, "POOL", "POOL_Med_Start", 4.1, 0, 1, 1, 0, 0, 1 ); + if ( distance_to_ball < 1.20 ) { + distance_to_ball = 1.20; + } + + GetXYInFrontOfPos( Xa, Ya, poolrot + 180 - 5.0, X, Y, distance_to_ball ); // offset 5 degrees + SetPlayerPos( playerid, X, Y, Z ); + SetPlayerFacingAngle( playerid, poolrot ); + + if ( distance_to_ball > 1.5 ) { + ApplyAnimation( playerid, "POOL", "POOL_XLong_Start", 4.1, 0, 1, 1, 1, 1, 1 ); + } else { //if ( distance_to_ball > 1.2 ) { + ApplyAnimation( playerid, "POOL", "POOL_Long_Start", 4.1, 0, 1, 1, 1, 1, 1 ); + //ApplyAnimation( playerid, "POOL", "POOL_Med_Start", 4.1, 0, 1, 1, 1, 1, 1 ); + } g_poolTableData[ poolid ] [ E_AIMER ] = playerid; g_poolTableData[ poolid ] [ E_POWER ] = 1.0; @@ -281,11 +299,12 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) } else { - TogglePlayerControllable(playerid, true); - GivePlayerWeapon(playerid, 7, 1); + TogglePlayerControllable( playerid, true ); + GivePlayerWeapon( playerid, 7, 1 ); ClearAnimations( playerid ); SetCameraBehindPlayer( playerid ); + ApplyAnimation( playerid, "CARRY", "crry_prtial", 4.0, 0, 1, 1, 0, 0 ); g_poolTableData[ poolid ] [ E_AIMER ] = -1; DestroyObject( g_poolTableData[ poolid ] [ E_AIMER_OBJECT ] ); @@ -306,16 +325,21 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) Pool_UpdateScoreboard( poolid ); GetObjectPos( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], ball_x, ball_y, ball_z ); + new Float: distance_to_ball = GetPlayerDistanceFromPoint( playerid, ball_x, ball_y, ball_z ); - ApplyAnimation( playerid, "POOL", "POOL_Med_Shot", 4.1, 0, 1, 1, 0, 0, 1); + if ( distance_to_ball > 1.5 ) { + ApplyAnimation( playerid, "POOL", "POOL_XLong_Shot", 4.1, 0, 1, 1, 0, 0, 1 ); + } else { + ApplyAnimation( playerid, "POOL", "POOL_Long_Shot", 4.1, 0, 1, 1, 0, 0, 1 ); + } speed = 0.4 + ( g_poolTableData[ poolid ] [ E_POWER ] * 2.0 ) / 100.0; PHY_SetObjectVelocity(g_poolBallData[poolid] [E_BALL_OBJECT] [0], speed * floatsin(-p_PoolAngle[ playerid ] [ 0 ], degrees), speed * floatcos(-p_PoolAngle[ playerid ] [ 0 ], degrees)); - SetPlayerCameraPos(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0); - SetPlayerCameraLookAt(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ]); + SetPlayerCameraPos( playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0 ); + SetPlayerCameraLookAt( playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] ); - PlayPoolSound(poolid, 31810); + PlayPoolSound( poolid, 31810 ); g_poolTableData[ poolid ] [ E_AIMER ] = -1; DestroyObject( g_poolTableData[ poolid ] [ E_AIMER_OBJECT ] ); g_poolTableData[ poolid ] [ E_AIMER_OBJECT ] = -1; @@ -330,8 +354,9 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) { if ( PRESSED( KEY_SECONDARY_ATTACK ) ) { - if ( IsPlayerPlayingPool( playerid ) ) { - Pool_SendTableMessage( poolid, COLOR_GREY, "-- "COL_WHITE" %s(%d) has left the table", ReturnPlayerName( playerid ), playerid ); + if ( IsPlayerPlayingPool( playerid ) ) + { + Pool_SendTableMessage( p_PoolID[ playerid ], COLOR_GREY, "-- "COL_WHITE" %s(%d) has left the table", ReturnPlayerName( playerid ), playerid ); return Pool_RemovePlayer( playerid ); } @@ -394,6 +419,7 @@ stock Pool_RemovePlayer( playerid ) p_PoolID[ playerid ] = -1; DestroyDynamicObject( p_PoolHoleGuide[ playerid ] ); p_PoolHoleGuide[ playerid ] = -1; + RestoreCamera( playerid ); // check if the player is even in the table if ( poolid != -1 && Iter_Contains( poolplayers< poolid >, playerid ) ) @@ -698,7 +724,9 @@ stock Pool_EndGame( poolid ) g_poolTableData[ poolid ] [ E_FOULS ] = 0; g_poolTableData[ poolid ] [ E_EXTRA_SHOT ] = false; - KillTimer(g_poolTableData[ poolid ] [ E_TIMER ]); + KillTimer( g_poolTableData[ poolid ] [ E_TIMER ] ); + DestroyObject( g_poolTableData[ poolid ] [ E_AIMER_OBJECT ] ); + g_poolTableData[ poolid ] [ E_AIMER_OBJECT ] = -1; for ( new i = 0; i < 16; i ++ ) if ( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] != -1 ) { PHY_DeleteObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ); @@ -735,10 +763,16 @@ public PlayPoolSound( poolid, soundid ) { return 1; } -public OnPoolUpdate(poolid) +public OnPoolUpdate( poolid ) { - if ( ! g_poolTableData[ poolid ] [ E_STARTED ] ) - return 0; + if ( ! g_poolTableData[ poolid ] [ E_STARTED ] ) { + return 1; + } + + if ( ! Iter_Count( poolplayers< poolid > ) ) { + // Pool_EndGame( poolid ); + // return 1; + } if ( g_poolTableData[ poolid ] [ E_AIMER ] != -1 ) { @@ -757,12 +791,11 @@ public OnPoolUpdate(poolid) newrot = p_PoolAngle[ playerid ] [ 0 ] + (lr > 0 ? 0.9 : -0.9); dist = GetDistanceBetweenPoints( X, Y, 0.0, Xa, Ya, 0.0 ); - printf("%f", dist); - if ( dist < 0.85 ) { - dist = 0.85; + if ( dist < 1.20 ) { + dist = 1.20; } - if (AngleInRangeOfAngle(p_PoolAngle[ playerid ] [ 1 ], newrot, 30.0)) + if ( AngleInRangeOfAngle( p_PoolAngle[ playerid ] [ 1 ], newrot, 30.0 ) ) { p_PoolAngle[ playerid ] [ 0 ] = newrot; @@ -778,12 +811,12 @@ public OnPoolUpdate(poolid) SetPlayerCameraLookAt(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ]); } - GetXYInFrontOfPos(Xa, Ya, newrot + 180, x, y, 0.085); - SetObjectPos(g_poolTableData[ poolid ] [ E_AIMER_OBJECT ], x, y, Za); - SetObjectRot(g_poolTableData[ poolid ] [ E_AIMER_OBJECT ], 7.0, 0, p_PoolAngle[ playerid ] [ 0 ] + 180); - GetXYInFrontOfPos(Xa, Ya, newrot + 180, X, Y, dist); - SetPlayerPos(playerid, X, Y, Z); - SetPlayerFacingAngle(playerid, newrot); + GetXYInFrontOfPos( Xa, Ya, newrot + 180, x, y, 0.085 ); + SetObjectPos( g_poolTableData[ poolid ] [ E_AIMER_OBJECT ], x, y, Za ); + SetObjectRot( g_poolTableData[ poolid ] [ E_AIMER_OBJECT ], 7.0, 0, p_PoolAngle[ playerid ] [ 0 ] + 180 ); + GetXYInFrontOfPos( Xa, Ya, newrot + 180 - 5.0, x, y, dist ); // offset 5 degrees + SetPlayerPos( playerid, x, y, Z ); + SetPlayerFacingAngle( playerid, newrot ); } } } @@ -832,11 +865,11 @@ public OnPoolUpdate(poolid) public RestoreCamera( playerid ) { - TextDrawHideForPlayer(playerid, g_PoolTextdraw); - HidePlayerProgressBar(playerid, g_PoolPowerBar[playerid]); - - TogglePlayerControllable(playerid, 1); - return SetCameraBehindPlayer(playerid); + TextDrawHideForPlayer( playerid, g_PoolTextdraw ); + HidePlayerProgressBar( playerid, g_PoolPowerBar[ playerid ] ); + TogglePlayerControllable( playerid, 1 ); + ApplyAnimation( playerid, "CARRY", "crry_prtial", 4.0, 0, 1, 1, 0, 0 ); + return SetCameraBehindPlayer( playerid ); } public deleteBall( poolid, ballid ) @@ -950,6 +983,7 @@ public PHY_OnObjectUpdate( objectid ) if ( g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_CUE ) { GameTextForPlayer( current_player, "~n~~n~~n~~r~~h~You have pocketed the cue ball!", 10000, 4 ); + Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has wrongly pocketed the cue ball!", ReturnPlayerName( current_player ), current_player ); // penalty for that g_poolTableData[ poolid ] [ E_FOULS ] ++; @@ -970,13 +1004,13 @@ public PHY_OnObjectUpdate( objectid ) if ( p_PoolScore[ current_player ] < 7 ) { p_PoolScore[ opposite_player ] ++; - Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has accidentally pocketed the 8-Ball ... %s(%d) wins!", ReturnPlayerName( current_player ), current_player, ReturnPlayerName( opposite_player ), opposite_player ); + Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has accidentally pocketed the 8-Ball ... %s(%d) wins!", ReturnPlayerName( current_player ), current_player, ReturnPlayerName( opposite_player ), opposite_player ); Pool_OnPlayerWin( poolid, opposite_player ); } else if ( g_poolTableData[ poolid ] [ E_PLAYER_8BALL_TARGET ] [ current_player ] != holeid ) { p_PoolScore[ opposite_player ] ++; - Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has put the 8-Ball in the wrong pocket ... %s(%d) wins!", ReturnPlayerName( current_player ), current_player, ReturnPlayerName( opposite_player ), opposite_player ); + Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has put the 8-Ball in the wrong pocket ... %s(%d) wins!", ReturnPlayerName( current_player ), current_player, ReturnPlayerName( opposite_player ), opposite_player ); Pool_OnPlayerWin( poolid, opposite_player ); } else @@ -1015,12 +1049,12 @@ public PHY_OnObjectUpdate( objectid ) } // mark final target hole - if ( p_PoolScore[ first_player ] == 7 || p_PoolScore[ second_player ] == 7 ) + if ( ( p_PoolScore[ first_player ] == 7 && p_PoolHoleGuide[ first_player ] == -1 ) || ( p_PoolScore[ second_player ] == 7 && p_PoolHoleGuide[ second_player ] == -1 ) ) { new player_being_marked = p_PoolScore[ first_player ] == 7 ? first_player : second_player; - if ( ! IsValidDynamicObject( p_PoolHoleGuide[ player_being_marked ] ) ) + if ( p_PoolHoleGuide[ player_being_marked ] == -1 ) { new opposite_holeid = g_poolHoleOpposite[ holeid ]; @@ -1077,7 +1111,7 @@ stock Pool_QueueNextPlayer( poolid, current_player ) if ( g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] && g_poolTableData[ poolid ] [ E_FOULS ] < 1 ) { g_poolTableData[ poolid ] [ E_EXTRA_SHOT ] = false; - Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has an extra shot remaining!", ReturnPlayerName( current_player ), current_player ); + Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has an extra shot remaining!", ReturnPlayerName( current_player ), current_player ); } else { @@ -1090,7 +1124,7 @@ stock Pool_QueueNextPlayer( poolid, current_player ) g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] = current_player == first_player ? second_player : first_player; // reset ball positions just incase - Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d)'s turn to play!", ReturnPlayerName( g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ), g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ); + Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d)'s turn to play!", ReturnPlayerName( g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ), g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ] ); } // respawn the cue ball if it has been pocketed From da1f2f91bf60cd55cf0d2ed5e0e66c5332c8e350 Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Fri, 14 Sep 2018 19:12:39 +1000 Subject: [PATCH 13/17] no longer can jump on top of the table to shoot instructions given to first player that joins the table cleanup --- gamemodes/irresistible/cnr/features/pool.pwn | 267 ++++++++----------- 1 file changed, 117 insertions(+), 150 deletions(-) diff --git a/gamemodes/irresistible/cnr/features/pool.pwn b/gamemodes/irresistible/cnr/features/pool.pwn index abb805d..de52f11 100644 --- a/gamemodes/irresistible/cnr/features/pool.pwn +++ b/gamemodes/irresistible/cnr/features/pool.pwn @@ -168,7 +168,7 @@ hook OnPlayerConnect( playerid ) hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) { new Float: pooltable_distance = 99999.99; - new poolid = GetClosestPoolTable( playerid, pooltable_distance ); + new poolid = Pool_GetClosestTable( playerid, pooltable_distance ); if ( poolid != -1 && pooltable_distance < 2.5 ) { @@ -176,8 +176,13 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) { // quit table if ( HOLDING( KEY_SECONDARY_ATTACK ) ) { - Pool_SendTableMessage( poolid, COLOR_GREY, "-- "COL_WHITE" %s(%d) has left the table", ReturnPlayerName( playerid ), playerid ); - return Pool_RemovePlayer( playerid ); + if ( PRESSED( KEY_CROUCH ) ) { + HidePlayerHelpDialog( playerid ); + Pool_SendTableMessage( poolid, COLOR_GREY, "-- "COL_WHITE" %s(%d) has left the table", ReturnPlayerName( playerid ), playerid ); + return Pool_RemovePlayer( playerid ); + } else { + return GameTextForPlayer( playerid, "~w~and now...~n~~w~ press ~r~~k~~PED_DUCK~~w~ to exit", 3500, 3 ), 1; + } } // make pressing key fire annoying @@ -208,33 +213,14 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) { if ( g_poolTableData[ poolid ] [ E_AIMER ] == playerid ) { - - new Float:poolrot = p_PoolAngle[ playerid ] [ 0 ], - Float:Xa, - Float:Ya, - Float:Za, - Float:x, - Float:y; - - GetObjectPos(g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], Xa, Ya, Za); - - if ( ( p_PoolCameraBirdsEye{ playerid } = ! p_PoolCameraBirdsEye{ playerid } ) == false ) - { - GetXYBehindObjectInAngle(g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], poolrot, x, y, 0.675); - SetPlayerCameraPos(playerid, x, y, g_poolTableData[ poolid ] [ E_Z ] + DEFAULT_AIM); - SetPlayerCameraLookAt(playerid, Xa, Ya, Za + 0.170); - } - else - { - SetPlayerCameraPos(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0); - SetPlayerCameraLookAt(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ]); - } + p_PoolCameraBirdsEye{ playerid } = ! p_PoolCameraBirdsEye{ playerid }; + Pool_UpdatePlayerCamera( playerid, poolid ); } } if ( RELEASED( KEY_HANDBRAKE ) ) { - if ( AreAllBallsStopped( poolid ) ) + if ( Pool_AreBallsStopped( poolid ) ) { if ( g_poolTableData[ poolid ] [ E_AIMER ] != playerid ) { @@ -244,12 +230,16 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) if ( ! p_PoolChalking{ playerid } && g_poolTableData[ poolid ] [ E_AIMER ] == -1 ) { - new Float:poolrot, - Float:X, Float:Y, Float:Z, + new Float:X, Float:Y, Float:Z, Float:Xa, Float:Ya, Float:Za, Float:x, Float:y; GetPlayerPos( playerid, X, Y, Z ); + + if ( Z > g_poolTableData[ poolid ] [ E_Z ] + 0.5 ) { + return SendPoolMessage( playerid, "Lower yourself from the table." ); + } + GetObjectPos( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], Xa, Ya, Za ); new @@ -257,39 +247,37 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) if ( distance_to_ball < 1.8 && Z < 999.5 ) { - printf( "Distance To Ball %f", distance_to_ball ); + new + Float: poolrot = atan2( Ya - Y, Xa - X ) - 90.0; TogglePlayerControllable( playerid, false ); - GetAngleToXY( Xa, Ya, X, Y, poolrot ); p_PoolAngle[ playerid ] [ 0 ] = poolrot; p_PoolAngle[ playerid ] [ 1 ] = poolrot; SetPlayerArmedWeapon( playerid, 0 ); - GetXYInFrontOfPos( Xa, Ya, poolrot + 180, x, y, 0.085 ); + Pool_GetXYInFrontOfPos( Xa, Ya, poolrot + 180, x, y, 0.085 ); g_poolTableData[ poolid ] [ E_AIMER_OBJECT ] = CreateObject( 3004, x, y, Za, 7.0, 0, poolrot + 180 ); - SetPlayerCameraPos( playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0 ); - if ( distance_to_ball < 1.20 ) { distance_to_ball = 1.20; } - GetXYInFrontOfPos( Xa, Ya, poolrot + 180 - 5.0, X, Y, distance_to_ball ); // offset 5 degrees + Pool_GetXYInFrontOfPos( Xa, Ya, poolrot + 180 - 5.0, X, Y, distance_to_ball ); // offset 5 degrees SetPlayerPos( playerid, X, Y, Z ); SetPlayerFacingAngle( playerid, poolrot ); if ( distance_to_ball > 1.5 ) { ApplyAnimation( playerid, "POOL", "POOL_XLong_Start", 4.1, 0, 1, 1, 1, 1, 1 ); - } else { //if ( distance_to_ball > 1.2 ) { + } else { ApplyAnimation( playerid, "POOL", "POOL_Long_Start", 4.1, 0, 1, 1, 1, 1, 1 ); - //ApplyAnimation( playerid, "POOL", "POOL_Med_Start", 4.1, 0, 1, 1, 1, 1, 1 ); } g_poolTableData[ poolid ] [ E_AIMER ] = playerid; g_poolTableData[ poolid ] [ E_POWER ] = 1.0; g_poolTableData[ poolid ] [ E_DIRECTION ] = 0; + Pool_UpdatePlayerCamera( playerid, poolid ); Pool_UpdateScoreboard( poolid ); TextDrawShowForPlayer( playerid, g_PoolTextdraw ); @@ -318,7 +306,6 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) if ( g_poolTableData[ poolid ] [ E_AIMER ] == playerid ) { new Float: ball_x, Float: ball_y, Float: ball_z; - new Float: speed; g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] --; @@ -333,8 +320,8 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) ApplyAnimation( playerid, "POOL", "POOL_Long_Shot", 4.1, 0, 1, 1, 0, 0, 1 ); } - speed = 0.4 + ( g_poolTableData[ poolid ] [ E_POWER ] * 2.0 ) / 100.0; - PHY_SetObjectVelocity(g_poolBallData[poolid] [E_BALL_OBJECT] [0], speed * floatsin(-p_PoolAngle[ playerid ] [ 0 ], degrees), speed * floatcos(-p_PoolAngle[ playerid ] [ 0 ], degrees)); + new Float: speed = 0.4 + ( g_poolTableData[ poolid ] [ E_POWER ] * 2.0 ) / 100.0; + PHY_SetObjectVelocity( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], speed * floatsin( -p_PoolAngle[ playerid ] [ 0 ], degrees ), speed * floatcos( -p_PoolAngle[ playerid ] [ 0 ], degrees ) ); SetPlayerCameraPos( playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0 ); SetPlayerCameraLookAt( playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] ); @@ -346,7 +333,7 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) GivePlayerWeapon( playerid, 7, 1 ); } - else ClearAnimations(playerid); + else ClearAnimations( playerid ); } } } @@ -356,6 +343,7 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) { if ( IsPlayerPlayingPool( playerid ) ) { + HidePlayerHelpDialog( playerid ); Pool_SendTableMessage( p_PoolID[ playerid ], COLOR_GREY, "-- "COL_WHITE" %s(%d) has left the table", ReturnPlayerName( playerid ), playerid ); return Pool_RemovePlayer( playerid ); } @@ -385,6 +373,7 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) Pool_SendTableMessage( poolid, COLOR_GREY, "-- "COL_WHITE" %s(%d) has joined the table (2/2)", ReturnPlayerName( playerid ), playerid ); Pool_QueueNextPlayer( poolid, random_cuer ); + foreach ( new i : poolplayers< poolid > ) { p_PoolScore[ i ] = 0; PlayerPlaySound( i, 1085, 0.0, 0.0, 0.0 ); @@ -393,10 +382,11 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) g_poolTableData[ poolid ] [ E_STARTED ] = true; Pool_UpdateScoreboard( poolid ); - RespawnPoolBalls( poolid ); + Pool_RespawnBalls( poolid ); } else { + ShowPlayerHelpDialog( playerid, 0, "~y~~h~~k~~PED_LOCK_TARGET~ ~w~- Aim Cue~n~~y~~h~~k~~PED_FIREWEAPON~ ~w~- Shoot Cue~n~~y~~h~~k~~PED_JUMPING~ ~w~- Camera Mode~n~~y~~h~~k~~VEHICLE_ENTER_EXIT~ ~w~- Exit Game~n~~n~~r~~h~Waiting for 1 more player..." ); UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], -1, sprintf( "" # COL_GREY "Pool Table\n{FFFFFF}Press ENTER To Join %s(%d)", ReturnPlayerName( playerid ), playerid ) ); Pool_SendTableMessage( poolid, COLOR_GREY, "-- "COL_WHITE" %s(%d) has joined the table (1/2)", ReturnPlayerName( playerid ), playerid ); } @@ -430,10 +420,14 @@ stock Pool_RemovePlayer( playerid ) // forfeit player if ( g_poolTableData[ poolid ] [ E_STARTED ] ) { - new - replacement_winner = Iter_First( poolplayers< poolid > ); // there's only 1 guy in the table + // ... if there's only 1 guy in the table might as well declare him winner + if ( Iter_Count( poolplayers< poolid > ) ) + { + new + replacement_winner = Iter_First( poolplayers< poolid > ); - Pool_OnPlayerWin( poolid, replacement_winner ); + Pool_OnPlayerWin( poolid, replacement_winner ); + } return Pool_EndGame( poolid ); } else @@ -472,10 +466,10 @@ stock CreatePoolTable( Float: X, Float: Y, Float: Z, Float: A = 0.0, interior = g_poolTableData[ gID] [ E_TABLE ] = CreateDynamicObject( 2964, X, Y, Z - 1.0, 0.0, 0.0, A, world, interior ); g_poolTableData[ gID] [ E_LABEL ] = CreateDynamic3DTextLabel( DEFAULT_POOL_STRING, COLOR_GREY, X, Y, Z, 10.0, INVALID_PLAYER_ID, INVALID_VEHICLE_ID, 0, world, interior ); - RotateXY( -0.964, -0.51, A, x_vertex[ 0 ], y_vertex[ 0 ] ); - RotateXY( -0.964, 0.533, A, x_vertex[ 1 ], y_vertex[ 1 ] ); - RotateXY( 0.976, -0.51, A, x_vertex[ 2 ], y_vertex[ 2 ] ); - RotateXY( 0.976, 0.533, A, x_vertex[ 3 ], y_vertex[ 3 ] ); + Pool_RotateXY( -0.964, -0.51, A, x_vertex[ 0 ], y_vertex[ 0 ] ); + Pool_RotateXY( -0.964, 0.533, A, x_vertex[ 1 ], y_vertex[ 1 ] ); + Pool_RotateXY( 0.976, -0.51, A, x_vertex[ 2 ], y_vertex[ 2 ] ); + Pool_RotateXY( 0.976, 0.533, A, x_vertex[ 3 ], y_vertex[ 3 ] ); PHY_CreateWall( x_vertex[0] + X, y_vertex[0] + Y, x_vertex[1] + X, y_vertex[1] + Y); PHY_CreateWall( x_vertex[1] + X, y_vertex[1] + Y, x_vertex[3] + X, y_vertex[3] + Y); @@ -513,7 +507,7 @@ stock CreatePoolTable( Float: X, Float: Y, Float: Z, Float: A = 0.0, interior = return gID; } -stock GetClosestPoolTable( playerid, &Float: dis = 99999.99 ) +stock Pool_GetClosestTable( playerid, &Float: dis = 99999.99 ) { new pooltable = -1; @@ -532,7 +526,7 @@ stock GetClosestPoolTable( playerid, &Float: dis = 99999.99 ) return pooltable; } -stock RespawnPoolBalls( poolid ) +stock Pool_RespawnBalls( poolid ) { if ( g_poolTableData[ poolid ] [ E_AIMER ] != -1 ) { @@ -556,7 +550,7 @@ stock RespawnPoolBalls( poolid ) for ( new i = 0; i < sizeof( g_poolBallOffsetData ); i ++ ) { // get offset according to angle of table - RotateXY( g_poolBallOffsetData[ i ] [ E_OFFSET_X ], g_poolBallOffsetData[ i ] [ E_OFFSET_Y ], g_poolTableData[ poolid ] [ E_ANGLE ], offset_x, offset_y ); + Pool_RotateXY( g_poolBallOffsetData[ i ] [ E_OFFSET_X ], g_poolBallOffsetData[ i ] [ E_OFFSET_Y ], g_poolTableData[ poolid ] [ E_ANGLE ], offset_x, offset_y ); // reset balls if ( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] != -1 ) { @@ -574,7 +568,7 @@ stock RespawnPoolBalls( poolid ) ); // initialize physics on each ball - InitBalls( poolid, i ); + Pool_InitBalls( poolid, i ); } KillTimer( g_poolTableData[ poolid ] [ E_TIMER ] ); @@ -582,7 +576,7 @@ stock RespawnPoolBalls( poolid ) g_poolTableData[ poolid ] [ E_BALLS_SCORED ] = 0; } -stock InitBalls(poolid, ballid) +stock Pool_InitBalls( poolid, ballid ) { PHY_InitObject(g_poolBallData[poolid] [E_BALL_OBJECT] [ballid], 3003, _, _, PHY_MODE_2D); @@ -594,63 +588,31 @@ stock InitBalls(poolid, ballid) g_poolBallData[ poolid ] [ E_POCKETED ] [ ballid ] = false; } -stock RotateXY( Float: xi, Float: yi, Float: angle, &Float: xf, &Float: yf ) +stock Pool_RotateXY( Float: xi, Float: yi, Float: angle, &Float: xf, &Float: yf ) { xf = xi * floatcos( angle, degrees ) - yi * floatsin( angle, degrees ); yf = xi * floatsin( angle, degrees ) + yi * floatcos( angle, degrees ); return 1; } -stock GetXYBehindObjectInAngle(objectid, Float:a, &Float:x2, &Float:y2, Float:distance) -{ - new Float:z; - GetObjectPos(objectid, x2, y2, z); - - x2 += (distance * floatsin(-a+180, degrees)); - y2 += (distance * floatcos(-a+180, degrees)); -} - -stock AreAllBallsStopped( poolid ) +stock Pool_AreBallsStopped( poolid ) { new balls_not_moving = 0; - new bool: checklist[ 16]; - for ( new i = 0; i < 16; i ++ ) if ( g_poolBallData[ poolid ] [ E_POCKETED ] [ i ] || ! PHY_IsObjectMoving( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ) ) { balls_not_moving ++; - checklist[i] = true; } - - szBigString = ""; - for ( new i = 0; i < 16; i++ ) { - if ( checklist[i] == false ) format( szBigString, sizeof(szBigString), "%s%s(%d), ", szBigString, g_poolBallOffsetData[i][E_BALL_NAME], i); - } - printf("not stopped: %s", szBigString); - return balls_not_moving >= 16; } -stock GetAngleToXY(Float:X, Float:Y, Float:CurrX, Float:CurrY, &Float:angle) +stock Pool_GetXYInFrontOfPos( Float: xx, Float: yy, Float: a, &Float: x2, &Float: y2, Float: distance ) { - angle = atan2(Y-CurrY, X-CurrX); - angle = floatsub(angle, 90.0); - if(angle < 0.0) angle = floatadd(angle, 360.0); + x2 = xx + ( distance * floatsin( -a, degrees ) ); + y2 = yy + ( distance * floatcos( -a, degrees ) ); } -stock GetXYInFrontOfPos(Float:xx,Float:yy,Float:a, &Float:x2, &Float:y2, Float:distance) -{ - if (a > 360) { - a = a - 360; - } - - xx += (distance * floatsin(-a, degrees)); - yy += (distance * floatcos(-a, degrees)); - x2 = xx; - y2 = yy; -} - -stock IsBallInHole( poolid, objectid ) +stock Pool_IsBallInHole( poolid, objectid ) { new Float: hole_x, Float: hole_y; @@ -658,7 +620,7 @@ stock IsBallInHole( poolid, objectid ) for ( new i = 0; i < sizeof( g_poolPotOffsetData ); i ++ ) { // rotate offsets according to table - RotateXY( g_poolPotOffsetData[ i ] [ 0 ], g_poolPotOffsetData[ i ] [ 1 ], g_poolTableData[ poolid ] [ E_ANGLE ], hole_x, hole_y ); + Pool_RotateXY( g_poolPotOffsetData[ i ] [ 0 ], g_poolPotOffsetData[ i ] [ 1 ], g_poolTableData[ poolid ] [ E_ANGLE ], hole_x, hole_y ); // check if it is at the pocket if ( IsBallAtPos( objectid, g_poolTableData[ poolid ] [ E_X ] + hole_x , g_poolTableData[ poolid ] [ E_Y ] + hole_y, g_poolTableData[ poolid ] [ E_Z ], POCKET_RADIUS ) ) { @@ -770,17 +732,17 @@ public OnPoolUpdate( poolid ) } if ( ! Iter_Count( poolplayers< poolid > ) ) { - // Pool_EndGame( poolid ); - // return 1; + Pool_EndGame( poolid ); + return 1; } if ( g_poolTableData[ poolid ] [ E_AIMER ] != -1 ) { new playerid = g_poolTableData[ poolid ] [ E_AIMER ], keys, ud, lr; - GetPlayerKeys(playerid, keys, ud, lr); + GetPlayerKeys( playerid, keys, ud, lr ); - if (!(keys & KEY_FIRE)) + if ( ! ( keys & KEY_FIRE ) ) { if (lr) { @@ -788,9 +750,10 @@ public OnPoolUpdate( poolid ) GetPlayerPos(playerid, X, Y ,Z); GetObjectPos(g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], Xa, Ya, Za); - newrot = p_PoolAngle[ playerid ] [ 0 ] + (lr > 0 ? 0.9 : -0.9); + newrot = p_PoolAngle[ playerid ] [ 0 ] + ( lr > 0 ? 0.9 : -0.9 ); dist = GetDistanceBetweenPoints( X, Y, 0.0, Xa, Ya, 0.0 ); + // keep the head out of the point of view if ( dist < 1.20 ) { dist = 1.20; } @@ -798,23 +761,12 @@ public OnPoolUpdate( poolid ) if ( AngleInRangeOfAngle( p_PoolAngle[ playerid ] [ 1 ], newrot, 30.0 ) ) { p_PoolAngle[ playerid ] [ 0 ] = newrot; + Pool_UpdatePlayerCamera( playerid, poolid ); - if ( ! p_PoolCameraBirdsEye{ playerid } ) - { - GetXYBehindObjectInAngle(g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], newrot, x, y, 0.675); - SetPlayerCameraPos(playerid, x, y, g_poolTableData[ poolid ] [ E_Z ] + DEFAULT_AIM); - SetPlayerCameraLookAt(playerid, Xa, Ya, Za + 0.170); - } - else - { - SetPlayerCameraPos(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0); - SetPlayerCameraLookAt(playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ]); - } - - GetXYInFrontOfPos( Xa, Ya, newrot + 180, x, y, 0.085 ); + Pool_GetXYInFrontOfPos( Xa, Ya, newrot + 180, x, y, 0.085 ); SetObjectPos( g_poolTableData[ poolid ] [ E_AIMER_OBJECT ], x, y, Za ); SetObjectRot( g_poolTableData[ poolid ] [ E_AIMER_OBJECT ], 7.0, 0, p_PoolAngle[ playerid ] [ 0 ] + 180 ); - GetXYInFrontOfPos( Xa, Ya, newrot + 180 - 5.0, x, y, dist ); // offset 5 degrees + Pool_GetXYInFrontOfPos( Xa, Ya, newrot + 180 - 5.0, x, y, dist ); // offset 5 degrees SetPlayerPos( playerid, x, y, Z ); SetPlayerFacingAngle( playerid, newrot ); } @@ -822,41 +774,32 @@ public OnPoolUpdate( poolid ) } else { - if (g_poolTableData[ poolid ] [ E_DIRECTION ]) - { + if ( g_poolTableData[ poolid ] [ E_DIRECTION ] ) { g_poolTableData[ poolid ] [ E_POWER ] -= 2.0; - } - else - { + } else { g_poolTableData[ poolid ] [ E_POWER ] += 2.0; } - if (g_poolTableData[ poolid ] [ E_POWER ] <= 0) - { + if ( g_poolTableData[ poolid ] [ E_POWER ] <= 0 ) { g_poolTableData[ poolid ] [ E_DIRECTION ] = 0; g_poolTableData[ poolid ] [ E_POWER ] = 2.0; } - else if (g_poolTableData[ poolid ] [ E_POWER ] > 100.0) - { + else if ( g_poolTableData[ poolid ] [ E_POWER ] > 100.0 ) { g_poolTableData[ poolid ] [ E_DIRECTION ] = 1; - g_poolTableData[ poolid ] [ E_POWER ] = 100.0; + g_poolTableData[ poolid ] [ E_POWER ] = 99.0; } - // ShowPlayerPoolTextdraw(playerid); - - SetPlayerProgressBarMaxValue(playerid, g_PoolPowerBar[playerid], 67.0); - SetPlayerProgressBarValue(playerid, g_PoolPowerBar[playerid], ((67.0 * g_poolTableData[ poolid ] [ E_POWER ])/100.0)); - ShowPlayerProgressBar(playerid, g_PoolPowerBar[playerid]); - - TextDrawShowForPlayer(playerid, g_PoolTextdraw); + SetPlayerProgressBarMaxValue( playerid, g_PoolPowerBar[ playerid ], 67.0 ); + SetPlayerProgressBarValue( playerid, g_PoolPowerBar[ playerid ], ( ( 67.0 * g_poolTableData[ poolid ] [ E_POWER ] ) / 100.0 ) ); + ShowPlayerProgressBar( playerid, g_PoolPowerBar[ playerid ] ); + TextDrawShowForPlayer( playerid, g_PoolTextdraw ); } } new current_player = g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ]; - if ( ( ! g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] || g_poolTableData[ poolid ] [ E_FOULS ] || g_poolTableData[ poolid ] [ E_EXTRA_SHOT ] ) && AreAllBallsStopped( poolid ) ) - { + if ( ( ! g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] || g_poolTableData[ poolid ] [ E_FOULS ] || g_poolTableData[ poolid ] [ E_EXTRA_SHOT ] ) && Pool_AreBallsStopped( poolid ) ) { Pool_QueueNextPlayer( poolid, current_player ); SetTimerEx( "RestoreCamera", 800, 0, "d", current_player ); } @@ -904,13 +847,10 @@ public PHY_OnObjectCollideWithObject( object1, object2 ) { foreach ( new id : pooltables ) if ( g_poolTableData[ id ] [ E_STARTED ] ) { - for ( new i = 0; i < 16; i ++ ) + for ( new i = 0; i < 16; i ++ ) if ( object1 == g_poolBallData[ id ] [ E_BALL_OBJECT ] [ i ] ) { - if ( object1 == g_poolBallData[ id ] [ E_BALL_OBJECT ] [ i ] ) - { - PlayPoolSound( id, 31800 + random( 3 ) ); - return 1; - } + PlayPoolSound( id, 31800 + random( 3 ) ); + return 1; } } return 1; @@ -943,7 +883,7 @@ public PHY_OnObjectUpdate( objectid ) if ( objectid == g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ poolball_index ] && ! g_poolBallData[ poolid ] [ E_POCKETED ] [ poolball_index ] && PHY_IsObjectMoving( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ poolball_index ] ) ) { new - holeid = IsBallInHole( poolid, objectid ); + holeid = Pool_IsBallInHole( poolid, objectid ); if ( holeid != -1 ) { @@ -982,7 +922,7 @@ public PHY_OnObjectUpdate( objectid ) // check what was pocketed if ( g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_CUE ) { - GameTextForPlayer( current_player, "~n~~n~~n~~r~~h~You have pocketed the cue ball!", 10000, 4 ); + GameTextForPlayer( current_player, "~n~~n~~n~~r~~h~You have pocketed the cue ball!", 10000, 3 ); Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has wrongly pocketed the cue ball!", ReturnPlayerName( current_player ), current_player ); // penalty for that @@ -1029,7 +969,7 @@ public PHY_OnObjectUpdate( objectid ) opposite_player = current_player == first_player ? second_player : first_player; p_PoolScore[ opposite_player ] += 1; - GameTextForPlayer( current_player, "~n~~n~~n~~r~wrong ball", 3000, 4); + GameTextForPlayer( current_player, "~n~~n~~n~~r~wrong ball", 3000, 3); Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has wrongly pocketed %s %s, instead of %s!", ReturnPlayerName( current_player ), current_player, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolBallOffsetData[ poolball_index ] [ E_BALL_NAME ], g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ current_player ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); // penalty for that @@ -1040,7 +980,7 @@ public PHY_OnObjectUpdate( objectid ) else { p_PoolScore[ current_player ] ++; - GameTextForPlayer( current_player, "~n~~n~~n~~w~Score: +1", 3000, 4); + GameTextForPlayer( current_player, "~n~~n~~n~~g~+1", 3000, 3); Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has pocketed a %s %s!", ReturnPlayerName( current_player ), current_player, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolBallOffsetData[ poolball_index ] [ E_BALL_NAME ] ); // extra shot for scoring one's own @@ -1059,7 +999,7 @@ public PHY_OnObjectUpdate( objectid ) new opposite_holeid = g_poolHoleOpposite[ holeid ]; - RotateXY( g_poolPotOffsetData[ opposite_holeid ] [ 0 ], g_poolPotOffsetData[ opposite_holeid ] [ 1 ], g_poolTableData[ poolid ] [ E_ANGLE ], hole_x, hole_y ); + Pool_RotateXY( g_poolPotOffsetData[ opposite_holeid ] [ 0 ], g_poolPotOffsetData[ opposite_holeid ] [ 1 ], g_poolTableData[ poolid ] [ E_ANGLE ], hole_x, hole_y ); p_PoolHoleGuide[ player_being_marked ] = CreateDynamicObject( 18643, g_poolTableData[ poolid ] [ E_X ] + hole_x, g_poolTableData[ poolid ] [ E_Y ] + hole_y, g_poolTableData[ poolid ] [ E_Z ] - 0.5, 0.0, -90.0, 0.0, .playerid = player_being_marked ); g_poolTableData[ poolid ] [ E_PLAYER_8BALL_TARGET ] [ player_being_marked ] = opposite_holeid; SendPoolMessage( player_being_marked, "You are now required to put the 8-Ball in the designated pocket." ); @@ -1069,7 +1009,7 @@ public PHY_OnObjectUpdate( objectid ) } // rotate hole offsets according to table - RotateXY( g_poolPotOffsetData[ holeid ] [ 0 ], g_poolPotOffsetData[ holeid ] [ 1 ], g_poolTableData[ poolid ] [ E_ANGLE ], hole_x, hole_y ); + Pool_RotateXY( g_poolPotOffsetData[ holeid ] [ 0 ], g_poolPotOffsetData[ holeid ] [ 1 ], g_poolTableData[ poolid ] [ E_ANGLE ], hole_x, hole_y ); // move object into the pocket new move_speed = MoveObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ poolball_index ], g_poolTableData[ poolid ] [ E_X ] + hole_x, g_poolTableData[ poolid ] [ E_Y ] + hole_y, g_poolTableData[ poolid ] [ E_Z ] - 0.5, 1.0); @@ -1092,7 +1032,7 @@ public PHY_OnObjectUpdate( objectid ) stock Pool_OnPlayerWin( poolid, winning_player ) { - if ( ! IsPlayerConnected( winning_player ) ) + if ( ! IsPlayerConnected( winning_player ) && ! IsPlayerNPC( winning_player ) ) return 0; // restore camera @@ -1133,7 +1073,7 @@ stock Pool_QueueNextPlayer( poolid, current_player ) new Float: x, Float: y; - RotateXY( 0.5, 0.0, g_poolTableData[ poolid ] [ E_ANGLE ], x, y ); + Pool_RotateXY( 0.5, 0.0, g_poolTableData[ poolid ] [ E_ANGLE ], x, y ); // make sure object dont exist if ( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ] != -1 ) { @@ -1144,7 +1084,7 @@ stock Pool_QueueNextPlayer( poolid, current_player ) // recreate cueball g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ] = CreateObject( 3003, g_poolTableData[ poolid ] [ E_X ] + x, g_poolTableData[ poolid ] [ E_Y ] + y, g_poolTableData[ poolid ] [ E_Z ] - 0.045, 0.0, 0.0, 0.0 ); - InitBalls( poolid, 0 ); + Pool_InitBalls( poolid, 0 ); } // update turn @@ -1192,7 +1132,7 @@ stock Pool_ResetBallPositions( poolid, begining_ball = 0, last_ball = MAX_POOL_B g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] = CreateObject( modelid, last_x, last_y, last_z, last_rx, last_ry, last_rz ); // initialize physics on each ball - InitBalls( poolid, i ); + Pool_InitBalls( poolid, i ); } } @@ -1220,7 +1160,7 @@ CMD:endgame(playerid) if ( ! IsPlayerAdmin( playerid ) ) return 0; - new iPool = GetClosestPoolTable( playerid ); + new iPool = Pool_GetClosestTable( playerid ); if ( iPool == -1 ) return SendError( playerid, "You must be near a pool table to use this command." ); @@ -1234,7 +1174,7 @@ CMD:endgame(playerid) CMD:play(playerid) { new - iPool = GetClosestPoolTable( playerid ); + iPool = Pool_GetClosestTable( playerid ); if ( iPool == -1 ) return SendError( playerid, "You are not near a pool table." ); @@ -1259,7 +1199,7 @@ CMD:play(playerid) UpdateDynamic3DTextLabelText(g_poolTableData[ iPool ] [ E_LABEL ], -1, sprintf( "{FFDC2E}%s is currently playing a test game.", ReturnPlayerName( playerid )) ); - RespawnPoolBalls( iPool ); + Pool_RespawnBalls( iPool ); } } else @@ -1269,6 +1209,33 @@ CMD:play(playerid) return 1; } +stock Pool_UpdatePlayerCamera( playerid, poolid ) +{ + new + Float: Xa, Float: Ya, Float: Za; + + GetObjectPos( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], Xa, Ya, Za ); + + if ( ! p_PoolCameraBirdsEye{ playerid } ) + { + new + Float: x, Float: y, Float: z; + + GetObjectPos( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], x, y, z ); + + x += ( 0.675 * floatsin( -p_PoolAngle[ playerid ] [ 0 ] + 180.0, degrees ) ); + y += ( 0.675 * floatcos( -p_PoolAngle[ playerid ] [ 0 ] + 180.0, degrees ) ); + + SetPlayerCameraPos( playerid, x, y, g_poolTableData[ poolid ] [ E_Z ] + DEFAULT_AIM ); + SetPlayerCameraLookAt( playerid, Xa, Ya, Za + 0.170 ); + } + else + { + SetPlayerCameraPos( playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0 ); + SetPlayerCameraLookAt( playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] ); + } +} + /* ** Commands ** */ CMD:addpool(playerid, params[]) @@ -1295,7 +1262,7 @@ CMD:addpool(playerid, params[]) CMD:camtest( playerid, params[ ] ) { new - iPool = GetClosestPoolTable( playerid ); + iPool = Pool_GetClosestTable( playerid ); if ( iPool == -1 ) return SendError( playerid, "You are not near a pool table." ); @@ -1314,7 +1281,7 @@ CMD:addpool(playerid, params[]) CMD:setoffset( playerid, params[ ] ) { - new iPool = GetClosestPoolTable( playerid ); + new iPool = Pool_GetClosestTable( playerid ); new offset; new Float: x, Float: y; From 3db3ec273108c295d9b3db47c7eab9ac013d5527 Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Fri, 14 Sep 2018 19:56:07 +1000 Subject: [PATCH 14/17] add system for waging pool --- gamemodes/irresistible/cnr/features/pool.pwn | 86 ++++++++++++++++++-- 1 file changed, 79 insertions(+), 7 deletions(-) diff --git a/gamemodes/irresistible/cnr/features/pool.pwn b/gamemodes/irresistible/cnr/features/pool.pwn index de52f11..01d6d70 100644 --- a/gamemodes/irresistible/cnr/features/pool.pwn +++ b/gamemodes/irresistible/cnr/features/pool.pwn @@ -18,17 +18,17 @@ #define POOL_TIMER_SPEED 30 #define DEFAULT_AIM 0.38 #define DEFAULT_POOL_STRING "Pool Table\n{FFFFFF}Press ENTER To Play" +#define POOL_FEE_RATE 0.02 #define MAX_POOL_TABLES 32 #define MAX_POOL_BALLS 16 // do not modify -#define COL_POOL "{C0C0C0}" +#define DIALOG_POOL_WAGER 3284 /* ** Macros ** */ #define SendPoolMessage(%0,%1) \ SendClientMessageFormatted(%0, -1, "{4B8774}[POOL] {E5861A}" # %1) - /* ** Constants (do not modify) ** */ enum E_POOL_BALL_TYPE { E_STRIPED, @@ -90,6 +90,8 @@ enum E_POOL_TABLE_DATA E_SHOTS_LEFT, E_FOULS, E_PLAYER_8BALL_TARGET[ MAX_PLAYERS ], bool: E_EXTRA_SHOT, + E_WAGER, bool: E_READY, + Float: E_POWER, E_DIRECTION, E_TABLE, Text3D: E_LABEL, @@ -165,6 +167,44 @@ hook OnPlayerConnect( playerid ) return 1; } +hook OnDialogResponse( playerid, dialogid, response, listitem, inputtext[ ] ) +{ + if ( dialogid == DIALOG_POOL_WAGER ) + { + new + poolid = p_PoolID[ playerid ]; + + if ( poolid == -1 ) { + return SendError( playerid, "Unable to identify pool table. Please enter the pool table again." ); + } + + new + wager_amount = strval( inputtext ); + + if ( response && wager_amount > 0 ) + { + if ( wager_amount > GetPlayerCash( playerid ) ) { + ShowPlayerDialog( playerid, DIALOG_POOL_WAGER, DIALOG_STYLE_INPUT, "{FFFFFF}Pool Wager", "{FFFFFF}Please specify the minimum entry fee for the table:\n\n"COL_RED"You do not have this much money!", "Set", "No" ); + } else { + GivePlayerCash( playerid, -wager_amount ); + g_poolTableData[ poolid ] [ E_WAGER ] = wager_amount; + g_poolTableData[ poolid ] [ E_READY ] = true; + Pool_SendTableMessage( poolid, -1, ""COL_GREY"-- "COL_WHITE" %s(%d) has set the pool wager to %s!", ReturnPlayerName( playerid ), playerid, cash_format( wager_amount ) ); + UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], -1, sprintf( "" # COL_GREY "Pool Table\n{FFFFFF}Press ENTER To Join %s(%d)\n"COL_RED"%s Entry", ReturnPlayerName( playerid ), playerid, cash_format( wager_amount ) ) ); + } + return 1; + } + else + { + g_poolTableData[ poolid ] [ E_WAGER ] = 0; + g_poolTableData[ poolid ] [ E_READY ] = true; + Pool_SendTableMessage( poolid, -1, ""COL_GREY"-- "COL_WHITE" %s(%d) has set the pool wager to FREE!", ReturnPlayerName( playerid ), playerid ); + UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], -1, sprintf( "" # COL_GREY "Pool Table\n{FFFFFF}Press ENTER To Join %s(%d)", ReturnPlayerName( playerid ), playerid ) ); + } + } + return 1; +} + hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) { new Float: pooltable_distance = 99999.99; @@ -341,10 +381,10 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) { if ( PRESSED( KEY_SECONDARY_ATTACK ) ) { - if ( IsPlayerPlayingPool( playerid ) ) + if ( IsPlayerPlayingPool( playerid ) && Iter_Contains( poolplayers< poolid >, playerid ) ) { HidePlayerHelpDialog( playerid ); - Pool_SendTableMessage( p_PoolID[ playerid ], COLOR_GREY, "-- "COL_WHITE" %s(%d) has left the table", ReturnPlayerName( playerid ), playerid ); + Pool_SendTableMessage( poolid, COLOR_GREY, "-- "COL_WHITE" %s(%d) has left the table", ReturnPlayerName( playerid ), playerid ); return Pool_RemovePlayer( playerid ); } @@ -358,12 +398,29 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) // ensure this player isn't already joined if ( ! IsPlayerPlayingPool( playerid ) && ! Iter_Contains( poolplayers< poolid >, playerid ) ) { + if ( pool_player_count == 1 && ! g_poolTableData[ poolid ] [ E_READY ] ) { + return SendError( playerid, "This pool table is not ready to play." ); + } + + new + entry_fee = g_poolTableData[ poolid ] [ E_WAGER ]; + + if ( GetPlayerCash( playerid ) < entry_fee && g_poolTableData[ poolid ] [ E_READY ] ) { + return SendError( playerid, "You need %s to join this pool table.", cash_format( entry_fee ) ); + } + + // add to table Iter_Add( poolplayers< poolid >, playerid ); // reset variables p_isPlayingPool{ playerid } = true; p_PoolID[ playerid ] = poolid; + // deduct cash + if ( g_poolTableData[ poolid ] [ E_READY ] ) { + GivePlayerCash( playerid, -entry_fee ); + } + // start the game if there's two players if ( pool_player_count + 1 >= 2 ) { @@ -373,7 +430,6 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) Pool_SendTableMessage( poolid, COLOR_GREY, "-- "COL_WHITE" %s(%d) has joined the table (2/2)", ReturnPlayerName( playerid ), playerid ); Pool_QueueNextPlayer( poolid, random_cuer ); - foreach ( new i : poolplayers< poolid > ) { p_PoolScore[ i ] = 0; PlayerPlaySound( i, 1085, 0.0, 0.0, 0.0 ); @@ -386,8 +442,11 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) } else { + g_poolTableData[ poolid ] [ E_WAGER ] = 0; + g_poolTableData[ poolid ] [ E_READY ] = false; + ShowPlayerDialog( playerid, DIALOG_POOL_WAGER, DIALOG_STYLE_INPUT, "{FFFFFF}Pool Wager", "{FFFFFF}Please specify the minimum entry fee for the table:", "Set", "No Fee" ); ShowPlayerHelpDialog( playerid, 0, "~y~~h~~k~~PED_LOCK_TARGET~ ~w~- Aim Cue~n~~y~~h~~k~~PED_FIREWEAPON~ ~w~- Shoot Cue~n~~y~~h~~k~~PED_JUMPING~ ~w~- Camera Mode~n~~y~~h~~k~~VEHICLE_ENTER_EXIT~ ~w~- Exit Game~n~~n~~r~~h~Waiting for 1 more player..." ); - UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], -1, sprintf( "" # COL_GREY "Pool Table\n{FFFFFF}Press ENTER To Join %s(%d)", ReturnPlayerName( playerid ), playerid ) ); + UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], -1, sprintf( "" # COL_GREY "Pool Table\n"COL_ORANGE"... waiting For %s(%d) ...", ReturnPlayerName( playerid ), playerid ) ); Pool_SendTableMessage( poolid, COLOR_GREY, "-- "COL_WHITE" %s(%d) has joined the table (1/2)", ReturnPlayerName( playerid ), playerid ); } return 1; @@ -432,6 +491,13 @@ stock Pool_RemovePlayer( playerid ) } else { + // no players and is a ready table, then refund + if ( ! Iter_Count( poolplayers< poolid > ) && g_poolTableData[ poolid ] [ E_READY ] ) + { + GivePlayerCash( playerid, g_poolTableData[ poolid ] [ E_WAGER ] ); + g_poolTableData[ poolid ] [ E_READY ] = false; + g_poolTableData[ poolid ] [ E_WAGER ] = 0; + } UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], COLOR_GREY, DEFAULT_POOL_STRING ); } } @@ -685,6 +751,8 @@ stock Pool_EndGame( poolid ) g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] = 0; g_poolTableData[ poolid ] [ E_FOULS ] = 0; g_poolTableData[ poolid ] [ E_EXTRA_SHOT ] = false; + g_poolTableData[ poolid ] [ E_READY ] = false; + g_poolTableData[ poolid ] [ E_WAGER ] = 0; KillTimer( g_poolTableData[ poolid ] [ E_TIMER ] ); DestroyObject( g_poolTableData[ poolid ] [ E_AIMER_OBJECT ] ); @@ -1035,13 +1103,17 @@ stock Pool_OnPlayerWin( poolid, winning_player ) if ( ! IsPlayerConnected( winning_player ) && ! IsPlayerNPC( winning_player ) ) return 0; + new + win_amount = floatround( float( g_poolTableData[ poolid ] [ E_WAGER ] ) * POOL_FEE_RATE ); + // restore camera RestoreCamera( winning_player ); + GivePlayerCash( winning_player, win_amount ); // winning player Pool_SendTableMessage( poolid, -1, "{9FCF30}****************************************************************************************"); Pool_SendTableMessage( poolid, -1, "{9FCF30}Player {FF8000}%s {9FCF30}has won the game!", ReturnPlayerName( winning_player ) ); - // Pool_SendTableMessage( poolid, "{9FCF30}Prize: {377CC8}%s | -%0.0f%s percent fee", number_format(w_chips), T_POT_FEE_RATE * 100.0, "%%"); + Pool_SendTableMessage( poolid, -1, "{9FCF30}Prize: {377CC8}%s | -%0.0f%s percent fee", number_format( win_amount ), win_amount > 0 ? POOL_FEE_RATE * 100.0 : 0.0, "%%"); Pool_SendTableMessage( poolid, -1, "{9FCF30}****************************************************************************************"); return 1; } From 0a18215da9f8f976a45e0d11443b7cf85b97fd2f Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Fri, 14 Sep 2018 21:10:29 +1000 Subject: [PATCH 15/17] if a player pockets the cue ball, the next player will be able to set it next turn --- gamemodes/irresistible/cnr/features/pool.pwn | 95 ++++++++++++++++---- 1 file changed, 77 insertions(+), 18 deletions(-) diff --git a/gamemodes/irresistible/cnr/features/pool.pwn b/gamemodes/irresistible/cnr/features/pool.pwn index 01d6d70..572e1fb 100644 --- a/gamemodes/irresistible/cnr/features/pool.pwn +++ b/gamemodes/irresistible/cnr/features/pool.pwn @@ -88,7 +88,7 @@ enum E_POOL_TABLE_DATA E_NEXT_SHOOTER, E_SHOTS_LEFT, E_FOULS, E_PLAYER_8BALL_TARGET[ MAX_PLAYERS ], - bool: E_EXTRA_SHOT, + bool: E_EXTRA_SHOT, bool: E_CUE_POCKETED, E_WAGER, bool: E_READY, @@ -234,7 +234,7 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) SetPlayerArmedWeapon( playerid, 0 ); SetPlayerAttachedObject( playerid, 0, 338, 6, 0, 0.07, -0.85, 0, 0, 0 ); - ApplyAnimation( playerid, "POOL", "POOL_ChalkCue", 3.0, 0, 0, 0, 0, 0, 1 ); + ApplyAnimation( playerid, "POOL", "POOL_ChalkCue", 3.0, 0, 1, 1, 1, 0, 1 ); SetTimerEx( "PlayPoolSound", 1400, false, "dd", playerid, 31807 ); SetTimerEx( "RestoreWeapon", 3500, false, "d", playerid ); @@ -268,6 +268,10 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) return SendPoolMessage( playerid, "It is not your turn. Please wait." ); } + if ( g_poolTableData[ poolid ] [ E_CUE_POCKETED ] ) { + return SendPoolMessage( playerid, "You can aim the cue as soon as you place the cue ball." ); + } + if ( ! p_PoolChalking{ playerid } && g_poolTableData[ poolid ] [ E_AIMER ] == -1 ) { new Float:X, Float:Y, Float:Z, @@ -446,7 +450,7 @@ hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) g_poolTableData[ poolid ] [ E_READY ] = false; ShowPlayerDialog( playerid, DIALOG_POOL_WAGER, DIALOG_STYLE_INPUT, "{FFFFFF}Pool Wager", "{FFFFFF}Please specify the minimum entry fee for the table:", "Set", "No Fee" ); ShowPlayerHelpDialog( playerid, 0, "~y~~h~~k~~PED_LOCK_TARGET~ ~w~- Aim Cue~n~~y~~h~~k~~PED_FIREWEAPON~ ~w~- Shoot Cue~n~~y~~h~~k~~PED_JUMPING~ ~w~- Camera Mode~n~~y~~h~~k~~VEHICLE_ENTER_EXIT~ ~w~- Exit Game~n~~n~~r~~h~Waiting for 1 more player..." ); - UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], -1, sprintf( "" # COL_GREY "Pool Table\n"COL_ORANGE"... waiting For %s(%d) ...", ReturnPlayerName( playerid ), playerid ) ); + UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], -1, sprintf( "" # COL_GREY "Pool Table\n"COL_ORANGE"... Waiting For %s(%d) ...", ReturnPlayerName( playerid ), playerid ) ); Pool_SendTableMessage( poolid, COLOR_GREY, "-- "COL_WHITE" %s(%d) has joined the table (1/2)", ReturnPlayerName( playerid ), playerid ); } return 1; @@ -753,6 +757,7 @@ stock Pool_EndGame( poolid ) g_poolTableData[ poolid ] [ E_EXTRA_SHOT ] = false; g_poolTableData[ poolid ] [ E_READY ] = false; g_poolTableData[ poolid ] [ E_WAGER ] = 0; + g_poolTableData[ poolid ] [ E_CUE_POCKETED ] = false; KillTimer( g_poolTableData[ poolid ] [ E_TIMER ] ); DestroyObject( g_poolTableData[ poolid ] [ E_AIMER_OBJECT ] ); @@ -804,17 +809,69 @@ public OnPoolUpdate( poolid ) return 1; } - if ( g_poolTableData[ poolid ] [ E_AIMER ] != -1 ) + new Float: Xa, Float: Ya, Float: Za; + new Float: X, Float: Y, Float: Z; + new keys, ud, lr; + + if ( g_poolTableData[ poolid ] [ E_CUE_POCKETED ] ) { - new playerid = g_poolTableData[ poolid ] [ E_AIMER ], keys, ud, lr; + new + playerid = g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ]; + + GetPlayerKeys( playerid, keys, ud, lr ); + GetObjectPos( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], X, Y, Z ); + + if ( ud == KEY_UP ) Y += 0.01; + else if ( ud == KEY_DOWN ) Y -= 0.01; + + if ( lr == KEY_LEFT ) X -= 0.01; + else if ( lr == KEY_RIGHT ) X += 0.01; + + // boundaries + new Float: vertices[ 4 ]; + + Pool_RotateXY( g_poolTableData[ poolid ] [ E_X ] + 0.85, g_poolTableData[ poolid ] [ E_Y ] + 0.4, g_poolTableData[ poolid ] [ E_ANGLE ], vertices[ 0 ], vertices[ 1 ] ); + Pool_RotateXY( g_poolTableData[ poolid ] [ E_X ] - 0.85, g_poolTableData[ poolid ] [ E_Y ] - 0.4, g_poolTableData[ poolid ] [ E_ANGLE ], vertices[ 2 ], vertices[ 3 ] ); + + if ( X > vertices[ 0 ] ) X = vertices[ 0 ]; + else if ( X < vertices[ 2 ] ) X = vertices[ 2 ]; + + if ( Y > vertices[ 1 ] ) Y = vertices[ 1 ]; + else if ( Y < vertices[ 3 ] ) Y = vertices[ 3 ]; + + // set position + SetObjectPos( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], X, Y, Z ); + + if ( keys & KEY_FIRE ) + { + // check if we are placing the pool ball near another pool ball + for ( new i = 1; i < MAX_POOL_BALLS; i ++ ) if ( IsValidObject( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ] ) ) { + GetObjectPos( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ i ], Xa, Ya, Za ); + if ( GetDistanceFromPointToPoint( X, Y, Xa, Ya ) < 0.085 ) { + return GameTextForPlayer( playerid, "~n~~n~~n~~r~~h~Ball too close to other!", 500, 3 ); + } + } + + // reset state + SetCameraBehindPlayer( playerid ); + TogglePlayerControllable( playerid, true ); + g_poolTableData[ poolid ] [ E_CUE_POCKETED ] = false; + ApplyAnimation( playerid, "CARRY", "crry_prtial", 4.0, 0, 1, 1, 0, 0 ); + Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has placed the cueball!", ReturnPlayerName( playerid ), playerid ); + } + } + else if ( g_poolTableData[ poolid ] [ E_AIMER ] != -1 ) + { + new + playerid = g_poolTableData[ poolid ] [ E_AIMER ]; GetPlayerKeys( playerid, keys, ud, lr ); if ( ! ( keys & KEY_FIRE ) ) { - if (lr) + if ( lr ) { - new Float: X, Float: Y, Float: Z, Float: Xa, Float: Ya, Float: Za, Float: x, Float: y, Float: newrot, Float: dist; + new Float: x, Float: y, Float: newrot, Float: dist; GetPlayerPos(playerid, X, Y ,Z); GetObjectPos(g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], Xa, Ya, Za); @@ -869,7 +926,7 @@ public OnPoolUpdate( poolid ) if ( ( ! g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] || g_poolTableData[ poolid ] [ E_FOULS ] || g_poolTableData[ poolid ] [ E_EXTRA_SHOT ] ) && Pool_AreBallsStopped( poolid ) ) { Pool_QueueNextPlayer( poolid, current_player ); - SetTimerEx( "RestoreCamera", 800, 0, "d", current_player ); + SetTimerEx( "RestoreCamera", 800, 0, "d", current_player ); } return 1; } @@ -958,6 +1015,7 @@ public PHY_OnObjectUpdate( objectid ) new first_player = Iter_First( poolplayers< poolid > ); new second_player = Iter_Last( poolplayers< poolid > ); new current_player = g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ]; + new opposite_player = current_player != first_player ? first_player : second_player; // printf ("first_player %d, second_player %d, current_player = %d", first_player, second_player, current_player); @@ -990,19 +1048,17 @@ public PHY_OnObjectUpdate( objectid ) // check what was pocketed if ( g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_CUE ) { - GameTextForPlayer( current_player, "~n~~n~~n~~r~~h~You have pocketed the cue ball!", 10000, 3 ); - Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has wrongly pocketed the cue ball!", ReturnPlayerName( current_player ), current_player ); + GameTextForPlayer( current_player, "~n~~n~~n~~r~wrong ball", 3000, 3); + Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has pocketed the cue ball, %s(%d) will set it!", ReturnPlayerName( current_player ), current_player, ReturnPlayerName( opposite_player ), opposite_player ); // penalty for that g_poolTableData[ poolid ] [ E_FOULS ] ++; g_poolTableData[ poolid ] [ E_SHOTS_LEFT ] = 0; g_poolTableData[ poolid ] [ E_EXTRA_SHOT ] = false; + g_poolTableData[ poolid ] [ E_CUE_POCKETED ] = true; } else if ( g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_8BALL ) { - new - opposite_player = current_player != first_player ? first_player : second_player; - g_poolTableData[ poolid ] [ E_BALLS_SCORED ] ++; // restore player camera @@ -1033,9 +1089,6 @@ public PHY_OnObjectUpdate( objectid ) // check if player pocketed their own ball type or btfo if ( g_poolTableData[ poolid ] [ E_BALLS_SCORED ] > 1 && g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ current_player ] != g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] ) { - new - opposite_player = current_player == first_player ? second_player : first_player; - p_PoolScore[ opposite_player ] += 1; GameTextForPlayer( current_player, "~n~~n~~n~~r~wrong ball", 3000, 3); Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has wrongly pocketed %s %s, instead of %s!", ReturnPlayerName( current_player ), current_player, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolBallOffsetData[ poolball_index ] [ E_BALL_NAME ], g_poolTableData[ poolid ] [ E_PLAYER_BALL_TYPE ] [ current_player ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ) ); @@ -1048,7 +1101,7 @@ public PHY_OnObjectUpdate( objectid ) else { p_PoolScore[ current_player ] ++; - GameTextForPlayer( current_player, "~n~~n~~n~~g~+1", 3000, 3); + GameTextForPlayer( current_player, "~n~~n~~n~~g~+1 score", 3000, 3); Pool_SendTableMessage( poolid, -1, "{2DD9A9} * * %s(%d) has pocketed a %s %s!", ReturnPlayerName( current_player ), current_player, g_poolBallOffsetData[ poolball_index ] [ E_BALL_TYPE ] == E_STRIPED ? ( "Striped" ) : ( "Solid" ), g_poolBallOffsetData[ poolball_index ] [ E_BALL_NAME ] ); // extra shot for scoring one's own @@ -1155,8 +1208,14 @@ stock Pool_QueueNextPlayer( poolid, current_player ) // recreate cueball g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ] = CreateObject( 3003, g_poolTableData[ poolid ] [ E_X ] + x, g_poolTableData[ poolid ] [ E_Y ] + y, g_poolTableData[ poolid ] [ E_Z ] - 0.045, 0.0, 0.0, 0.0 ); - Pool_InitBalls( poolid, 0 ); + + // set next player camera + new next_shooter = g_poolTableData[ poolid ] [ E_NEXT_SHOOTER ]; + SetPlayerCameraPos( next_shooter, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] + 2.0 ); + SetPlayerCameraLookAt( next_shooter, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_Y ], g_poolTableData[ poolid ] [ E_Z ] ); + ApplyAnimation( next_shooter, "POOL", "POOL_Idle_Stance", 3.0, 0, 1, 1, 0, 0, 1 ); + TogglePlayerControllable( next_shooter, false ); } // update turn From 22f69ca1be760bead4df58c6fc20e8004e5dbd19 Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Sat, 15 Sep 2018 12:05:53 +1000 Subject: [PATCH 16/17] setlevel was not working for level 6 ... moved server defs to _config --- gamemodes/irresistible/cnr/commands/admin/admin_six.pwn | 2 +- gamemodes/irresistible/config/_config.pwn | 6 ++++++ gamemodes/sf-cnr.pwn | 9 +-------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/gamemodes/irresistible/cnr/commands/admin/admin_six.pwn b/gamemodes/irresistible/cnr/commands/admin/admin_six.pwn index c2dc327..527a48a 100644 --- a/gamemodes/irresistible/cnr/commands/admin/admin_six.pwn +++ b/gamemodes/irresistible/cnr/commands/admin/admin_six.pwn @@ -260,7 +260,7 @@ CMD:setlevel( playerid, params[ ] ) iLevel ; if ( !IsPlayerAdmin( playerid ) && p_AdminLevel[ playerid ] < 6 ) return SendError( playerid, ADMIN_COMMAND_REJECT ); - else if ( sscanf( params, "d", pID, iLevel ) ) SendUsage( playerid, "/setlevel [PLAYER_ID] [LEVEL]"); + else if ( sscanf( params, "ud", pID, iLevel ) ) SendUsage( playerid, "/setlevel [PLAYER_ID] [LEVEL]"); else if ( iLevel < 0 || iLevel > 6 ) return SendError( playerid, "Please specify an administration level between 0 and 6." ); else if ( !IsPlayerConnected( pID ) || IsPlayerNPC( pID ) ) return SendError( playerid, "Invalid Player ID." ); else diff --git a/gamemodes/irresistible/config/_config.pwn b/gamemodes/irresistible/config/_config.pwn index 9101a56..eca375b 100644 --- a/gamemodes/irresistible/config/_config.pwn +++ b/gamemodes/irresistible/config/_config.pwn @@ -8,3 +8,9 @@ /* ** Includes ** */ #include "irresistible\config\database.pwn" // keep #1 #include "irresistible\config\colors.pwn" + +/* ** Configuration ** */ +#define FILE_BUILD "v11.36.105" +#define SERVER_NAME "San Fierro Cops And Robbers (0.3.7)" +#define SERVER_WEBSITE "www.sfcnr.com" +#define SERVER_IP "54.36.127.43:7777" diff --git a/gamemodes/sf-cnr.pwn b/gamemodes/sf-cnr.pwn index b6209b7..7b0a7ea 100644 --- a/gamemodes/sf-cnr.pwn +++ b/gamemodes/sf-cnr.pwn @@ -112,13 +112,6 @@ new bool: False = false; #define CreateBillboard(%0,%1,%2,%3,%4) SetDynamicObjectMaterialText(CreateDynamicObject(7246,%1,%2,%3,0,0,%4),0,(%0),120,"Arial",24,0,-1,-16777216,1) -/* ** Configuration ** */ -#define FILE_BUILD "v11.36.105" -#define SERVER_NAME "San Fierro Cops And Robbers (0.3.7)" -#define SERVER_WEBSITE "www.sfcnr.com" -#define SERVER_IP "192.169.82.202:7777" - - //#define MAX_WEAPONS 54 #define MAX_CLASS_BAN_WARNS 3 #define MAX_CAR_MODS 15 @@ -14549,7 +14542,7 @@ function OnSafeHelperUpdate( playerid, robberyid ) Float: distance = distanceFromSafe( playerid, robberyid ) ; - if ( robberyid == INVALID_OBJECT_ID || distance > 100.0 || !IsPlayerConnected( playerid ) || !IsPlayerSpawned( playerid ) ) + if ( robberyid == INVALID_OBJECT_ID || distance > 100.0 || ! IsPlayerConnected( playerid ) || ! IsPlayerSpawned( playerid ) || IsPlayerInCasino( playerid ) || IsPlayerPlayingPool( playerid ) ) { p_SafeHelperTimer[ playerid ] = -1; HidePlayerHelpDialog( playerid ); From 91463f020b79c1840e1502da2150848482d8d11a Mon Sep 17 00:00:00 2001 From: Lorenc Pekaj Date: Sat, 15 Sep 2018 12:06:35 +1000 Subject: [PATCH 17/17] if player distant from pool, auto removed from table. lot of bug fixes --- gamemodes/irresistible/cnr/features/pool.pwn | 101 ++++++++++++------- 1 file changed, 62 insertions(+), 39 deletions(-) diff --git a/gamemodes/irresistible/cnr/features/pool.pwn b/gamemodes/irresistible/cnr/features/pool.pwn index 572e1fb..5442416 100644 --- a/gamemodes/irresistible/cnr/features/pool.pwn +++ b/gamemodes/irresistible/cnr/features/pool.pwn @@ -21,7 +21,7 @@ #define POOL_FEE_RATE 0.02 #define MAX_POOL_TABLES 32 -#define MAX_POOL_BALLS 16 // do not modify +#define MAX_POOL_BALLS (16) // do not modify #define DIALOG_POOL_WAGER 3284 @@ -90,7 +90,7 @@ enum E_POOL_TABLE_DATA E_SHOTS_LEFT, E_FOULS, E_PLAYER_8BALL_TARGET[ MAX_PLAYERS ], bool: E_EXTRA_SHOT, bool: E_CUE_POCKETED, - E_WAGER, bool: E_READY, + E_WAGER, bool: E_READY, E_CUEBALL_AREA, Float: E_POWER, E_DIRECTION, @@ -138,8 +138,8 @@ hook OnScriptInit( ) TextDrawSetSelectable(g_PoolTextdraw, 0); // create static pooltables - CreatePoolTable( 2048.5801, 1330.8917, 10.6719, 0, 0 ); - // CreatePoolTable(Float: X, Float: Y, Float: Z, Float: A = 0.0, interior = 0, world = 0) + CreatePoolTable( 510.10159, -84.83590, 998.93750, 90.00000, 11, 7 ); // misty's bar + CreatePoolTable( 506.48441, -84.83590, 998.93750, 90.00000, 11, 7 ); // misty's bar printf( "[POOL TABLES]: %d pool tables have been successfully loaded.", Iter_Count( pooltables ) ); return 1; @@ -164,6 +164,7 @@ hook OnPlayerDeath( playerid, killerid, reason ) hook OnPlayerConnect( playerid ) { g_PoolPowerBar[ playerid ] = CreatePlayerProgressBar( playerid, 530.000000, 233.000000, 61.000000, 6.199999, -1429936641, 100.0000, 0 ); + RemoveBuildingForPlayer( playerid, 2964, 510.1016, -84.8359, 997.9375, 9999.9 ); return 1; } @@ -190,7 +191,7 @@ hook OnDialogResponse( playerid, dialogid, response, listitem, inputtext[ ] ) g_poolTableData[ poolid ] [ E_WAGER ] = wager_amount; g_poolTableData[ poolid ] [ E_READY ] = true; Pool_SendTableMessage( poolid, -1, ""COL_GREY"-- "COL_WHITE" %s(%d) has set the pool wager to %s!", ReturnPlayerName( playerid ), playerid, cash_format( wager_amount ) ); - UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], -1, sprintf( "" # COL_GREY "Pool Table\n{FFFFFF}Press ENTER To Join %s(%d)\n"COL_RED"%s Entry", ReturnPlayerName( playerid ), playerid, cash_format( wager_amount ) ) ); + UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], -1, sprintf( "" # COL_GREY "Pool Table\n"COL_GREEN"Press ENTER To Join %s(%d)\n"COL_RED"%s Entry", ReturnPlayerName( playerid ), playerid, cash_format( wager_amount ) ) ); } return 1; } @@ -199,7 +200,26 @@ hook OnDialogResponse( playerid, dialogid, response, listitem, inputtext[ ] ) g_poolTableData[ poolid ] [ E_WAGER ] = 0; g_poolTableData[ poolid ] [ E_READY ] = true; Pool_SendTableMessage( poolid, -1, ""COL_GREY"-- "COL_WHITE" %s(%d) has set the pool wager to FREE!", ReturnPlayerName( playerid ), playerid ); - UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], -1, sprintf( "" # COL_GREY "Pool Table\n{FFFFFF}Press ENTER To Join %s(%d)", ReturnPlayerName( playerid ), playerid ) ); + UpdateDynamic3DTextLabelText( g_poolTableData[ poolid ] [ E_LABEL ], -1, sprintf( "" # COL_GREY "Pool Table\n"COL_GREEN"Press ENTER To Join %s(%d)", ReturnPlayerName( playerid ), playerid ) ); + } + } + return 1; +} + +hook OnPlayerUpdateEx( playerid ) +{ + new + poolid = p_PoolID[ playerid ]; + + if ( IsPlayerPlayingPool( playerid ) && poolid != -1 ) + { + new + Float: distance_to_table = GetPlayerDistanceFromPoint( playerid, g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_X ], g_poolTableData[ poolid ] [ E_X ] ); + + if ( distance_to_table >= 25.0 ) + { + Pool_SendTableMessage( poolid, COLOR_GREY, "-- "COL_WHITE" %s(%d) has been kicked from the table [Reason: Out Of Range]", ReturnPlayerName( playerid ), playerid ); + return Pool_RemovePlayer( playerid ), 1; } } return 1; @@ -516,38 +536,50 @@ stock CreatePoolTable( Float: X, Float: Y, Float: Z, Float: A = 0.0, interior = } new - gID = Iter_Free( pooltables ); + poolid = Iter_Free( pooltables ); - if ( gID != ITER_NONE ) + if ( poolid != ITER_NONE ) { new Float: x_vertex[ 4 ], Float: y_vertex[ 4 ]; - Iter_Add( pooltables, gID ); + Iter_Add( pooltables, poolid ); - g_poolTableData[ gID ] [ E_X ] = X; - g_poolTableData[ gID ] [ E_Y ] = Y; - g_poolTableData[ gID ] [ E_Z ] = Z; - g_poolTableData[ gID ] [ E_ANGLE ] = A; + g_poolTableData[ poolid ] [ E_X ] = X; + g_poolTableData[ poolid ] [ E_Y ] = Y; + g_poolTableData[ poolid ] [ E_Z ] = Z; + g_poolTableData[ poolid ] [ E_ANGLE ] = A; - g_poolTableData[ gID ] [ E_INTERIOR ] = interior; - g_poolTableData[ gID ] [ E_WORLD ] = world; + g_poolTableData[ poolid ] [ E_INTERIOR ] = interior; + g_poolTableData[ poolid ] [ E_WORLD ] = world; - g_poolTableData[ gID] [ E_TABLE ] = CreateDynamicObject( 2964, X, Y, Z - 1.0, 0.0, 0.0, A, world, interior ); - g_poolTableData[ gID] [ E_LABEL ] = CreateDynamic3DTextLabel( DEFAULT_POOL_STRING, COLOR_GREY, X, Y, Z, 10.0, INVALID_PLAYER_ID, INVALID_VEHICLE_ID, 0, world, interior ); + g_poolTableData[ poolid ] [ E_TABLE ] = CreateDynamicObject( 2964, X, Y, Z - 1.0, 0.0, 0.0, A, .interiorid = interior, .worldid = world ); + g_poolTableData[ poolid ] [ E_LABEL ] = CreateDynamic3DTextLabel( DEFAULT_POOL_STRING, COLOR_GREY, X, Y, Z, 10.0, .interiorid = interior, .worldid = world ); Pool_RotateXY( -0.964, -0.51, A, x_vertex[ 0 ], y_vertex[ 0 ] ); Pool_RotateXY( -0.964, 0.533, A, x_vertex[ 1 ], y_vertex[ 1 ] ); Pool_RotateXY( 0.976, -0.51, A, x_vertex[ 2 ], y_vertex[ 2 ] ); Pool_RotateXY( 0.976, 0.533, A, x_vertex[ 3 ], y_vertex[ 3 ] ); - PHY_CreateWall( x_vertex[0] + X, y_vertex[0] + Y, x_vertex[1] + X, y_vertex[1] + Y); - PHY_CreateWall( x_vertex[1] + X, y_vertex[1] + Y, x_vertex[3] + X, y_vertex[3] + Y); - PHY_CreateWall( x_vertex[2] + X, y_vertex[2] + Y, x_vertex[3] + X, y_vertex[3] + Y); - PHY_CreateWall( x_vertex[0] + X, y_vertex[0] + Y, x_vertex[2] + X, y_vertex[2] + Y); + PHY_CreateWall( x_vertex[ 0 ] + X, y_vertex[ 0 ] + Y, x_vertex[ 1 ] + X, y_vertex[ 1 ] + Y ); + PHY_CreateWall( x_vertex[ 1 ] + X, y_vertex[ 1 ] + Y, x_vertex[ 3 ] + X, y_vertex[ 3 ] + Y ); + PHY_CreateWall( x_vertex[ 2 ] + X, y_vertex[ 2 ] + Y, x_vertex[ 3 ] + X, y_vertex[ 3 ] + Y ); + PHY_CreateWall( x_vertex[ 0 ] + X, y_vertex[ 0 ] + Y, x_vertex[ 2 ] + X, y_vertex[ 2 ] + Y ); + + // create boundary for replacing the cueball + new + Float: vertices[ 4 ]; + + Pool_RotateXY( 0.85, 0.4, g_poolTableData[ poolid ] [ E_ANGLE ], vertices[ 0 ], vertices[ 1 ] ); + Pool_RotateXY( -0.85, -0.4, g_poolTableData[ poolid ] [ E_ANGLE ], vertices[ 2 ], vertices[ 3 ] ); + + vertices[ 0 ] += g_poolTableData[ poolid ] [ E_X ], vertices[ 2 ] += g_poolTableData[ poolid ] [ E_X ]; + vertices[ 1 ] += g_poolTableData[ poolid ] [ E_Y ], vertices[ 3 ] += g_poolTableData[ poolid ] [ E_Y ]; + + g_poolTableData[ poolid ] [ E_CUEBALL_AREA ] = CreateDynamicRectangle( vertices[ 2 ], vertices[ 3 ], vertices[ 0 ], vertices[ 1 ], .interiorid = interior, .worldid = world ); #if defined POOL_DEBUG - ReloadPotTestLabel( 0, gID ); + ReloadPotTestLabel( 0, poolid ); /*new Float: middle_x; new Float: middle_y; CreateDynamicObject( 18643, x_vertex[0] + X, y_vertex[0] + Y, Z - 1.0, 0.0, -90.0, 0.0 ); @@ -574,7 +606,7 @@ stock CreatePoolTable( Float: X, Float: Y, Float: Z, Float: A = 0.0, interior = CreateDynamicObject( 18643, ((x_vertex[0] + X) + middle_x) / 2.0, ((y_vertex[2] + Y) + middle_y) / 2.0, Z - 1.0, 0.0, -90.0, 0.0 );*/ #endif } - return gID; + return poolid; } stock Pool_GetClosestTable( playerid, &Float: dis = 99999.99 ) @@ -827,21 +859,12 @@ public OnPoolUpdate( poolid ) if ( lr == KEY_LEFT ) X -= 0.01; else if ( lr == KEY_RIGHT ) X += 0.01; - // boundaries - new Float: vertices[ 4 ]; - - Pool_RotateXY( g_poolTableData[ poolid ] [ E_X ] + 0.85, g_poolTableData[ poolid ] [ E_Y ] + 0.4, g_poolTableData[ poolid ] [ E_ANGLE ], vertices[ 0 ], vertices[ 1 ] ); - Pool_RotateXY( g_poolTableData[ poolid ] [ E_X ] - 0.85, g_poolTableData[ poolid ] [ E_Y ] - 0.4, g_poolTableData[ poolid ] [ E_ANGLE ], vertices[ 2 ], vertices[ 3 ] ); - - if ( X > vertices[ 0 ] ) X = vertices[ 0 ]; - else if ( X < vertices[ 2 ] ) X = vertices[ 2 ]; - - if ( Y > vertices[ 1 ] ) Y = vertices[ 1 ]; - else if ( Y < vertices[ 3 ] ) Y = vertices[ 3 ]; - - // set position - SetObjectPos( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], X, Y, Z ); + // set position only if it is within boundaries + if ( IsPointInDynamicArea( g_poolTableData[ poolid ] [ E_CUEBALL_AREA ], X, Y, 0.0 ) ) { + SetObjectPos( g_poolBallData[ poolid ] [ E_BALL_OBJECT ] [ 0 ], X, Y, Z ); + } + // click to set if ( keys & KEY_FIRE ) { // check if we are placing the pool ball near another pool ball @@ -1157,7 +1180,7 @@ stock Pool_OnPlayerWin( poolid, winning_player ) return 0; new - win_amount = floatround( float( g_poolTableData[ poolid ] [ E_WAGER ] ) * POOL_FEE_RATE ); + win_amount = floatround( float( g_poolTableData[ poolid ] [ E_WAGER ] ) * ( 1 - POOL_FEE_RATE ) ); // restore camera RestoreCamera( winning_player ); @@ -1166,7 +1189,7 @@ stock Pool_OnPlayerWin( poolid, winning_player ) // winning player Pool_SendTableMessage( poolid, -1, "{9FCF30}****************************************************************************************"); Pool_SendTableMessage( poolid, -1, "{9FCF30}Player {FF8000}%s {9FCF30}has won the game!", ReturnPlayerName( winning_player ) ); - Pool_SendTableMessage( poolid, -1, "{9FCF30}Prize: {377CC8}%s | -%0.0f%s percent fee", number_format( win_amount ), win_amount > 0 ? POOL_FEE_RATE * 100.0 : 0.0, "%%"); + Pool_SendTableMessage( poolid, -1, "{9FCF30}Prize: {377CC8}%s | -%0.0f%s percent fee", cash_format( win_amount ), win_amount > 0 ? POOL_FEE_RATE * 100.0 : 0.0, "%%"); Pool_SendTableMessage( poolid, -1, "{9FCF30}****************************************************************************************"); return 1; }