' Jasc Soccer Just Another Sensi Clone - a try to make a sensi clone by Pitto

' a must
#include "fbgfx.bi"

'this is the language I use
Using FB

'oh yea, I like random numbers, They're so useful and funny! :)
randomize timer()
'#DEFINE#################################################################################

#define GAME_NAME "JASC SOCCER"
#define GAME_VERSION "0.21"
#define GAME_AUTHOR "Pitto"

'USEFUL CONSTS###########################################################################
'no change x and y, please, or the gk may get crazy :O
const PITCH_X as Integer = 50
const PITCH_Y as Integer = 50
'pitch dimensions
const PITCH_W as Integer = 768 'use a 32 multiplier… the pitch texture may fit better!
const PITCH_H as Integer = 992 'idem
const PITCH_PENALTY_AREA as Single = PITCH_W*0.30 'see update players sub for details
'net dimensions
const PITCH_NET_W as Integer = 100
const PITCH_NET_H as Integer = 25
const PITCH_MIDDLE_W as Integer = PITCH_W\2 + PITCH_X
const PITCH_MIDDLE_H as Integer = PITCH_H\2 + PITCH_Y
'net positions
const PITCH_NET_TOP_Y as Integer = PITCH_W\2+PITCH_Y
const PITCH_NET_BOTTOM_Y as Integer = PITCH_W\2+PITCH_Y+PITCH_H
'TACTIC CONSTS --------------------------------------------------------------------------
'tiles on the pitch *NO CHANGE THIS VALUE PLEASE!*** JASC MAY CRASH :(
const TILES_N_TOT as Integer = 35
const COL_TOT_N as Integer = 6
const ROW_TOT_N as Integer = 6
'PHYSICS CONSTS -------------------------------------------------------------------------
'gravity acceleration
const GRAVITY_ACCEL as single = 9.80665f
'friction of the ball bouncing on the pitch
const BOUNCE_FRICTION as single = 0.85
'friction of the air
const AIR_FRICTION as single = 0.98
'friction of the pitch
const FRICTION as single = 0.9
'maximum speed the ball can reach so it doesn't become a ball flame
const BALL_MAX_SPEED as Integer = 20
'minimum speed of the ball
const BALL_MIN_SPEED as Single = 0.5
const GRAVITY as single = 0.980665f
'TRIGONOMETRIC CONSTS--------------------------------------------------------------------
const PI as single = 3.14159265f
const PI_2 as single = PI/2
const _2PI_1_8 as single = PI/4
const _2PI_2_8 as single = PI/2
const _2PI_3_8 as single = PI*0.75
const _2PI_5_8 as single = PI + _2PI_1_8
const _2PI_6_8 as single = PI + PI/2
const _2PI_7_8 as single = PI + PI*0.75
const _2PI as single = PI*2
const _2PI8 as single = _2PI_1_8
'DISPLAY CONSTS -------------------------------------------------------------------------
'screen width and height
'IMPORTANT! -> Not less than 450 x 200 or the sprites may load badly
const SCREEN_W as Integer = 640 
const SCREEN_H as Integer = 480
'useful to don't allow the camera to move everywere, this sets a limit
const CAMERA_PADDING as Integer = 45
'ratio of the xy movements of the camera having the ball as reference point
const CAMERA_EASING_RATIO as Integer = 6
'PLAYERS CONSTS--------------------------------------------------------------------------
'players for each team *SAME AS ABOVE* :(
#define PL_N_TOT 11
'default speed of the players
#define PL_DEFAULT_SPEED 1.35
'delay of the player before executing another action
#define PL_DELAY_TIME 50
#define PL_DELAY_FALLING 10
#define PL_DELAY_FALLED 20
'minimum distance between two players - see check_pl_collisions sub for details
#define PL_MIN_DIST 8
'minimum distance between two sliders - see check_pl_collisions sub for details
#define PL_MIN_SLIDE_DIST 16
'minimum distance from opponent pl to allow pl owner of the ball to run to the net
#define PL_RUN_SPACE 40
'maximum distance to allow the human pl to pass to another player
#define MAX_DIST_PASS 400
'total number of the player sprites
#define PL_SPRITES_TOT_N 136
'possibility % a slide contact become a foul
#define RND_SLIDE_FOUL 50
'possibility % a contact become falling
#define RND_CONTACT_FALL 2

'lenght in ms of the sleep statement
#define SLEEP_TIME 20

'colors
#define C_BLACK &h000000
#define C_WHITE &hFFFFFF
#define C_GRAY &h7F7F7F
#define C_RED &hFF0000
#define C_BLUE &h0000FF
#define C_GREEN &h00FF00
#define C_YELLOW &hFFFF00
#define C_CYAN &h00FFFF
#define C_LILIAC &h7F00FFs
#define C_ORANGE &hFF7F00
#define C_PURPLE &h7F007F
#define C_DARK_RED &h7F0000
#define C_DARK_GREEN &h007F00
#define C_DARK_BLUE &h00007F

'kit predefined colors
#define C_KIT_HAIR RGB(23,23,23)
#define C_KIT_SHIRT RGB(0,0,127)
#define C_KIT_PANTS RGB(127,127,255)
#define C_KIT_SHOES RGB(63,63,63)
#define C_KIT_LINE RGB(43,154,209)
#define C_KIT_SKIN RGB(255,125,20)
#define C_KIT_SOCKS RGB(63,0,63)

'ENUMS
enum proto_pl_action
    none = 0
    running = 1
    jumping = 2
    sliding = 3
    falling = 4
    falled = 5
    gk_jumping = 6
    gk_falled = 7
    gk_falled_w_ball = 8
    gk_w_ball = 9
    throw_in = 10
    corner_kicker = 11
    penalty_kicker = 12
end enum

enum proto_match_event
    none = 0
    ball_in_game
    penalty_t0
    penalty_t1
    throw_in_lside_t0
    throw_in_lside_t1
    throw_in_rside_t0
    throw_in_rside_t1
    throw_in_tl_side_t0
    throw_in_tl_side_t1
    throw_in_tr_side_t0
    throw_in_tr_side_t1
    throw_in_bl_side_t0
    throw_in_bl_side_t1
    throw_in_br_side_t0
    throw_in_br_side_t1
    corner_tl_side_t0
    corner_tl_side_t1
    corner_tr_side_t0
    corner_tr_side_t1
    corner_bl_side_t0
    corner_bl_side_t1
    corner_br_side_t0
    corner_br_side_t1
    gk_t0_owner
    gk_t1_owner
    ball_on_centre_t0 
    ball_on_centre_t1
    foul_t0
    foul_t1
    presentation
    happy_t0
    happy_t1
end enum


'TYPES
TYPE camera_proto
    dim x as single
    dim y as single
    dim w as single
    dim h as single
    dim speed as single
    dim rds as single
END TYPE

TYPE player_proto
    dim id as Integer       'unique id of the player 0-PL_N_TOT*2
    dim team as Integer     ' 0  for home team - 1 for away team
    dim number as Integer   'number of the player
    dim label as string * 32 'name of the player    *out of order
    dim old_x as single 'old x position
    dim old_y as single 'old y position
    dim x as single         'x position
    dim y as single         'y position
    dim z as single         'z position
    dim rds as single       'rotation of the player (in radiants (0-6.28))
    dim tact_offset_x as Integer 'offset x to the tactic
    dim tact_offset_y as Integer 'offset y to the tactic
    dim speed_default as single     'speed defualt of the player
    dim speed as single     'speed of the player
    dim speed_max as single 'maximum speed that the player can reach
    dim accel as single     'acceleration delta    *out of order
    dim frame as Integer    'useful to get the correct sprite frame
    dim frame_offset as Integer 'useful to get the correct sprite frame
    dim dist as single  'distance covered by the pl
    dim w as Integer        'width
    dim ball_radius as Integer 'maximum distance to get the ball    *out of order
    dim active as Integer ' check if the player is ready to make an action
    'ACTION: 0 none; 1 Running; 2 Jumping; 3 Sliding; 4 Falling; 5 Falled;
    '6 Goalkeeping Jump
    dim action as proto_pl_action
    dim delay as Integer ' how many cycles delays the player to perform  an action
    dim skin as Integer
    'skin color: 0: white with black hair; 1: brown with black hair;
    '2:white with yellow air;
END TYPE

TYPE ball_proto
    dim x as single         'x position
    dim y as single         'y position
    dim z as single         'z position
    dim old_x as single
    dim old_y as single
    dim z_speed as single       'z accel ratio
    dim z_speed_init as single   'z accel ratio
    dim speed as single     'speed 
    dim w as Integer  'width
    dim rds as single 'rotation
    dim effect as single 'effect
    dim frame as Integer 'which frame
END TYPE

'SHARED VARIABLES----------------------------------------------------------------------------
DIM SHARED Debug as Integer = 0
'exit flag
DIM shared Exit_flag as Integer = 0

DIM SHARED goal_team_0 as integer = 0
DIM SHARED goal_team_1 as integer = 0

dim shared tct_tile(0 to 9, 0 to 35) as Integer 'tactic array
'it indicates in wich `a` tile the pl must go if the ball is in `b` tile
'for example: ball in tile 20, pl must go to tile 12
'see also functions `get_tact_tile`, `get_rds_from_tile`,
'`get_dist_from_tile` and `get_ball_tile`
'and sub `load_tact`

dim shared bhv_tile(0 to 35, 0 to 9) as Integer 'behavior array
'it gives a percentage table for the behavior of the players owners of the ball
'see relative sub for details

DIM SHARED Pl_sprite_0(PL_SPRITES_TOT_N) AS ANY PTR ' A pointer that points to a memory buffer (for plrs sprites)
DIM SHARED Pl_sprite_1(PL_SPRITES_TOT_N) AS ANY PTR ' A pointer that points to a memory buffer (for plrs sprites)
DIM SHARED Gk_sprite(PL_SPRITES_TOT_N) AS ANY PTR ' A pointer that points to a memory buffer (for plrs sprites)
DIM SHARED Ball_sprite(15) AS ANY PTR '  A pointer that points to a memory buffer (for ball sprites)
DIM SHARED Net_sprite(2) AS ANY PTR '  A pointer that points to a memory buffer (for net sprites)
DIM SHARED Pitch_sprite(2) AS ANY PTR '  A pointer that points to a memory buffer (for pitch sprites)
DIM SHARED Banner_sprite AS ANY PTR 'idem for banner
DIM SHARED Shadowed_sprite AS ANY PTR 'idem for shadowed sprite

DIM SHARED Workpage AS INTEGER ' buffer holding the player sprites
DIM SHARED Addframe as Integer = 0 'to be soon removed

DIM shared C_x_o as single = 0 'camera x offset
DIM shared C_y_o as single = 0 'camera y offset

dim shared Camera as camera_proto 'camera type
dim shared Pl(PL_N_TOT*2) as player_proto 'player type
dim shared Ball as ball_proto 'ball type

dim shared PL_target_id as Integer = -1 '-1: none; 0-etc. indicates the id of the pl that's receiving pass
dim shared PL_ball_owner_id as Integer = -1 '-1: none; 0-etc. indicates the id of the pl owning the ball
dim shared PL_ball_owner_delay as Integer = PL_DELAY_TIME*2 'for how much time owning the ball after the touch
dim shared PL_team_owner_id as Integer = -1 'indicates the id of the team owning the ball

dim shared SHELL_message as string * 64 'this is useful for debug, to store and display shell-like messages

'action input key - in this case the "CONTROL" key on the keyboard
Dim shared Key_pressed as integer = 0
dim shared Key_released as integer = 0
dim shared Key_pressed_time_start as double = 0
dim shared Key_pressed_time_stop as double = 0
dim shared Key_pressed_gap as double = 0

'checks if the match is PC vs PC or Human vs PC
dim shared Human_control as integer = 0
'training mode, play with your team against only the opponent GK
dim shared Training_mode as integer = 0

dim shared Match_time_start as double = 0

'MATCH EVENTS ---------------------------------------------------------------------------
dim shared Match_event as proto_match_event 'indicates the actual match event
Match_event = ball_in_game 'default... I'll change this value soon
dim shared Match_event_delay as Integer = 0 'delay between every state change
dim shared Match_event_last_tile as Integer = 0 'stores the tile where the ball
'was before going off the pitch
dim shared Match_event_old_ball_x as Single 'store the old x pos of the ball
dim shared Match_event_old_ball_y as Single 'store the old y pos of the ball              
#define MATCH_EVENT_DEFAULT_DELAY 45
'----------------------------------------------------------------------------------------
dim shared main_menu_selected_item as UShort = 0

'USEFUL VARIABLES------------------------------------------------------------------------
dim count as integer = 0

'init camera dimensions
camera.w = SCREEN_W
camera.h = SCREEN_H
camera.x = PITCH_MIDDLE_W
camera.y = PITCH_MIDDLE_H

' FUNCTIONS DECLARATIONS---------------------------------------------------------------------
'converts radiants to degree
declare function r_t_d (degree as integer) as integer
' converts degree to radiants
declare function d_t_r (degree as integer) as single
' calculates the angle between two points
declare function a_b_t_p (x1 as single, y1 as single, x2 as single, y2 as single) as single
' calculates the distance between two points
declare function d_b_t_p (x1 as single, y1 as single, x2 as single, y2 as single) as single
' calculates the starting frame for the player sprite from the angle in radiants
declare function start_frame (radiants as single) as integer
' calculates in wich pitch tile the player must go (use it if the player hasn't the ball possession)
declare function get_tact_tile (pl_id as Integer) as Integer
' returns in wich tile is the ball
declare function get_ball_tile(team as Integer) as Integer
' calculate the radiants to get the right tile
declare function get_rds_from_tile(tile as Integer, pl_x as single, pl_y as single) as single
' calculate the distance between player and the tile where he must go
declare function get_dist_from_tile(tile as Integer, pl_x as single, pl_y as single) as single
' return the nearest player to the ball
declare function get_nrst_pl_ball(n_team as Integer) as Integer
' giving the id of the team returns the nearest player to pass the ball
declare function get_nrst_pl_pass(pl_id as Integer) as Integer
' giving the id of the team returns the 2nd nearest player to pass the ball
declare function get_nrst2_pl_pass(pl_id as Integer, order as Integer) as Integer
' giving the unique id of the player calculate wich is his team
' and return the farrest player to pass the ball
declare function get_farrest_pl_to_pass(pl_id as Integer) as Integer    '*out of order
' giving the unique id of the player calculate wich is his team and
'return the player nearest to the corner line
declare function get_endline_pl_to_pass(pl_id as integer) as Integer
' giving the unique id of the player calculate wich is his team and
'return the player nearest to middlefield
declare function get_centerest_pl_to_pass(pl_id as Integer) as Integer
' giving the unique id of the player owner of the ball
' calculate wich is his team and returns the right player to pass by longside 
declare function get_longside_pl_to_pass (pl_id as Integer) as Integer
' giving the unique id of the player owner of the ball
' calculate wich is his team and returns the right player to pass by shortside
declare function get_shortside_pl_to_pass (pl_id as Integer) as Integer
'giving the distance between pl an pl to pass returns the correct speed of the ball
declare function get_passing_ball_speed (dist as Single) as Single
'this function returns 1 if the object is into the camera crop - useful to use less CPU timing for
'drawing functions
declare function is_in_camera_crop (x as single, y as single, diam as integer) as Integer
'cheks if the pl can perform a slide
declare function is_ball_slidable (c as integer) as Integer
'cheks if the pl can perform an headkick
declare function is_ball_headkickable (c as integer) as Integer
'checks if the ball is controllable by human player
declare function is_ball_controllable_by_human (c as integer) as Integer
'checks if the ball is into penalty area
declare function is_ball_into_penalty_area (c as integer) as Integer
'return if the pl_to_pass is in the field of view of the player - based upon the player rds
declare function is_in_pl_fieldview (c as Integer, pl_to_pass as integer) as Integer
'return 1 if the pl is into his opponent penalty area
declare function is_pl_into_opponent_penalty_area (c as integer) as Integer
'return the nearest pl to the line of pass - only for Human controlled player
declare function get_pl_to_pass(c as integer) as Integer
'return the current match_event - useful for debug
declare function print_match_event(event as Integer) as String

'SUBS DECLARATIONS-----------------------------------------------------------------------
'load fonts
DECLARE SUB load_fonts()
'load tactics
DECLARE SUB load_tact()
'load behavior of the player owner of the ball
DECLARE SUB load_behavior()
'get user input to control the direction of the player 
DECLARE SUB get_user_input_ways(c as integer)
'load sprites
DECLARE SUB load_bitmap()
'paints the kits of the teams with a custom color - and also the color of the skin of
'the players
DECLARE SUB paint_kits(C_shirt_0 as Integer, C_pants_0 as Integer, C_socks_0 as Integer, _
C_shirt_1 as Integer, C_pants_1 as Integer, C_socks_1 as Integer)
'delete the sprites
DECLARE SUB delete_bitmap()
'cheks if the sprites have been rightly loaded
DECLARE SUB check_bitmap()
'checks if the ball goes off the game pitch
DECLARE SUB check_throw_in_corner_kick()
'draws the nets
DECLARE SUB draw_top_net()
DECLARE SUB draw_bottom_net()
'draws the pitch
DECLARE SUB draw_pitch()
'update the ball
DECLARE SUB update_ball()
'draw the grid
DECLARE SUB draw_grid()
'draws the players
DECLARE SUB draw_players()
'resets the position of the players (0's ids on the left side, 1's ids on the right side)
DECLARE SUB reset_players_positions()
'puts the ball into the centre of the pitch
DECLARE SUB put_ball_on_centre()
' update the beahovior of the players
DECLARE SUB update_players()
' checks if the ball gest the limits of the pitch
' or if the ball goes into any net
DECLARE SUB check_ball_border_pitch_limit()
'updates the position of the camera following the ball with easing effect
DECLARE SUB update_camera_position()
'initialize the players proprietes
DECLARE SUB init_players_proprietes()
'sets to 0 axis z of the ball and z_Speed of the ball
DECLARE SUB reset_ball_z()
'draws the ball
DECLARE SUB draw_ball()
'giving the id of the player who owns the ball, calculate in wich tile is,
'it manages the player behavior (for example: running to the net, passing, shooting, etc...)
DECLARE SUB get_pl_behavior(pl_id as Integer)
'checks if two or more players collide
DECLARE SUB check_pl_collisions()
'a player without ball and far away from the ball must run the tactic
DECLARE SUB run_tactic(c as Integer)
'draws the bottom infos
DECLARE SUB draw_bottom_info()
'aknowledgements
DECLARE SUB draw_aknowledgements()
'intro
DECLARE SUB draw_intro()
'generic user input
DECLARE SUB get_user_input()
'debug
DECLARE SUB draw_debug()
'Main menu
DECLARE SUB draw_main_menu()
DECLARE SUB update_main_menu()
'update the current match event
DECLARE SUB update_match_event()
'all the player MUST run the tactic except the pl_id send as argument
'if you want that ALL the pl MUST run the tactic send -1 as argument
DECLARE SUB run_tactic_all_players(c as integer)
'move a single player
DECLARE SUB move_player(c as integer)
'move all players
DECLARE SUB move_players()
' giving ids 1 and 0 reset the correct gk ready position
DECLARE SUB reset_gk_net_position (c as integer)
'this sub doesn't allow the ball to go far far away when its goes outside the game field
DECLARE SUB check_ball_limits()
'restore the original value of the players
DECLARE SUB restore_players_speed()
'store the old ball position
DECLARE SUB store_ball_position()

SUB check_ball_limits()
    'border pitch limit check
    if (ball.x > PITCH_X+PITCH_W+CAMERA_PADDING) THEN
        ball.x = PITCH_X+PITCH_W+CAMERA_PADDING-5
        ball.rds = PI - ball.rds
        ball.speed *= 0.3:ball.z_speed *= 0.5
    END IF
    if (ball.x < PITCH_X - CAMERA_PADDING) THEN
        ball.x = PITCH_X - CAMERA_PADDING + 5
        ball.rds = PI - ball.rds
        ball.speed *= 0.3:ball.z_speed *= 0.5
    END IF
    if (ball.y > PITCH_Y + PITCH_H + CAMERA_PADDING) THEN
        ball.y = PITCH_Y + PITCH_H + CAMERA_PADDING - 5
        ball.rds = PI*2 - ball.rds
        ball.speed *= 0.3:ball.z_speed *= 0.5
    END IF
    if (ball.y <  PITCH_Y - CAMERA_PADDING ) THEN
        ball.y = PITCH_Y - CAMERA_PADDING + 5
        ball.rds = PI*2 - ball.rds
        ball.speed *= 0.3
        ball.z_speed *= 0.5
    END IF
    
END SUB

SUB check_ball_goals()
    'goal check team 0
    if  (ball.x > PITCH_MIDDLE_W - PITCH_NET_W\2) and _
    (ball.x < PITCH_MIDDLE_W + PITCH_NET_W\2) and _
    (ball.y < PITCH_Y + 5) and ball.z < PITCH_NET_H then
    put_ball_on_centre()
    reset_players_positions()
    goal_team_0 +=1
    camera.speed = 0
    PL_ball_owner_id = -1
    exit sub
end if
if  (ball.x > PITCH_MIDDLE_W - PITCH_NET_W\2) and _
(ball.x < PITCH_MIDDLE_W + PITCH_NET_W\2) and _
(ball.y > PITCH_Y + PITCH_H - 5) and ball.z < PITCH_NET_H then
put_ball_on_centre()
reset_players_positions()
goal_team_1 +=1
camera.speed = 0
PL_ball_owner_id = -1
exit sub
end if
END SUB

SUB check_bitmap()
    dim as Integer img_x = 0
    dim as Integer img_y = 0
    dim as Integer count = 0 
    
    screenlock ' Lock the screen
    screenset workpage, workpage xor 1 ' Swap work pages.
    for count = 0 to PL_SPRITES_TOT_N - 1
        if (count > 0) and (count MOD 17 = 0) then
            img_x = 0
            img_y += 32
        end if
        PUT (img_x,img_y), pl_sprite_0(count),trans
        draw string (img_x,img_y), str(count)
        img_x += 22
    next count
    workpage xor = 1 ' Swap work pages.
    flip
    screenunlock ' Unlock the page to display what has been drawn on the screen
    sleep 
    img_x = 0
    img_y = 0
    cls
    
    for count = 0 to PL_SPRITES_TOT_N - 1
        if (count > 0) and (count MOD 21 = 0) then
            img_x = 0
            img_y += 20
        end if
        PUT (img_x,img_y), pl_sprite_1(count),trans
        draw string (img_x,img_y), str(count)
        img_x += 28
    next count
    workpage xor = 1 ' Swap work pages.
    flip
    screenunlock ' Unlock the page to display what has been drawn on the screen
    sleep 1000
    
    for count = 0 to PL_SPRITES_TOT_N - 1
        if (count > 0) and (count MOD 21 = 0) then
            img_x = 0
            img_y += 20
        end if
        PUT (img_x,img_y), gk_sprite(count),trans
        draw string (img_x,img_y), str(count)
        img_x += 28
    next count
    workpage xor = 1 ' Swap work pages.
    flip
    screenunlock ' Unlock the page to display what has been drawn on the screen
    sleep 1000
    '    img_x = 20
    '    img_y = 20
    '    for count = 0 to PL_SPRITES_TOT_N - 1
    '        cls
    '        PUT (img_x,img_y), pl_sprite_0(count),trans
    '        PUT (img_x + 50,img_y), pl_sprite_1(count),trans
    '        draw string (img_x,img_y+20), str(count)
    '        draw string (img_x,img_y+40), hex(count)
    '        flip
    '        sleep 35
    '    next count
    
END SUB


SUB check_pl_collisions()
    Dim c as Integer 
    Dim d as Integer
    'check each pl
    for c = 0 to (PL_N_TOT*2-1)
        'check collision only if the interested pllayers are int the crop view
        if is_in_camera_crop (pl(c).x, pl(c).y, 64) then
            for d  = 0 to (PL_N_TOT*2-1)
                if d = c or pl(c).active = 0 then continue for 'doesn't check himself obviously :)
                if d_b_t_p (pl(c).x, pl(c).y,pl(d).x, pl(d).y) < PL_MIN_DIST then
                    'some fighting betweeen two players
                    pl(d).x = pl(d).old_x + PL_MIN_DIST/2 - (rnd*PL_MIN_DIST)
                    pl(d).y = pl(d).old_y + PL_MIN_DIST/2 - (rnd*PL_MIN_DIST)
                    
                    'also with running fighting one of the pl may fall
                    if int(rnd*100) < RND_CONTACT_FALL then
                        pl(c).active = 0
                        pl(c).action = falling
                        pl(c).delay = PL_DELAY_FALLING
                        continue for, for
                    end if
                    continue for, for
                end if
            next d
        end if
    next c
END SUB

SUB check_throw_in_corner_kick()
    if Ball.x > PITCH_X + PITCH_W then
        select case PL_team_owner_id
        case 0
            match_event = throw_in_rside_t1
        case 1
            match_event = throw_in_rside_t0
        end select
        Match_event_delay = MATCH_EVENT_DEFAULT_DELAY
        PL_team_owner_id = -1
        PL_ball_owner_id = -1
    end if
    'throw in lside check
    if Ball.x < PITCH_X then
        select case PL_team_owner_id
        case 0
            match_event = throw_in_lside_t1
        case 1
            match_event = throw_in_lside_t0
        end select
        Match_event_delay = MATCH_EVENT_DEFAULT_DELAY
        PL_team_owner_id = -1
        PL_ball_owner_id = -1
    end if
    'throw in tside check
    if Ball.y < PITCH_Y then
        select case PL_team_owner_id
        case 0
            if Ball.x < PITCH_MIDDLE_W then
                Match_event = throw_in_tl_side_t1
            else
                Match_event = throw_in_tr_side_t1
            end if
        case 1
            if Ball.x < PITCH_MIDDLE_W then
                Match_event = corner_tl_side_t0
            else
                Match_event = corner_tr_side_t0
            end if
        end select
        Match_event_delay = MATCH_EVENT_DEFAULT_DELAY
        PL_team_owner_id = -1
        PL_ball_owner_id = -1
    end if
    'throw in bside check
    if Ball.y > PITCH_Y + PITCH_H then
        select case PL_team_owner_id
        case 0
            if Ball.x < PITCH_MIDDLE_W then
                Match_event = corner_bl_side_t1
            else
                Match_event = corner_br_side_t1
            end if
        case 1
            if Ball.x < PITCH_MIDDLE_W then
                Match_event = throw_in_bl_side_t0
            else
                Match_event = throw_in_br_side_t0
            end if
        end select
        Match_event_delay = MATCH_EVENT_DEFAULT_DELAY
        PL_team_owner_id = -1
        PL_ball_owner_id = -1
    end if
END SUB


SUB delete_bitmap()
    dim count as Integer
    For count = 0 To PL_SPRITES_TOT_N - 1
        If pl_sprite_0(count) Then ImageDestroy pl_sprite_0(count)
        If pl_sprite_1(count) Then ImageDestroy pl_sprite_1(count)
    Next
    For count = 0 To 14
        If ball_sprite(count) Then ImageDestroy ball_sprite(count)
    Next
    If net_sprite(0)   Then ImageDestroy net_sprite(0)
    If net_sprite(1)   Then ImageDestroy net_sprite(1)
    If pitch_sprite(0) Then ImageDestroy pitch_sprite(0)
    If pitch_sprite(1) Then ImageDestroy pitch_sprite(1)
    If banner_sprite   Then ImageDestroy banner_sprite
    If shadowed_sprite Then ImageDestroy shadowed_sprite
END SUB

SUB draw_aknowledgements()
    ScreenSet 0, 0
    Color RGB(255, 128, 0), RGB(0, 0, 64)
    Cls
    Do
    Loop While Len(InKey)
    Color RGB(255, 255, 255), RGB(0, 0, 64)
    Print
    Print "            A K N O W L E D G E M E N T S"
    Color RGB(255, 128, 0), RGB(0, 0, 64)
    Print
    Print " - Lachie Dazdarian - for his tutorials about creating a game in FB"
    Print
    Print " - I3I2UI/I0 for his very useful code tips and cleanup"
    Print
    Print " - The Fbgfx developers"
    Print
    Print " - The FreeBasic Developers"
    Print
    Print " - The FBIde Developers"
    Print
    Print " - All the followers of the"
    Print "   http://www.freebasic.net/forum/viewtopic.php?f=15&t=20637"
    Print "   thread"
    Print
    Print " OKAY, THANK YOU... press a key to QUIT"
    Print " Bye!"
    GetKey
    
END SUB

SUB draw_ball()
    dim offset_frame as Integer
    dim x as Integer
    
    if (ball.z > 25) then
        if ball.z < 60 then
            offset_frame = 5
        else
            offset_frame = 10
        end if
    else
        offset_frame = 0
    end if
    
    if d_b_t_p(ball.x, ball.y, ball.old_x, ball.old_y) > 1 then
        ball.frame += 1
    end if
    
    if ball.frame MOD 5 = 0  then ball.frame = 0
    
    circle (ball.x-c_x_o, ball.y-c_y_o+2),ball.w, RGB (0,50,0),,,,F
    PUT (ball.x-c_x_o-8, ball.y- 8 - ball.z- c_y_o), ball_sprite(ball.frame + offset_frame), trans
    
END SUB

SUB draw_bottom_info()
    dim d as Integer
    
    for d = 0 to int (SCREEN_W / 32) +1 
        PUT (32*d, SCREEN_H-32), shadowed_sprite, trans
    next
    
    Draw String (20,SCREEN_H - 20), str(goal_team_0) + "-" + str(goal_team_1)
    Draw string (64,SCREEN_H - 20), SHELL_message, RGB(200,200,200)
    
    if Match_event_delay then
        for d = 8 to int (SCREEN_W / 32) +1 
            PUT (32*d, SCREEN_H\2 - 6), shadowed_sprite, trans
        next
        Draw String (SCREEN_W \ 2, SCREEN_H \ 2), str(goal_team_0) + "-" _
        + str(goal_team_1), C_WHITE
        draw string (SCREEN_W \ 2, SCREEN_H \ 2 + 16), "Match_Event: " + print_match_event(Match_event), C_WHITE
    end if
    
    
END SUB

SUB draw_bottom_net()
    
    PUT (PITCH_MIDDLE_W - 53 - c_x_o, PITCH_Y + PITCH_H - 28 - c_y_o ), net_sprite(1), trans
    
end sub

SUB draw_debug()
    dim c as integer
    if (DEBUG) then
        draw_grid()
        
        print "ball tile 0: "; get_ball_tile(0)
        print "ball tile 1: "; get_ball_tile(1)
        print "ball.x  ball.y  speed rds z"
        'this line doesn't works with the new compiler
        'print using "####.##"; ball.x, ball.y, ball.speed, ball.rds, ball.z
        print "key pressed: "; key_pressed
        print "match_event: "; Match_event; " "; print_match_event(Match_event)
        print "match_event_delay: "; Match_event_delay
        print "match_event_old_ball_x: "; match_event_old_ball_x
        print "match_event_old_ball_y: "; match_event_old_ball_y
        print "PL_ball_owner_id: "; PL_ball_owner_id
        print "PL_team_owner_id: "; PL_team_owner_id
        if get_pl_to_pass(Pl_ball_owner_id) then
            line (pl(get_nrst_pl_ball(0)).x-c_x_o, pl(get_nrst_pl_ball(0)).y-c_y_o)-_
            (pl(get_pl_to_pass(Pl_ball_owner_id)).x-c_x_o,pl(get_pl_to_pass(Pl_ball_owner_id)).y-c_y_o), RGB(255,255,0)
        end if
        
        line (Match_event_old_ball_x - C_x_o, PITCH_Y - C_y_o) - _
        (Match_event_old_ball_x - C_x_o, PITCH_H + PITCH_Y - C_y_o), C_WHITE, , &b1010101010101010
        
        line (PITCH_X - C_x_o, Match_event_old_ball_y - C_y_o) - _
        (PITCH_X + PITCH_W - C_x_o, Match_event_old_ball_y - C_y_o), C_WHITE, , &b1010101010101010

        for c = 0 to PL_N_TOT * 2 - 1
            if pl(c).team = PL_team_owner_id then
                circle (pl(c).x - C_x_o, pl(c).y - c_y_o),12, C_ORANGE,,,,F
            end if
            if pl(c).id = PL_ball_owner_id then
                circle (pl(c).x - C_x_o, pl(c).y - c_y_o),10, C_DARK_RED,,,,F
            end if
            if pl(c).id = PL_target_id then
                circle (pl(c).x - C_x_o, pl(c).y - c_y_o),8, C_GREEN,,,,F
            end if
            if pl(c).delay > 0 and pl(c).delay MOD 3 = 0 then
                circle (pl(c).x - C_x_o, pl(c).y - c_y_o),6, C_WHITE,,,,F
            end if
        next c
        
        circle (Match_event_old_ball_x - C_x_o +3, Match_event_old_ball_y - c_y_o +3),6, RGB (255,255,0),,,,F
        
        
        
        print left(str(Key_pressed_gap),5) + " Key_pressed_gap"
        print left(str(Pl(Pl_ball_owner_id).rds),6) + " Pl ball owner rds"
        if Pl_ball_owner_id <> -1 then
            draw string (pl(Pl_ball_owner_id).x - C_x_o, pl(Pl_ball_owner_id).y - C_y_o + 20), "ID: " + str(pl(Pl_ball_owner_id).id), C_WHITE
            draw string (pl(Pl_ball_owner_id).x - C_x_o, pl(Pl_ball_owner_id).y - C_y_o + 30), "NUMBER: " + str(pl(Pl_ball_owner_id).number), C_WHITE
            draw string (pl(Pl_ball_owner_id).x - C_x_o, pl(Pl_ball_owner_id).y - C_y_o + 40), "ACTION: " + str(pl(Pl_ball_owner_id).action), C_WHITE
            draw string (pl(Pl_ball_owner_id).x - C_x_o, pl(Pl_ball_owner_id).y - C_y_o + 50), "DELAY: " + str(pl(Pl_ball_owner_id).delay), C_WHITE
            draw string (pl(Pl_ball_owner_id).x - C_x_o, pl(Pl_ball_owner_id).y - C_y_o + 60), "ACTIVE: " + str(pl(Pl_ball_owner_id).active), C_WHITE
        end if
        
        Draw string (SCREEN_W - 200,SCREEN_H - 50), "PL_Team_owner_id " + str(PL_team_owner_id), RGB(200,200,200)
        
        'input key debug -------------------------------------
        if MULTIKEY(SC_UP) then
            line (40, 400)-(60,380), C_WHITE, BF
        end if
        if MULTIKEY(SC_DOWN) then
            line (40, 400)-(60,420), C_WHITE, BF
        end if
        if MULTIKEY(SC_LEFT) then
            line (20, 400)-(40,420), C_WHITE, BF
        end if
        if MULTIKEY(SC_RIGHT) then
            line (60, 400)-(80,420), C_WHITE, BF
        end if
        if MULTIKEY(SC_CONTROL) then
            line (100, 400)-(140,420), C_WHITE, BF
        end if
        
        line (40, 400)-(60,380), C_BLACK, B
        line (20, 400)-(40,420), C_BLACK, B
        line (40, 400)-(60,420), C_BLACK, B
        line (60, 400)-(80,420), C_BLACK, B
        line (100, 400)-(140,420), C_BLACK, B
        '-----------------------------------------------------
        
    end if
end SUB

SUB draw_grid()
    dim as integer x, y, x2,y2, col, row, count
    count = 0
    for row = 0 to ROW_TOT_N -1 step 1
        for col = 0 to COL_TOT_N -1 step 1
            'draw the grid
            x = col * PITCH_W \ COL_TOT_N + PITCH_X 
            y = row * PITCH_H \ ROW_TOT_N + PITCH_Y
            x2 = x + PITCH_W \ COL_TOT_N
            y2 = y + PITCH_H \ ROW_TOT_N
            line (x-c_x_o,y-c_y_o)-(x2-c_x_o,y2-c_y_o),C_GRAY,b 
            draw string (x+5-c_x_o,y+5-c_y_o), str(count), C_WHITE
            draw string (x+ 30-c_x_o,y+5-c_y_o), "- " + str(TILES_N_TOT - count), C_WHITE
            'check if the ball is into a box of the grid and fill it using paint function
            if (ball.x > x) and (ball.x < x2) and (ball.y>y) and (ball.y < y2) then
                paint (ball.x-c_x_o, ball.y-c_y_o),C_DARK_GREEN,C_GRAY
                draw string (x+5-c_x_o,y+5-c_y_o), str(count), C_WHITE
                draw string (x+ 30-c_x_o,y+5-c_y_o), "- " + str(TILES_N_TOT - count), C_WHITE
            end if
            count +=1
        next col
    next row
    if is_ball_into_penalty_area (0) then
        circle (ball.x - c_x_o, ball.y - c_y_o), 16, C_RED,,,,F
    end if
    if is_ball_into_penalty_area (1) then
        circle (ball.x - c_x_o, ball.y - c_y_o), 16, C_BLUE,,,,F
    end if
END SUB

SUB draw_intro()
    
END SUB

SUB draw_main_menu()
    dim a as integer = 0
    static frame as single = 0
    dim menu_labels(4) as string = {"Play Vs PC", "Watch a match","Training","Training in debug mode", "Exit"}
    dim string_color as Uinteger
    
    'this is only a joke
    frame += 0.3
    if frame > PL_SPRITES_TOT_N then frame = 0
    
    cls
    color C_GRAY, C_DARK_BLUE
    Print "J A S C   S O C C E R"
    Print "version " + str(GAME_VERSION)
    print 
    print "use arrow keys to move"
    print "CTRL to slide, jump, kick and so on..."
    
    for a = 0 to 4
        if a = main_menu_selected_item then
            line (20,a*25 + 75)-(20 + 250,a*25 + 90), C_ORANGE, BF
            line (20,a*25 + 75)-(20 + 250,a*25 + 90), C_RED, B
            PUT (20,a*25 + 70),pl_sprite_0(int(frame)), trans
            string_color = C_DARK_BLUE
        else
            line (20,a*25 + 75)-(20 + 250,a*25 + 90), C_GRAY, BF
            line (20,a*25 + 75)-(20 + 250,a*25 + 90), C_WHITE, B
            string_color = C_WHITE
        end if
        draw string (50,a*25 + 80), menu_labels(a), string_color
    next a
    
    flip
    screenunlock ' Unlock the page to display what has been drawn on the screen
END SUB

SUB draw_pitch()
    dim as Integer pitch_rows, pitch_cols
    dim as Integer a, b
    dim banner_message as string*32
    pitch_rows = PITCH_H \ 32 + 4
    pitch_cols = PITCH_W \ 32 + 4 
    
    
    Paint (SCREEN_W\2,SCREEN_H\2), &h3B6F16
    
    
    'drawing the grass
    for a = 0 to pitch_rows -1
        for b = 0 to pitch_cols -1
            if is_in_camera_crop (PITCH_X + b*32, PITCH_Y + a*32, 128) then
                if a mod 2 = 0 then
                    PUT (PITCH_X - 64 + (b*32)- c_x_o, PITCH_Y - 64 +(a*32) - c_y_o),pitch_sprite(0),trans
                else
                    PUT (PITCH_X - 64 + (b*32)- c_x_o, PITCH_Y - 64 +(a*32) - c_y_o),pitch_sprite(1),trans
                end if
            end if
        next b
    next a
    
    'banner
    PUT (PITCH_X + 10 - c_x_o, PITCH_Y - 27 - c_y_o), banner_sprite, trans
    banner_message = GAME_NAME + " " + str(GAME_VERSION) + " ::: "
    draw string (PITCH_X + 15 - c_x_o,  PITCH_Y - 20 - c_y_o), banner_message, RGB(50,50,50)
    
    PUT (PITCH_X + PITCH_W - 266 - c_x_o, PITCH_Y - 27 - c_y_o), banner_sprite, trans
    banner_message = Str(Goal_team_0) + " - " + str(Goal_team_1)
    draw string (PITCH_X + PITCH_W - 256 - c_x_o,  PITCH_Y - 20 - c_y_o), banner_message, RGB(50,50,50)
    
    'drawing the pitch's border lines
    Line (PITCH_X - c_x_o, PITCH_Y - c_y_o)-(PITCH_W+PITCH_X- c_x_o, PITCH_H+PITCH_Y- c_y_o),RGB (255,255,255),b
    
    'middle line and circle
    Line (PITCH_X - c_x_o, PITCH_MIDDLE_H - c_y_o)-(PITCH_X + PITCH_W - c_x_o, PITCH_MIDDLE_H - c_y_o),RGB (255,255,255)
    Circle (PITCH_MIDDLE_W - c_x_o, PITCH_Y + PITCH_H\2- c_y_o), 84,RGB (255,255,255),,,0.8
    Circle (PITCH_MIDDLE_W - c_x_o, PITCH_Y + PITCH_H\2- c_y_o), 2,RGB (255,255,255),,,,F
    
    'Top penalty area
    Line    (PITCH_MIDDLE_W - PITCH_PENALTY_AREA - c_x_o,_
    PITCH_Y - c_y_o)-_
    (PITCH_MIDDLE_W + PITCH_PENALTY_AREA - c_x_o,_
    PITCH_Y + PITCH_PENALTY_AREA/1.5 - c_y_o), RGB (255,255,255),B
    'Top Gk area
    Line    (PITCH_MIDDLE_W - PITCH_PENALTY_AREA/2 - c_x_o,_
    PITCH_Y - c_y_o)-_
    (PITCH_MIDDLE_W + PITCH_PENALTY_AREA/2 - c_x_o,_
    PITCH_Y + PITCH_PENALTY_AREA/4 - c_y_o), RGB (255,255,255),B
    'top penalty dish
    Circle (PITCH_MIDDLE_W - c_x_o, PITCH_Y + PITCH_PENALTY_AREA/1.5 - 48 - c_y_o), 2,RGB (255,255,255),,,,F
    'top penalty circle
    Circle (PITCH_MIDDLE_W - c_x_o, PITCH_Y + PITCH_PENALTY_AREA/1.5 - 48 - c_y_o),_
    84,RGB (255,255,255),3.75,5.65
    
    'bottom penalty area
    Line    (PITCH_MIDDLE_W - PITCH_PENALTY_AREA - c_x_o,_
    PITCH_Y + PITCH_H - c_y_o)-_
    (PITCH_MIDDLE_W + PITCH_PENALTY_AREA - c_x_o,_
    PITCH_Y + PITCH_H - PITCH_PENALTY_AREA/1.5 - c_y_o), RGB (255,255,255),B
    'bottom Gk area
    Line    (PITCH_MIDDLE_W - PITCH_PENALTY_AREA/2 - c_x_o,_
    PITCH_Y + PITCH_H - c_y_o)-_
    (PITCH_MIDDLE_W + PITCH_PENALTY_AREA/2 - c_x_o,_
    PITCH_Y + PITCH_H - PITCH_PENALTY_AREA/4 - c_y_o), RGB (255,255,255),B
    'bottom penalty dish
    Circle (PITCH_MIDDLE_W - c_x_o, PITCH_Y + PITCH_H - PITCH_PENALTY_AREA/1.5 + 48 - c_y_o), 2,RGB (255,255,255),,,,F
    'bottom penalty circle        
    Circle (PITCH_MIDDLE_W - c_x_o, PITCH_Y + PITCH_H - PITCH_PENALTY_AREA/1.5 + 48 - c_y_o),_
    84,RGB (255,255,255),0.61,2.52
    
    Circle (PITCH_X - c_x_o, PITCH_Y - c_y_o), 9, RGB(255,255,255),pi*1.5,0
    Circle (PITCH_X - c_x_o, PITCH_Y + PITCH_H - c_y_o), 9, RGB(255,255,255),0,pi/2
    Circle (PITCH_X+PITCH_W - c_x_o, PITCH_Y - c_y_o), 9, RGB(255,255,255),pi,pi*1.5
    Circle (PITCH_X+PITCH_W - c_x_o, PITCH_Y + PITCH_H - c_y_o), 9, RGB(255,255,255),pi/2,pi
    
END SUB
SUB draw_players()
    dim as Integer b, c, lowest, start, change, ref, frame_offset
    dim a(PL_N_TOT * 2,2) as integer
    
    b = 0
    
    'z sorting by pl.y value - using selection sorting algorithm
    for c = 0 to PL_N_TOT * 2-1
        a(c,0) = c
        a(c,1) = pl(c).y
    next c
    
    for start = 0 to PL_N_TOT * 2 - 1 
        ref = a(start,1)
        change = 0 
        for b = start+1 to PL_N_TOT * 2 - 1 
            if a(b,1) < ref then
                ref = a(b, 1)
                lowest = b
                change = 1
            end if
        next b
        if change then
            swap a(lowest, 0), a(start, 0)
            swap a(lowest, 1), a(start, 1)
        end if
    next start
    
    'draws players, shadow, and circle under nearest pl to the ball
    for c = 0 to PL_N_TOT * 2 - 1
        'draws circles yellow or red under the nearest pl to the ball
        if (Human_control) then
            if get_nrst_pl_ball(pl(a(c,0)).team) = a(c,0) then 
                if pl(a(c,0)).team = 0 then
                    'another one ring if the pl is the ball owner
                    if a(c,0) = PL_ball_owner_id then
                        circle (pl(a(c,0)).x - c_x_o, pl(a(c,0)).y+9 - c_y_o),11, RGB (255,255,255),,,,F
                    end if
                    circle (pl(a(c,0)).x - c_x_o, pl(a(c,0)).y+9 - c_y_o),9, RGB (200,0,100),,,,F
                    circle (pl(a(c,0)).x - c_x_o, pl(a(c,0)).y+9 - c_y_o),6, RGB (0,50,0),,,,F
                end if
                'draw the pl number
                
            end if
        end if
        
        if DEBUG then
            if is_pl_into_opponent_penalty_area (pl(a(c,0)).id) then
                circle (pl(a(c,0)).x - c_x_o, pl(a(c,0)).y - c_y_o),16, C_WHITE
            end if
            draw string (pl(a(c,0)).x -6- c_x_o, pl(a(c,0)).y -30  - c_y_o), str(pl(a(c,0)).number)        
        end if
        'DRAW the BALL Z-Sorted - -  doesn't works fine :(
        
        select case c
            case 1 to PL_N_TOT * 2 - 2
                if pl(a(c,0)).y < ball.y and pl(a(c+1,0)).y > ball.y then
                    draw_ball()
                end if
            case PL_N_TOT * 2 - 1
                if pl(a(c,0)).y > ball.y then
                    draw_ball()
                end if
            case 0
                if pl(a(c,0)).y < ball.y then
                    draw_ball()
                end if
        end select
        
        'puts the right set of sprites depending on the pl.action
        if is_in_camera_crop (pl(a(c,0)).x, pl(a(c,0)).y, 128) then
            select case pl(a(c,0)).action
            case 0 '*** at this moment undefined***
            case running, penalty_kicker
                
                pl(a(c,0)).frame_offset = 0
                pl(a(c,0)).dist += pl(a(c,0)).speed / 7
                if pl(a(c,0)).dist > 1 then
                    pl(a(c,0)).frame+=1
                    pl(a(c,0)).dist = 0
                end if
                if pl(a(c,0)).frame > 5 then pl(a(c,0)).frame=1
                if pl(a(c,0)).speed = 0 then pl((a(c,0))).frame = 0
                
                if pl(a(c,0)).team = 0 then
                    if pl(a(c,0)).id < 2 then
                        PUT (pl(a(c,0)).x - pl(a(c,0)).w - c_x_o, pl(a(c,0)).y - pl(a(c,0)).w - c_y_o),_
                        gk_sprite(start_frame(pl(a(c,0)).rds)+pl(a(c,0)).frame), trans
                    else
                        PUT (pl(a(c,0)).x - pl(a(c,0)).w - c_x_o, pl(a(c,0)).y - pl(a(c,0)).w - c_y_o),_
                        pl_sprite_0(start_frame(pl(a(c,0)).rds)+pl(a(c,0)).frame), trans
                    end if
                else
                    if pl(a(c,0)).id < 2 then
                        PUT (pl(a(c,0)).x - pl(a(c,0)).w - c_x_o, pl(a(c,0)).y - pl(a(c,0)).w - c_y_o),_
                        gk_sprite(start_frame(pl(a(c,0)).rds)+pl(a(c,0)).frame), trans
                    else
                        PUT (pl(a(c,0)).x - pl(a(c,0)).w - c_x_o, pl(a(c,0)).y - pl(a(c,0)).w - c_y_o),_
                        pl_sprite_1(start_frame(pl(a(c,0)).rds)+pl(a(c,0)).frame), trans
                    end if
                end if
            case jumping, sliding, falling, falled, throw_in, gk_falled_w_ball
                select case pl(a(c,0)).action
                    case jumping
                        frame_offset = 8
                    case sliding
                        frame_offset = 7
                    case falling, falled, gk_falled_w_ball
                        frame_offset = 6
                    case throw_in
                        frame_offset = 16
                end select
                
                if pl(a(c,0)).team = 0 then
                    if pl(a(c,0)).id < 2 then
                        PUT (pl(a(c,0)).x - pl(a(c,0)).w - c_x_o, pl(a(c,0)).y - pl(a(c,0)).w - c_y_o),_
                        gk_sprite(start_frame(pl(a(c,0)).rds)+frame_offset), trans
                    else
                        PUT (pl(a(c,0)).x - pl(a(c,0)).w - c_x_o, pl(a(c,0)).y - pl(a(c,0)).w - c_y_o),_
                        pl_sprite_0(start_frame(pl(a(c,0)).rds)+frame_offset), trans
                    end if
                else
                    if pl(a(c,0)).id < 2 then
                        PUT (pl(a(c,0)).x - pl(a(c,0)).w - c_x_o, pl(a(c,0)).y - pl(a(c,0)).w - c_y_o),_
                        gk_sprite(start_frame(pl(a(c,0)).rds)+frame_offset), trans
                    else
                        PUT (pl(a(c,0)).x - pl(a(c,0)).w - c_x_o, pl(a(c,0)).y - pl(a(c,0)).w - c_y_o),_
                        pl_sprite_1(start_frame(pl(a(c,0)).rds)+frame_offset), trans
                    end if
                end if
            
            case gk_jumping
                pl(a(c,0)).frame_offset +=1
                if pl(a(c,0)).frame_offset > 12 then pl(a(c,0)).frame_offset = 0
                if pl(a(c,0)).team = 0 then
                    if pl(a(c,0)).id < 2 then
                        PUT (pl(a(c,0)).x - pl(a(c,0)).w - c_x_o, pl(a(c,0)).y - pl(a(c,0)).w - c_y_o),_
                        gk_sprite(start_frame(pl(a(c,0)).rds)+int(pl(a(c,0)).frame_offset/2)+9), trans
                    else
                        PUT (pl(a(c,0)).x - pl(a(c,0)).w - c_x_o, pl(a(c,0)).y - pl(a(c,0)).w - c_y_o),_
                        pl_sprite_0(start_frame(pl(a(c,0)).rds)+int(pl(a(c,0)).frame_offset/2)+9), trans
                    end if
                else
                    if pl(a(c,0)).id < 2 then
                        PUT (pl(a(c,0)).x - pl(a(c,0)).w - c_x_o, pl(a(c,0)).y - pl(a(c,0)).w - c_y_o),_
                        gk_sprite(start_frame(pl(a(c,0)).rds)+int(pl(a(c,0)).frame_offset/2)+9), trans
                    else
                        PUT (pl(a(c,0)).x - pl(a(c,0)).w - c_x_o, pl(a(c,0)).y - pl(a(c,0)).w - c_y_o),_
                        pl_sprite_1(start_frame(pl(a(c,0)).rds)+int(pl(a(c,0)).frame_offset/2)+9), trans
                    end if
                end if

            case else
            end select
        end if
    next c
END SUB

SUB draw_top_net()
    PUT (PITCH_MIDDLE_W - 53 - c_x_o, PITCH_Y - 38 - c_y_o ), net_sprite(0), trans
end sub

'see comment below for details about the bhv_tile array

SUB get_pl_behavior(pl_id as Integer)
    dim tile as Integer '0-35
    dim decision as Integer '0-100
    dim pl_to_pass as Integer = 0
    
    decision = rnd*101
    tile = get_ball_tile(pl(pl_id).team)
    '--------------------------------------------------------------------
    'if there is enough room AND THE NET IS FAR - run to the opponent net
    if d_b_t_p(pl(pl_id).x,pl(pl_id).y, PITCH_MIDDLE_W, _
        PITCH_Y + PITCH_H * (pl(pl_id).team xor 0)) > PITCH_PENALTY_AREA and _
        d_b_t_p (pl(pl_id).x,pl(pl_id).y,_
        pl(get_nrst_pl_ball(pl(pl_id).team xor 1)).x,_
        pl(get_nrst_pl_ball(pl(pl_id).team xor 1)).y) > PL_RUN_SPACE then
            ball.rds = a_b_t_p (pl(pl_id).x, pl(pl_id).y,_
            PITCH_MIDDLE_W, PITCH_Y + (PITCH_H * (pl(pl_id).team xor 0))) + rnd * .5 -.25
            ball.speed = pl(pl_id).speed + rnd*1.5 + 0.5
            SHELL_message = "run to opponent"
    'else get standard behaviour table
    else
        select case decision
        case 0 to bhv_tile(tile, 0) '0: PASS TO NEAREST
            SHELL_message =  str(decision) + " TILE " + str(tile) + " PASS to nearest"
            'setting ball proprietes (z, angle, speed)            
            reset_ball_z()
            ball.rds = a_b_t_p (pl(pl_id).x, pl(pl_id).y,pl(get_nrst_pl_pass(pl_id)).x,pl(get_nrst_pl_pass(pl_id)).y)+rnd*.3-0.15
            ball.speed = get_passing_ball_speed (d_b_t_p(pl(pl_id).x, pl(pl_id).y,_
            pl(get_nrst_pl_pass(pl_id)).x,pl(get_nrst_pl_pass(pl_id)).y))
            
            PL_target_id = get_nrst_pl_pass(pl_id)
            PL_ball_owner_id = pl_id
            PL_team_owner_id = pl(pl_id).team
            
            exit sub
        case bhv_tile(tile, 0)+1 to bhv_tile(tile, 1)'1: pass_to_2nd_nearest
            SHELL_message =  str(decision) + " - TILE " + str(tile) + " PASS 2nd nearest"
            pl_to_pass = rnd*2 + 1
            
            'setting ball proprietes (z, angle, speed)
            reset_ball_z()
            ball.rds = a_b_t_p (pl(pl_id).x, pl(pl_id).y,_
            pl(get_nrst2_pl_pass(pl_id, pl_to_pass)).x,pl(get_nrst2_pl_pass(pl_id,pl_to_pass)).y)+rnd*.3-0.15
            ball.speed = get_passing_ball_speed (d_b_t_p(pl(pl_id).x, pl(pl_id).y,_
            pl(get_nrst2_pl_pass(pl_id, pl_to_pass)).x,pl(get_nrst2_pl_pass(pl_id,pl_to_pass)).y))
            
            PL_target_id = get_nrst2_pl_pass(pl_id,pl_to_pass)
            PL_ball_owner_id = pl_id
            PL_team_owner_id = pl(pl_id).team
            exit sub
        case bhv_tile(tile, 1)+1 to bhv_tile(tile, 2)'2: pass_short_side
            SHELL_message =  str(decision) + " - TILE " + str(tile) + " PASS Short Side"
            
            'setting ball proprietes (z, angle, speed)            
            reset_ball_z()
            ball.rds = a_b_t_p (pl(pl_id).x, pl(pl_id).y,pl(get_shortside_pl_to_pass(pl_id)).x,pl(get_shortside_pl_to_pass(pl_id)).y)+rnd*.3-0.15
            ball.speed = get_passing_ball_speed (d_b_t_p(pl(pl_id).x, pl(pl_id).y,_
            pl(get_shortside_pl_to_pass(pl_id)).x,pl(get_shortside_pl_to_pass(pl_id)).y))
            
            PL_target_id = get_shortside_pl_to_pass(pl_id)
            PL_ball_owner_id = pl_id
            PL_team_owner_id = pl(pl_id).team
            
            exit sub
        case bhv_tile(tile, 2)+1 to bhv_tile(tile, 3)'3: pass_long_side
            SHELL_message =  str(decision) + " - TILE " + str(tile) + " PASS Long Side"
            
            reset_ball_z()
            ball.rds = a_b_t_p (pl(pl_id).x, pl(pl_id).y,_
            pl(get_longside_pl_to_pass(pl_id)).x,pl(get_longside_pl_to_pass(pl_id)).y)
            ball.speed = get_passing_ball_speed (d_b_t_p(pl(pl_id).x, pl(pl_id).y,_
            pl(get_longside_pl_to_pass(pl_id)).x,pl(get_longside_pl_to_pass(pl_id)).y))
            
            PL_target_id = get_longside_pl_to_pass(pl_id)
            PL_ball_owner_id = pl_id
            PL_team_owner_id = pl(pl_id).team
            exit sub
        case bhv_tile(tile, 3)+1 to bhv_tile(tile, 4)'4: pass_endline
            SHELL_message =  str(decision) + " - TILE " + str(tile) + " PASS Endline"
            
            'setting ball proprietes (z, angle, speed)
            
            if decision mod 2 = 0 then 
                reset_ball_z()
                ball.speed = get_passing_ball_speed (d_b_t_p(pl(pl_id).x, pl(pl_id).y,_
                pl(get_endline_pl_to_pass(pl_id)).x,pl(get_endline_pl_to_pass(pl_id)).y))
            else
                ball.z_speed_init = rnd*5+10 : ball.z_speed=ball.z_speed_init
                ball.speed = get_passing_ball_speed (d_b_t_p(pl(pl_id).x, pl(pl_id).y,_
                pl(get_endline_pl_to_pass(pl_id)).x,pl(get_endline_pl_to_pass(pl_id)).y)) /5
            end if
            ball.rds = a_b_t_p (pl(pl_id).x, pl(pl_id).y,_
            pl(get_endline_pl_to_pass(pl_id)).x,pl(get_endline_pl_to_pass(pl_id)).y)
            
            PL_target_id = get_endline_pl_to_pass(pl_id)
            PL_ball_owner_id = pl_id
            PL_team_owner_id = pl(pl_id).team
            exit sub
        case bhv_tile(tile, 4)+1 to bhv_tile(tile, 5)'5: pass_center 
            SHELL_message =  str(decision) + " - TILE " + str(tile) + " PASS center"
            
            reset_ball_z()
            ball.rds = a_b_t_p (pl(pl_id).x, pl(pl_id).y,_
            pl(get_centerest_pl_to_pass(pl_id)).x,pl(get_centerest_pl_to_pass(pl_id)).y)
            ball.speed = get_passing_ball_speed (d_b_t_p(pl(pl_id).x, pl(pl_id).y,_
            pl(get_centerest_pl_to_pass(pl_id)).x,pl(get_centerest_pl_to_pass(pl_id)).y))
            
            PL_target_id = get_centerest_pl_to_pass(pl_id)
            PL_ball_owner_id = pl_id
            PL_team_owner_id = pl(pl_id).team
            exit sub
        case bhv_tile(tile, 5)+1 to bhv_tile(tile, 6)'6: run_to_centre
            SHELL_message =  str(decision) + " - TILE " + str(tile) + " R U N centre"
            ball.speed = pl(pl_id).speed + rnd*5 + 1
            ball.rds = a_b_t_p (pl(pl_id).x, pl(pl_id).y, pl(pl_id).x, PITCH_MIDDLE_H) + rnd * .5 -.25
            PL_target_id = -1 ' The pl is not passing to anyone
            PL_ball_owner_id = pl_id ' The pl become the ball owner
            exit sub
        case bhv_tile(tile, 6)+1 to bhv_tile(tile, 7)'7: run_to_net
            SHELL_message =  str(decision) + " - TILE " + str(tile) + " R U N to net"
            
            reset_ball_z()
            
            ' 1 xor 1 = 0 so 0*PITCH_W = 0 else 1*PITCH_W = PITCH_W
            ball.rds = a_b_t_p (pl(pl_id).x, pl(pl_id).y,_
            PITCH_MIDDLE_W , (PITCH_Y + PITCH_H * (pl(pl_id).team xor 1))) + rnd * .5 -.25
            ball.speed = pl(pl_id).speed + rnd*5 + 1
            PL_target_id = -1 ' The pl is not passing to anyone
            PL_ball_owner_id = pl_id ' The pl become the ball owner
            PL_team_owner_id = pl(pl_id).team
            exit sub
        case bhv_tile(tile, 7)+1 to bhv_tile(tile, 8)'8: run_to_endline
            SHELL_message =  str(decision) + " - TILE " + str(tile) + " R U N to endline"
            
            ball.rds = a_b_t_p (pl(pl_id).x, pl(pl_id).y,_
            PITCH_X + (PITCH_W * (pl(pl_id).team xor 1)), pl(pl_id).y+1) + rnd * .5 -.25
            ball.speed = pl(pl_id).speed + rnd*5 + 1
            PL_target_id = -1 ' The pl is not passing to anyone
            PL_ball_owner_id = pl_id ' The pl become the ball owner
            PL_team_owner_id = pl(pl_id).team
            'debug
            
            exit sub
        case bhv_tile(tile, 8)+1 to 100             '9: shoot_in_target
            SHELL_message =  str(decision) + " - TILE " + str(tile) + " SHOOT in TARGET"
            
            ball.rds = a_b_t_p (pl(pl_id).x, pl(pl_id).y,_
            PITCH_MIDDLE_W , PITCH_Y + PITCH_H * (pl(pl_id).team xor 0)) + rnd * .5 -.25
            
            if decision mod 2 = 0 then 
                ball.speed = 5*rnd+10
                ball.z_speed_init = rnd*5+9 : ball.z_speed=ball.z_speed_init
            else
                reset_ball_z()
                ball.speed = 2*rnd+18
                ball.z_speed_init = 10 : ball.z_speed=ball.z_speed_init
            end if
            
            
            PL_target_id = -1 ' The pl is not passing to anyone
            PL_ball_owner_id = pl_id ' The pl become the ball owner
            PL_team_owner_id = pl(pl_id).team
            exit sub
        case else
            SHELL_message =  str(decision) + " - TILE " + str(tile) + " *** SORRY <undefined>"
            exit sub
            
        end select
    end if
END SUB

SUB get_user_input()
    dim e As EVENT
    If (ScreenEvent(@e)) Then
        Select Case e.type
        Case EVENT_KEY_RELEASE
            If (e.scancode = SC_D) Then
                DEBUG = DEBUG xor 1
            End If
            If (e.scancode = SC_P) Then
                'pause
                SLEEP
            End If
        End Select
    End If
    'in Watch match and Debug mode the user may move the ball
    'or use some custom keys to check the correct behaviour of
    'the Match_event
    if DEBUG and Human_control = 0 then
        if Multikey(SC_UP) then ball.speed *=1.7
        if Multikey(SC_RIGHT) then ball.rds -= 0.25
        if Multikey(SC_LEFT) then ball.rds += 0.25
        if Multikey(SC_0) then Match_event = ball_in_game : Match_event_delay = MATCH_EVENT_DEFAULT_DELAY
        if Multikey(SC_1) then Match_event = corner_tl_side_t0 : Match_event_delay = MATCH_EVENT_DEFAULT_DELAY
        if Multikey(SC_2) then Match_event = corner_tr_side_t0 : Match_event_delay = MATCH_EVENT_DEFAULT_DELAY
        if Multikey(SC_3) then Match_event = throw_in_lside_t0 : Match_event_delay = MATCH_EVENT_DEFAULT_DELAY
        if Multikey(SC_4) then Match_event = throw_in_rside_t0 : Match_event_delay = MATCH_EVENT_DEFAULT_DELAY
        if Multikey(SC_5) then Match_event = penalty_t0 : Match_event_delay = MATCH_EVENT_DEFAULT_DELAY
        if Multikey(SC_6) then Match_event = penalty_t1 : Match_event_delay = MATCH_EVENT_DEFAULT_DELAY
        if Multikey(SC_7) then Match_event = foul_t0 : Match_event_delay = MATCH_EVENT_DEFAULT_DELAY
    end if
    
END SUB

SUB get_user_input_action(c as Integer)
    'if Human press the CTRL key that wasn't pressed before
    If Multikey(SC_CONTROL) and key_pressed = 0 and pl(c).action = running then
        Key_pressed = 1
        Key_released = 0
        Key_pressed_time_start = Timer
    end if
    'CTRL key released
    If not Multikey(SC_CONTROL) and key_pressed = 1 and pl(c).action = running then
        Key_pressed = 0
        Key_released = 1
    end if
    ' if the CTRL key has been released then...
    if (Key_released) and PL_ball_owner_id = c and is_ball_controllable_by_human(c) and pl(c).action = running then
        
        Key_pressed_gap = timer - Key_pressed_time_start
        Key_released = 0
        Key_pressed = 0
        reset_ball_z()
        ball.rds = pl(c).rds
        if Key_pressed_gap < 0.15 then
            'passing
            if get_pl_to_pass(c) then
                ball.rds = a_b_t_p (pl(c).x, pl(c).y,pl(get_pl_to_pass(c)).x,pl(get_pl_to_pass(c)).y)
                ball.speed =    get_passing_ball_speed (d_b_t_p(pl(c).x, pl(c).y,_
                pl(get_pl_to_pass(c)).x,pl(get_pl_to_pass(c)).y))
                PL_target_id = get_pl_to_pass(c)
            else
                ball.speed = pl(c).speed + 15
                'no pass anyone
                PL_target_id = -1
            end if
        else
            ball.speed = pl(c).speed + 50 * Key_pressed_gap
            ball.z_speed = 12
            ball.z_speed_init = ball.z_speed
            'no pass anyone
            PL_target_id = -1
        end if
        PL_ball_owner_id = c
        PL_team_owner_id = pl(c).team
        pl(c).delay = 20
    end if
    
    'if the CTRL key is released but the pl is not owner of the ball
    'or can't control it
    if (Key_released) then
        Key_released = 0
        Key_pressed = 0
        Key_pressed_time_start = 0
        Key_pressed_gap = 0
    end if
END SUB

SUB get_user_input_ways(c as Integer)
    'checks if the user is pressing two cursor key in the same time
    dim as integer input_diagonal = 0
    If MultiKey(SC_SPACE) then ball.z_speed = 12 : ball.z_speed_init = ball.z_speed
    
    'cursor keys------------------------------------------------------------------------
    If MultiKey(SC_UP) and MultiKey(SC_RIGHT) then
        input_diagonal = 1
        pl(c).rds = _2PI8
        pl(c).speed = pl(c).speed_default
    end if
    If MultiKey(SC_UP) and MultiKey(SC_LEFT) then
        input_diagonal = 1
        pl(c).rds = _2PI_3_8
        pl(c).speed = pl(c).speed_default
    end if
    If MultiKey(SC_DOWN) and MultiKey(SC_LEFT) then
        input_diagonal = 1
        pl(c).rds = _2PI_5_8
        pl(c).speed = pl(c).speed_default
    end if
    If MultiKey(SC_DOWN) and MultiKey(SC_RIGHT) then
        input_diagonal = 1
        pl(c).rds = _2PI_7_8
        pl(c).speed = pl(c).speed_default
    end if
    if input_diagonal = 0 then
        If MultiKey(SC_UP) then
            pl(c).rds = PI_2
            pl(c).speed = pl(c).speed_default
        end if
        If MultiKey(SC_LEFT) then
            pl(c).rds = PI
            pl(c).speed = pl(c).speed_default
        end if
        If MultiKey(SC_RIGHT) then
            pl(c).rds = 0
            pl(c).speed = pl(c).speed_default
        end if
        If MultiKey(SC_DOWN) then
            pl(c).rds = _2PI_6_8
            pl(c).speed = pl(c).speed_default
        end if
    end if
    If MultiKey(SC_CONTROL) and is_ball_headkickable(c) and Pl_ball_owner_id <> c and pl(c).action = running then
        shell_message = " - KEY CTRL Headkick"
        pl(c).speed = 12
        pl(c).delay = 10
        pl(c).action = 2 '2 = headkicking
        Key_released = 0
        Key_pressed = 0
        Key_pressed_time_start = 0
        Key_pressed_gap = 0
        exit sub
    end if
    If MultiKey(SC_CONTROL) and PL_ball_owner_id <> c and pl(c).action = running then
        shell_message = " - KEY CTRL slide"
        pl(c).speed = 15
        pl(c).delay =  20
        pl(c).action = sliding
        pl(c).rds = a_b_t_p(pl(c).x, pl(c).y, ball.x, ball.y)
        Key_released = 0
        Key_pressed = 0
        Key_pressed_time_start = 0
        Key_pressed_gap = 0
        exit sub
    end if
    
END SUB

SUB init_players_proprietes()
    'initializing players proprietes
    dim c as Integer
    for c = 0 to (PL_N_TOT*2-1)
        select case c
        'goalkeepers
        case 0, 1
            if c = 0 then
                pl(c).id = c
                pl(c).team = 0
                pl(c).number = int (c / 2)+1
                pl(c).x = PITCH_MIDDLE_W
                pl(c).y = PITCH_Y + 25+((PITCH_H-50) * (pl(c).team xor 1))
                pl(c).speed_default = 0
                pl(c).speed = pl(c).speed_default
            else
                pl(c).id = c
                pl(c).team = 1
                pl(c).number = int (c / 2)+1
                pl(c).x = PITCH_MIDDLE_W
                pl(c).y = PITCH_Y + 25+((PITCH_H-50) * (pl(c).team xor 1))
                pl(c).speed_default = 0
                pl(c).speed = pl(c).speed_default
            end if
            pl(c).frame = 0
            
            pl(c).tact_offset_x = rnd * 120 - 60
            pl(c).tact_offset_y = rnd * 120 - 60
            pl(c).ball_radius = 25
            pl(c).w = 10
            pl(c).delay = 0
            pl(c).active = 1 ' by default the pl is ready to perform any action
            pl(c).action = running 'by default the pl can run
            'other players
        case else
            if c mod 2 = 0 then
                pl(c).id = c
                pl(c).team = 0
                pl(c).number = int (c / 2)+1
                pl(c).x = rnd * PITCH_W + PITCH_X
                pl(c).y = rnd * PITCH_H\2 + PITCH_Y + PITCH_H\2
                pl(c).speed_default = rnd*(PL_DEFAULT_SPEED*2) + PL_DEFAULT_SPEED*2
                pl(c).speed = pl(c).speed_default
                pl(c).active = 1 ' by default the pl is ready to perform any action
                pl(c).action = running 'by default the pl can run
            else
                pl(c).id = c
                pl(c).team = 1
                pl(c).number = int (c / 2)+1
                if Training_mode then
                    pl(c).x = PITCH_X + pl(c).id * 15
                    pl(c).y = PITCH_Y - 15
                    pl(c).speed_default = 0
                    pl(c).speed = pl(c).speed_default
                    pl(c).active = 1 
                    pl(c).action = running 'by default the pl can run
                else
                    pl(c).x = rnd * PITCH_W + PITCH_X
                    pl(c).y = rnd * PITCH_H\2 + PITCH_Y
                    pl(c).speed_default = rnd*(PL_DEFAULT_SPEED*2) + PL_DEFAULT_SPEED*2
                    pl(c).speed = pl(c).speed_default
                    pl(c).active = 1 ' by default the pl is ready to perform any action
                    pl(c).action = running 'by default the pl can run
                end if
            end if
            pl(c).rds = 0
            pl(c).frame = 0
            pl(c).frame_offset = 0
            pl(c).dist = 0
            
            pl(c).tact_offset_x = rnd * 60 - 30
            pl(c).tact_offset_y = rnd * 60 - 30
            pl(c).ball_radius = 25
            pl(c).w = 10
            pl(c).delay = 0
            
        end select
    next c
    'initialize who is receiving the ball (none)
    PL_target_id = -1
END SUB



SUB load_bitmap()
    dim img_x as integer
    dim img_w as integer
    dim img_y as integer
    dim img_h as integer
    dim count as Integer
    dim action as Integer
    dim offset as integer
    
    'loading players sprites------------------------------------------------------------
    img_w = 21
    img_h = 25
    img_x = 0
    img_y = 0
    'load and stores the sprites into two array
    'one array for each team… then with paint_kits sub
    'the color of the kits of the sprites will be changed
    BLOAD "img\pl_sprites.bmp", 0
    'it loads three time the same sprite because so after it will be painted
    'with custom skin colors (see player_proto type for details)
    'decomment check_bitmap SUB if you want to check the result
    for count = 0 to PL_SPRITES_TOT_N -1
        if (count > 0) and (count MOD 17 = 0) then
            img_x = 0
            img_y += img_h
        end if
        pl_sprite_0(count) = IMAGECREATE (img_w, img_h)
        pl_sprite_1(count) = IMAGECREATE (img_w, img_h)
        gk_sprite(count) = IMAGECREATE (img_w, img_h)
        GET (img_x, img_y)-(img_x + 20, img_y + 24), pl_sprite_0(count)
        GET (img_x, img_y)-(img_x + 20, img_y + 24), pl_sprite_1(count)
        GET (img_x, img_y)-(img_x + 20, img_y + 24), gk_sprite(count)
        img_x += img_w
    next count
    
    '-----------------------------------------------------------------------------------
    
    'loading ball sprites
    BLOAD "img\ball_sprites.bmp", 0
    img_x = 0
    img_y = 0
    for count = 0 to 14
        ball_sprite(count) = IMAGECREATE (img_w, img_h)
        GET (img_x, img_y)-(img_x + 15, img_y + 15), ball_sprite(count)
        img_x += 16
    next count
    
    'loading net sprites
    BLOAD "img\net_0.bmp",0
    net_sprite(0) = IMAGECREATE(106,38)
    GET (0,0)-(105,37), net_sprite(0)
    BLOAD "img\net_1.bmp",0
    net_sprite(1) = IMAGECREATE(106,38)
    GET (0,0)-(105,37), net_sprite(1)
    
    'loading pitch grass
    BLOAD "img\pitch.bmp",0
    pitch_sprite(0) = IMAGECREATE(32,32)
    GET (0,0)-(31,31), pitch_sprite(0)
    pitch_sprite(1) = IMAGECREATE(32,32)
    GET (32,0)-(63,31), pitch_sprite(1)
    
    'loading advertising banner
    BLOAD "img\banner.bmp",0
    banner_sprite = IMAGECREATE(256,24)
    GET (0,0)-(255,23), banner_sprite
    
    'loading the shadowet texture
    BLOAD "img\shadowed.bmp",0
    shadowed_sprite = IMAGECREATE(32,32)
    GET (0,0)-(31,31), shadowed_sprite
    
END SUB




SUB load_behavior()
    dim tl as Integer = 0
    dim c as Integer = 0
    dim temp as Integer = 0
    'read and store into array
    For tl = 0 To 35
        for c = 0 to 9
            Read bhv_tile(tl,c)
        next c
    Next tl
    'transform 10, 20, 35 -> 10, (20+10) = 30, (10+20+35) = 65 [...] and so on
    For tl = 0 To 35
        for c = 1 to 9
            temp = bhv_tile(tl,c-1)
            bhv_tile(tl,c) += temp
        next c
    Next tl
    
END SUB

'BEHAVIOR DATA
'each row represents the behavior of the player OWNER of the ball in "x" tile
'every column represents a percentage [...]
'So, if the pl owns the ball in the 0 tile he could:
'DATA    [tile 0] 10,20,10,20,4,4,10,4,18,0
' 10% pass to nearest, 20% pass to 2nd nearest, 10% pass by short side,
'20% pass longside, 4% pass to the endline pl [...] and so on...

'fields meaning:
'0: pass_to_nearest; 1: pass_to_2nd_nearest; 2: pass_short_side; 3: pass_long_side
'4:pass_endline; 5: pass_center; 6: run_to_centre; 7: run_to_net
'8: run_to_endline; 9: shoot_in_target
'(see functions meaning on the top of this file)
'IMPORTANT: the SUM of each row is always 100

DATA    10,20,10,20,4,4,10,4,18,0
DATA    5,10,5,27,4,4,15,10,20,0
DATA    4,12,3,35,8,13,10,5,10,0
DATA    4,12,3,35,8,13,10,5,10,0
DATA    5,10,5,27,4,4,15,10,20,0
DATA    10,20,10,20,4,4,10,4,18,0
DATA    7,10,7,25,5,15,10,3,18,0
DATA    5,12,7,21,6,18,13,3,15,0
DATA    2,7,10,22,7,21,13,3,15,0
DATA    2,7,10,22,7,21,13,3,15,0
DATA    5,12,7,21,6,18,13,3,15,0
DATA    7,10,7,25,5,15,10,3,18,0
DATA    8,9,8,13,15,13,14,8,12,0
DATA    7,8,9,12,16,18,10,9,11,0
DATA    7,11,11,14,14,7,7,14,15,0
DATA    7,11,11,14,14,7,7,14,15,0
DATA    7,8,9,12,16,18,10,9,11,0
DATA    8,9,8,13,15,13,14,8,12,0
DATA    5,10,7,15,20,6,6,13,13,5
DATA    4,9,10,18,20,6,5,12,10,6
DATA    3,10,9,15,25,3,2,13,12,8
DATA    3,10,9,15,25,3,2,13,12,8
DATA    4,9,10,18,20,6,5,12,10,6
DATA    5,10,7,15,20,6,6,13,13,5
DATA    10,10,7,7,15,2,7,16,15,11
DATA    10,10,10,5,18,3,8,10,10,16
DATA    8,8,12,12,17,0,3,10,10,20
DATA    8,8,12,12,17,0,3,10,10,20
DATA    10,10,10,5,18,3,8,10,10,16
DATA    10,10,7,7,15,2,7,16,15,11
DATA    5,7,15,5,25,8,7,13,3,12
DATA    3,4,4,2,21,2,6,22,1,35
DATA    2,2,2,2,20,6,4,16,1,45
DATA    2,2,2,2,20,6,4,16,1,45
DATA    3,4,4,2,21,2,6,22,1,35
DATA    5,7,15,5,25,8,7,13,3,12


SUB load_fonts()
    '    draw string
END SUB

SUB load_tact()
    'the "tct_tile" array indicates in wich tile the player must be with corresponding
    'ball position. For example: ball in tile 0 -> read from tct_tile(0) = player in tile 1
    dim tl as Integer = 0
    dim c as Integer = 0
    
    For c = 0 To 9
        for tl = 0 to 35
            Read tct_tile(c,tl)
        next tl
    Next c
    
END SUB
'TACT DATA
'each row represents in wich tile the pl must go when he doesn't own the ball
'So, the defender (id: 1) must go to these tiles:
'DATA 	1,1,2,2,2,2,7,7,2,2 [...] etc
' when the ball is in the tile 0, he must go to tile 1
' when the ball is in the tile 1, he must go to tile 1
' when the ball is in the tile 2, he must go to tile 2 [...] and so on...

DATA    1,1,1,1,1,1,1,1,1,1,1,1,7,7,7,7,7,7,7,7,7,7,7,7,13,13,13,13,13,13,13,13,13,13,13,13
DATA    2,2,2,2,2,2,2,2,2,2,2,2,8,8,8,8,8,8,8,8,8,8,8,8,14,14,14,14,14,14,14,14,14,14,14,14
DATA    3,3,3,3,3,3,3,3,3,3,3,3,9,9,9,9,9,9,9,9,9,9,9,9,9,15,15,15,15,15,15,15,15,15,15,15
DATA    4,4,4,4,4,4,4,4,4,4,4,4,10,10,10,10,10,10,10,10,10,10,10,10,16,16,16,16,16,16,16,16,16,16,16,16
DATA    12,13,13,13,13,13,12,13,13,13,13,13,13,13,13,13,13,13,19,19,19,19,19,19,19,19,19,25,25,25,30,25,25,25,25,25
DATA    14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,20,20,20,20,20,20,26,26,26,26,26,26,25,26,26,26,26,26
DATA    15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,21,21,21,21,21,21,27,27,27,27,27,27,27,27,27,27,27,28
DATA    17,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,22,22,22,22,22,22,22,22,22,22,28,28,28,28,28,28,28,35
DATA    20,20,20,20,20,20,20,20,20,20,20,20,26,26,26,26,26,26,26,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32
DATA    21,21,21,21,21,21,21,21,21,21,21,21,27,27,27,27,27,27,27,33,33,33,33,28,33,33,33,33,33,33,33,33,33,33,33,33


SUB move_player(c as integer)
    '###IMPORTANT!#####
    'update pl position moving him
    pl(c).x +=  cos(pl(c).rds)*pl(c).speed
    pl(c).y +=  -sin(pl(c).rds)*pl(c).speed
END SUB

SUB move_all_players()
    dim c as integer = 0
    for c = 0 to PL_N_TOT * 2 - 1
        'if a player is sliding or jumping, ends this action and begin to run
        if pl(c).delay then
            pl(c).delay -=1
        else
            move_player(c)
        end if
        if pl(c).delay = 0 then pl(c).action = running
    next c
END SUB

SUB paint_kits(C_shirt_0 as Integer, C_pants_0 as Integer, C_socks_0 as Integer, _
    C_shirt_1 as Integer, C_pants_1 as Integer, C_socks_1 as Integer)
    
    Dim pitch As Integer
    Dim pixels As Any Ptr
    Dim count as Integer
    dim as Integer img_w = 0
    dim as Integer img_h = 0
    
    for count = 0 to PL_SPRITES_TOT_N - 1
        If 0 <> ImageInfo( pl_sprite_0(count),img_w ,img_h,, pitch, pixels ) Then
            Print "unable to retrieve image information."
            Sleep
            End
        End If
        'Paint the sprite white the selected color image by directly manipulating pixel memory.
        For y As Integer = 0 To img_h
            Dim row As Integer Ptr = pixels + y * pitch
            
            For x As Integer = 0 To img_w
                if row[x] = C_KIT_SHIRT then
                    row[x] = C_SHIRT_0
                end if
                if row[x] = C_KIT_PANTS then
                    row[x] = C_PANTS_0
                end if
                if row[x]= C_KIT_LINE then
                    row[x] = C_PANTS_0
                end if
                if row[x] = C_KIT_SOCKS then
                    row[x] = C_SOCKS_0
                end if
            Next x
            
        Next y
        If 0 <> ImageInfo( pl_sprite_1(count),img_w ,img_h,, pitch, pixels ) Then
            Print "unable to retrieve image information."
            Sleep
            End
        End If
        'Paint the sprite white the selected color image by directly manipulating pixel memory.
        For y As Integer = 0 To img_h
            Dim row As Integer Ptr = pixels + y * pitch
            
            For x As Integer = 0 To img_w
                if row[x] = C_KIT_SHIRT then
                    row[x] = C_SHIRT_1
                end if
                if row[x] = C_KIT_PANTS then
                    row[x] = C_PANTS_1
                end if
                if row[x]= C_KIT_LINE then
                    row[x] = C_PANTS_1
                end if
                if row[x] = C_KIT_SOCKS then
                    row[x] = C_SOCKS_1
                end if
            Next x
        Next y
    next count
    
END SUB

SUB put_ball_on_centre()
    ball.rds = 0
    ball.x = 1+ PITCH_MIDDLE_W
    ball.y = 1+ PITCH_MIDDLE_H
    ball.z = 0
    ball.z_speed = 0
    ball.speed = 0
    ball.w = 4
    ball.frame=0
END SUB

SUB reset_ball_z()
    ball.z = 0
    ball.z_speed = 0
    ball.z_speed_init = 0
END SUB

SUB reset_gk_net_position (c as integer)
    ' if the gk is far away from the net then he comeback to the net
    if d_b_t_p(pl(c).x, pl(c).y, _
    PITCH_MIDDLE_W, PITCH_Y + 25+((PITCH_H-50) * (pl(c).team xor 1))) > 5 then
    pl(c).rds = a_b_t_p(pl(c).x,pl(c).y, _
    PITCH_MIDDLE_W, PITCH_Y + 25+((PITCH_H-50) * (pl(c).team xor 1)))
    pl(c).speed = 3
    'when He gets the net remain there
else
    pl(c).speed = 0
    pl(c).x = PITCH_MIDDLE_W
    pl(c).y = PITCH_Y + 25+((PITCH_H-50) * (pl(c).team xor 1))
    'when stay in the net always watch the ball
    pl(c).rds = a_b_t_p(pl(c).x,pl(c).y, ball.x, ball.y)
end if
END SUB

SUB reset_players_positions()
    dim c as Integer
    for c = 0 to (PL_N_TOT*2-1)
        select case c
        'goalkeepers
        case 0, 1
            if c = 0 then
                pl(c).x = PITCH_MIDDLE_W
                pl(c).y = PITCH_Y + 25+((PITCH_H-50) * (pl(c).team xor 1))
            else
                pl(c).x = PITCH_MIDDLE_W
                pl(c).y = PITCH_Y + 25+((PITCH_H-50) * (pl(c).team xor 1))
            end if
            'other players
        case else
            if c mod 2 = 0 then
                pl(c).x = rnd * PITCH_W + PITCH_X
                pl(c).y = rnd * PITCH_H\2 + PITCH_Y + PITCH_H\2
            else
                if Training_mode then
                    pl(c).x = PITCH_X + pl(c).id * 15
                    pl(c).y = PITCH_Y - 15
                    pl(c).speed_default = 0
                    pl(c).speed = pl(c).speed_default
                    pl(c).active = 1 
                    pl(c).action = running 'by default the pl can run
                else
                    pl(c).x = rnd * PITCH_W + PITCH_X
                    pl(c).y = rnd * PITCH_H\2 + PITCH_Y
                    pl(c).speed = pl(c).speed_default
                    pl(c).active = 1 ' by default the pl is ready to perform any action
                    pl(c).action = running 'by default the pl can run
                end if
            end if
        end select
        pl(c).active = 1
        pl(c).action = 1
    next c
END SUB

SUB restore_players_speed()
    dim c as Integer
    for c = 0 to (PL_N_TOT*2-1)
        pl(c).speed = pl(c).speed_default
        pl(c).active = 1 
    next c
END SUB

SUB run_tactic(c as Integer)
    pl(c).speed = pl(c).speed_default
    pl(c).rds = get_rds_from_tile(get_tact_tile(c),pl(c).x + pl(c).tact_offset_x,pl(c).y+ pl(c).tact_offset_y)
    if get_dist_from_tile (get_tact_tile(c), pl(c).x + pl(c).tact_offset_x,pl(c).y + pl(c).tact_offset_y) < 5 then 
        pl(c).speed = 0
        'offset to the tactic to move randomly the the player (I don't like mummies)
        if int(rnd * 100) > 85 then
            pl(c).tact_offset_x = rnd * 60-30
            pl(c).tact_offset_y = rnd * 60-30
        end if
    else
        pl(c).speed = pl(c).speed_default
    end if
END SUB

SUB run_tactic_all_players(c as integer)
    dim d as Integer = 0
    for d = 2 to PL_N_TOT * 2 - 1
        if d = c then continue for
        run_tactic(d)
    next d
END SUB

SUB store_ball_position()
    if Ball.y > PITCH_Y and Ball.y < PITCH_Y + PITCH_H then 
        Match_event_old_ball_y = Ball.y
        
        'store the right ball x pos for right and left throw in
        if Ball.x > PITCH_X and Ball.x < PITCH_MIDDLE_W then
            Match_event_old_ball_x = PITCH_X + 2
        end if
        if Ball.x >= PITCH_MIDDLE_W and Ball.x < PITCH_W + PITCH_X then
            Match_event_old_ball_x = PITCH_X + PITCH_W - 2
        end if
    end if
    'store in which tile the ball is
    if get_ball_tile(0) > 0 and get_ball_tile(0) <= 35 then
        Match_event_last_tile = get_ball_tile(0)
    end if
END SUB

SUB update_ball()
    
    ball.old_x = ball.x
    ball.old_y = ball.y
    'this to desn't allow the ball to become a missile
    if ball.speed > BALL_MAX_SPEED then ball.speed = BALL_MAX_SPEED
    if ball.speed < BALL_MIN_SPEED then ball.speed = 0
    
    'ball bounce physics
    if ball.z_speed > 0 then
        ball.z += ball.z_speed - GRAVITY_ACCEL
        ball.z_speed *= GRAVITY
        ball.speed = ball.speed * AIR_FRICTION
        if (ball.z <=0) then
            ball.z_speed_init *= BOUNCE_FRICTION
            ball.z_speed = ball.z_speed_init
            ball.z = 0
        end if
    else
        if ball.z < 0.5 then ball.z = 0
        ball.speed = ball.speed * friction
    end if
    
    'ball position
    ball.x += cos(ball.rds)*ball.speed
    ball.y += -sin(ball.rds)*ball.speed
    
    'radiants check -> MOD 2*PI
    if ball.rds > PI*2 THEN ball.rds = ball.rds - PI*2
    if ball.rds < 0 THEN ball.rds = ball.rds + PI*2
    
END SUB

SUB update_camera_position()
    camera.speed = d_b_t_p(camera.x, camera.y, ball.x, ball.y) / CAMERA_EASING_RATIO
    camera.x += cos(a_b_t_p(camera.x, camera.y, ball.x, ball.y))*camera.speed
    camera.y += -sin(a_b_t_p(camera.x, camera.y, ball.x, ball.y))*camera.speed
    
    'padding & border limit check
    if (camera.x < PITCH_X + camera.w/2 - CAMERA_PADDING) then
        camera.x = PITCH_X + camera.w/2 - CAMERA_PADDING
    end if
    if (camera.x > PITCH_X + PITCH_W - camera.w/2 + CAMERA_PADDING) then
        camera.x = PITCH_X + PITCH_W - camera.w/2 + CAMERA_PADDING
    end if
    if (camera.y > PITCH_Y + PITCH_H - camera.h/2 + CAMERA_PADDING) then
        camera.y = PITCH_Y + PITCH_H - camera.h/2 + CAMERA_PADDING
    end if
    if (camera.y < PITCH_Y + camera.h/2 - CAMERA_PADDING) then
        camera.y = PITCH_Y + camera.h/2 - CAMERA_PADDING
    end if
    'update global variables
    c_x_o = camera.x - camera.w/2
    c_y_o = camera.y - camera.h/2
END SUB

SUB update_main_menu()
    dim e As EVENT
    dim enter_pressed as integer = 0
    If (ScreenEvent(@e)) Then
        Select Case e.type
        Case EVENT_KEY_RELEASE
            If (e.scancode = SC_UP) and main_menu_selected_item > 0 Then
                main_menu_selected_item -=1
            End If
            If (e.scancode = SC_DOWN) and main_menu_selected_item <= 3 Then
                main_menu_selected_item +=1
            End If
        End Select
    End If
    select case main_menu_selected_item
    case 0
        Human_control = 1
        Training_mode = 0
        Exit_flag = 0
        Debug = 0
    case 1
        Human_control = 0
        Training_mode = 0
        Exit_flag = 0
        Debug = 0
    case 2
        Human_control = 1
        Training_mode = 1
        Exit_flag = 0
        Debug = 0
    case 3
        Human_control = 1
        Training_mode = 1
        Debug = 1
        Exit_flag = 0
    case 4
        Exit_flag = 1
    end select
    
END SUB

sub update_match_event()
    'p is the id of the player selected to perform actions... and the other just watch!
    static p as Integer
    static match_flag as integer ' useful to not perform twice a match_Event
    dim rnd_pl as Integer
    
    'delay check <IMPORTANT!> ---------
    'if more than 0 then -1
    if Match_event_delay then Match_event_delay -=1
    
    'delay check for the Player owner of the ball <IMPORTANT!> ---------
    'if more than 0 then -1
    if PL_ball_owner_id then
        PL_ball_owner_delay -= 1
    else
        PL_ball_owner_delay = PL_DELAY_TIME*2
        PL_ball_owner_id = -1
    end if
    
    select case match_event
        case ball_in_game
            store_ball_position() 'store the right ball y pos for top and bottom throw in
            check_ball_goals() 'only if the ball is in game, there may be goals
            check_throw_in_corner_kick() 'check if the ball doesn't goes outside the pitch
            check_pl_collisions() 'only with ball in game pl may collide each other
            update_players() ' IMPORTANT
            '--------------------------------------------------------------------------
        case penalty_t0, penalty_t1
            if Match_event_delay then
                if Match_event = penalty_t0 then
                    p = get_nrst_pl_ball(0)
                else
                    p = get_nrst_pl_ball(1)
                end if
                'all have to follow tactic but not the pl(p)
                run_tactic_all_players(p)
                move_all_players()
                reset_gk_net_position (0)
                reset_gk_net_position (1)
            else
                if Match_event = penalty_t0 then
                    ball.x = PITCH_MIDDLE_W
                    ball.y = PITCH_Y + PITCH_PENALTY_AREA/1.5 - 48
                else
                    ball.x = PITCH_MIDDLE_W
                    ball.y = PITCH_Y + PITCH_H - PITCH_PENALTY_AREA/1.5 + 48
                end if
                reset_gk_net_position (0)
                reset_gk_net_position (1)
                reset_ball_z()
                restore_players_speed()
                'all the players still continue to move themselves
                run_tactic_all_players(p)
                pl(p).rds = a_b_t_p(pl(p).x, pl(p).y,Ball.x,Ball.y)
                move_all_players()
                if d_b_t_p(pl(p).x, pl(p).y, Ball.x,Ball.y) < 5 and match_flag = 0 then
                    pl(p).action = penalty_kicker
                    pl(p).delay = 20
                    pl(p).x = Ball.x
                    pl(p).y = Ball.y
                    match_flag = 1
                end if
                if match_flag and pl(p).delay < 1 then
                    'the pl shoots in the target
                    ball.rds = a_b_t_p (pl(p).x, pl(p).y,_
                    PITCH_MIDDLE_W , PITCH_Y + PITCH_H * (pl(p).team xor 0)) + rnd * 1.5 -.75
                    ball.speed = 10*rnd+10
                    ball.z_speed_init = 9 : ball.z_speed=ball.z_speed_init
                    PL_ball_owner_id = p
                    PL_team_owner_id = pl(p).team
                    pl(p).action = running
                    match_flag = 0
                    'IMPORTANT!
                    match_event = ball_in_game
                end if
            end if
        'SIDE THROW IN -----------------------------------------------------------------
        case throw_in_lside_t0, throw_in_rside_t0, throw_in_lside_t1, throw_in_rside_t1
            if Match_event_delay then
                if Match_event = throw_in_lside_t0 or Match_event = throw_in_rside_t0 then
                    p = get_nrst_pl_ball(0)
                else
                    p = get_nrst_pl_ball(1)
                end if
                'all have to follow tactic but not the pl(p)
                run_tactic_all_players(p)
                move_all_players()
                reset_gk_net_position (0)
                reset_gk_net_position (1)
            else
                'place the ball along the right or the left pitch line
                if Match_event = throw_in_lside_t0 or _
                Match_event = throw_in_lside_t1 then 
                    ball.x = PITCH_X + 5
                    ball.y = Match_event_old_ball_y
                else
                    ball.x = PITCH_X + PITCH_W - 5
                    ball.y = Match_event_old_ball_y
                end if
                reset_gk_net_position (0)
                reset_gk_net_position (1)
                reset_ball_z()
                restore_players_speed()
                'all the players still continue to move themselves
                run_tactic_all_players(p)
                'the pl id_selected goes to the pitch line to get the ball
                pl(p).rds = a_b_t_p(pl(p).x, pl(p).y,Ball.x,Ball.y)
                move_all_players()
                'if the pl id_selected gets the position then the game
                'may restart
                if d_b_t_p(pl(p).x, pl(p).y, Ball.x,Ball.y) < 5 and match_flag = 0 then
                    pl(p).action = throw_in
                    pl(p).delay = 20
                    pl(p).x = Ball.x
                    pl(p).y = Ball.y
                    match_flag = 1
                    pl(p).rds = a_b_t_p (pl(p).x, pl(p).y,_
                    pl(get_nrst_pl_pass(p)).x,pl(get_nrst_pl_pass(p)).y)
                end if
                if match_flag then pl(p).delay -=1
                if match_flag and pl(p).delay < 1 then
                    'the pl passest to the nearest one
                    ball.rds = a_b_t_p (pl(p).x, pl(p).y,_
                    pl(get_nrst_pl_pass(p)).x,pl(get_nrst_pl_pass(p)).y)
                    ball.speed = get_passing_ball_speed (d_b_t_p(pl(p).x, pl(p).y,_
                    pl(get_nrst_pl_pass(p)).x,pl(get_nrst_pl_pass(p)).y))/15
                    ball.z_speed = 15
                    ball.z_speed_init = ball.z_speed
                    PL_target_id = get_nrst_pl_pass(p)
                    PL_ball_owner_id = p
                    PL_team_owner_id = pl(p).team
                    pl(p).action = running
                    match_flag = 0
                    'IMPORTANT!
                    match_event = ball_in_game
                end if
            end if
    
        'THROW IN BOTTOM AND UPPER SIDE ------------------------------------------------
    case throw_in_tl_side_t0, throw_in_tl_side_t1, _
        throw_in_tr_side_t0, throw_in_tr_side_t1, _
        throw_in_bl_side_t0, throw_in_bl_side_t1, _
        throw_in_br_side_t0, throw_in_br_side_t1
        
        if Match_event = throw_in_tl_side_t0 _
        or Match_event = throw_in_tr_side_t0 _
        or Match_event = throw_in_bl_side_t0 _
        or Match_event = throw_in_br_side_t0 then
            p = 0 'id of gk team 0
        else
            p = 1 'id of gk team 0
        end if
        if Match_event_delay then
            run_tactic_all_players(-1) 'all the players run the tactic
            move_all_players()
            reset_gk_net_position (0)
            reset_gk_net_position (1)

        else
            run_tactic_all_players(-1) 'all the players run the tactic
            move_all_players()
            reset_ball_z()
            restore_players_speed()
            pl(p).speed = 3
            'return the right position for the ball
            select case Match_event
            case throw_in_tl_side_t0, throw_in_tl_side_t1
                ball.x = PITCH_MIDDLE_W - PITCH_PENALTY_AREA/2
                ball.y = PITCH_Y + PITCH_PENALTY_AREA/4
            case throw_in_tr_side_t0, throw_in_tr_side_t1
                ball.x = PITCH_MIDDLE_W + PITCH_PENALTY_AREA/2
                ball.y = PITCH_Y + PITCH_PENALTY_AREA/4
            case throw_in_bl_side_t0, throw_in_bl_side_t1
                ball.x = PITCH_MIDDLE_W - PITCH_PENALTY_AREA/2
                ball.y = PITCH_Y + PITCH_H - PITCH_PENALTY_AREA/4
            case throw_in_br_side_t0, throw_in_br_side_t1
                ball.x = PITCH_MIDDLE_W + PITCH_PENALTY_AREA/2
                ball.y = PITCH_Y + PITCH_H - PITCH_PENALTY_AREA/4
            end select
            
            'the gk goes to get the ball
            pl(p).rds = a_b_t_p(pl(p).x, pl(p).y,Ball.x,Ball.y)
            'if the gk gets the position then the game may restart
            if d_b_t_p(pl(p).x, pl(p).y, Ball.x,Ball.y) < 5 then
                pl(p).x = Ball.x
                pl(p).y = Ball.y
                'the gk launches the ball
                ball.rds = a_b_t_p (pl(p).x, pl(p).y,_
                PITCH_MIDDLE_W, PITCH_Y + (PITCH_H * (pl(p).team xor 0)))_
                + rnd * .5 -.25
                ball.speed = rnd * 5 + 10
                ball.z_speed = 15
                ball.z_speed_init = ball.z_speed
                PL_target_id = -1
                PL_ball_owner_id = p
                PL_team_owner_id = pl(p).team
                'IMPORTANT!
                match_event = ball_in_game
            end if
        end if
    case corner_tl_side_t0, corner_tl_side_t1, _
        corner_tr_side_t0, corner_tr_side_t1, _
        corner_bl_side_t0, corner_bl_side_t1, _
        corner_br_side_t0, corner_br_side_t1
        if Match_event = corner_tl_side_t0 or Match_event = corner_tr_side_t0 or _
        Match_event = corner_bl_side_t0 or Match_event = corner_br_side_t0 then
            p = get_nrst_pl_ball(0)
        else
            p = get_nrst_pl_ball(1)
        end if
        'reset the gk ready position
        reset_gk_net_position (0)
        reset_gk_net_position (1)

    if Match_event_delay then
        run_tactic_all_players(p) 'all the players run the tactic
        move_all_players()
    else
        'ball placement 
        select case Match_event
        case corner_tl_side_t0, corner_tl_side_t1
            ball.x = PITCH_X + 2
            ball.y = PITCH_Y + 2
        case corner_tr_side_t0, corner_tr_side_t1
            ball.x = PITCH_X + PITCH_W - 2
            ball.y = PITCH_Y + 2
        case corner_bl_side_t0, corner_bl_side_t1
            ball.x = PITCH_X + 2
            ball.y = PITCH_Y + PITCH_H - 2
        case corner_br_side_t0, corner_br_side_t1
            ball.x = PITCH_X + PITCH_W - 2
            ball.y = PITCH_Y + PITCH_H - 2
        end select

        reset_ball_z()
        'all the players still continue to move themselves
        run_tactic_all_players(p)
        'the pl id_selected goes to the pitch line to get the ball
        pl(p).rds = a_b_t_p(pl(p).x, pl(p).y,Ball.x,Ball.y)
        move_all_players()
        restore_players_speed()
        
        'if the pl id_selected gets the position then the game
        'may restart
        if d_b_t_p(pl(p).x, pl(p).y, Ball.x,Ball.y) < 5 then
            pl(p).x = Ball.x
            pl(p).y = Ball.y
            rnd_pl = rnd*4+1
            'the pl passest to the nearest one
            ball.rds = a_b_t_p (pl(p).x, pl(p).y,_
            pl(get_nrst2_pl_pass(p,rnd_pl)).x,pl(get_nrst2_pl_pass(p,rnd_pl)).y)+rnd*.3-0.15
            ball.speed = get_passing_ball_speed (d_b_t_p(pl(p).x, pl(p).y,_
            pl(get_nrst2_pl_pass(p,rnd_pl)).x,pl(get_nrst2_pl_pass(p,rnd_pl)).y))/15
            ball.z_speed = 13
            ball.z_speed_init = ball.z_speed
            PL_target_id = get_nrst2_pl_pass(p,rnd_pl)
            PL_ball_owner_id = p
            PL_team_owner_id = pl(p).team
            'IMPORTANT!
            match_event = ball_in_game
        end if
    end if
case gk_t0_owner, gk_t1_owner
    select case Match_event
        case gk_t0_owner
            p = 0
        case gk_t1_owner
            p = 1
    end select
    if Match_event_delay then
        run_tactic_all_players(-1) 'all the players run the tactic
        move_all_players()
        pl(p).speed = 0
    else
        restore_players_speed()
        pl(p).action = running
        rnd_pl = rnd*4+3
        'the gk passest to the nearest one
        ball.rds = a_b_t_p (pl(p).x, pl(p).y,_
        pl(get_nrst2_pl_pass(p,rnd_pl)).x,pl(get_nrst2_pl_pass(p,rnd_pl)).y)+rnd*.3-0.15
        ball.speed = get_passing_ball_speed (d_b_t_p(pl(p).x, pl(p).y,_
        pl(get_nrst2_pl_pass(p,rnd_pl)).x,pl(get_nrst2_pl_pass(p,rnd_pl)).y))/15
        ball.z_speed = 13
        ball.z_speed_init = ball.z_speed
        PL_target_id = get_nrst2_pl_pass(p,rnd_pl)
        PL_ball_owner_id = p
        PL_team_owner_id = pl(p).team
        'IMPORTANT!
        match_event = ball_in_game
    end if
        
case ball_on_centre_t0 
case ball_on_centre_t1
case foul_t0, foul_t1
    'execute this code only one time
    if match_flag=0 then
        Match_event_old_ball_x = Ball.x : Match_event_old_ball_y = Ball.y
        match_flag = 1
    end if
    if Match_event_delay then
        run_tactic_all_players(p) 'all the players run the tactic
        move_all_players()
        'reset the gk ready position
        reset_gk_net_position (0)
        reset_gk_net_position (1)
    else
        if Match_event = foul_t0 then
            p = get_nrst_pl_ball(1)
        else
            p = get_nrst_pl_ball(0)
        end if
        Ball.x = Match_event_old_ball_x
        Ball.y = Match_event_old_ball_y
        reset_ball_z()
        'all the players still continue to move themselves
        run_tactic_all_players(p)
        'the pl id_selected goes to the pitch line to get the ball
        pl(p).rds = a_b_t_p(pl(p).x, pl(p).y,Ball.x,Ball.y)
        move_all_players()
        restore_players_speed()
        ' if the pl reaches the ball, the game may restart
        if d_b_t_p(pl(p).x, pl(p).y, Ball.x,Ball.y) < 5 then
            pl(p).x = Ball.x
            pl(p).y = Ball.y
            'the pl passest to the nearest one
            ball.rds = a_b_t_p (pl(p).x, pl(p).y,_
            pl(get_nrst_pl_pass(p)).x,pl(get_nrst_pl_pass(p)).y)+rnd*.3-0.15
            ball.speed = get_passing_ball_speed (d_b_t_p(pl(p).x, pl(p).y,_
            pl(get_nrst_pl_pass(p)).x,pl(get_nrst_pl_pass(p)).y))/10
            ball.z_speed = 12
            ball.z_speed_init = ball.z_speed
            PL_target_id = get_nrst_pl_pass(p)
            PL_ball_owner_id = p
            PL_team_owner_id = pl(p).team
            'IMPORTANT!
            match_event = ball_in_game
            match_flag = 0
        end if
    end if
    
case presentation
case happy_t0
case happy_t1
end select
end sub

SUB update_players()
    dim c as Integer
    Dim d as Integer
    dim decision as Integer = 0
    dim pl_to_pass as Integer = 0
    dim trg_x as single
    dim trg_y as single
    
    
    'the following is a very bad try to give a decent AI to the players
    for c = 0 to PL_N_TOT * 2 - 1
        'this is useful for the pl behaviour
        decision = rnd*100
        'this is useful for the sprites
        pl(c).old_x = pl(c).x
        pl(c).old_y = pl(c).y
        
    select case pl(c).action
        case 0
        case running
            'countdown of the delay
            if pl(c).delay > 1 then
                pl(c).delay -=1
            else
                pl(c).delay = 0
            end if
            'goalkeepers routine
            if c < 2 then
                trg_x = PITCH_MIDDLE_W
                trg_y = PITCH_Y + 25+((PITCH_H-50) * (pl(c).team xor 1))
                ' if the ball is into the area then the GK runs to the ball
                if is_ball_into_penalty_area (c) then
                    pl(c).rds = a_b_t_p(pl(c).x,pl(c).y, ball.x,ball.y)
                    pl(c).speed = 5
                    ' if the ball is VERY near, and is in posses of the opponent team
                    'try to catch the ball jumping on it
                    if d_b_t_p(pl(c).x,pl(c).y, ball.x, ball.y) < 30 and _
                    ball.z < 25 and PL_team_owner_id <> pl(c).team then
                        pl(c).speed = 1 + int(rnd*14)
                        pl(c).rds += rnd*1-.5
                        pl(c).action = gk_jumping
                        pl(c).delay = 12
                        exit select
                    end if
'                    ' if the ball is VERY near... kick away the ball
                    if d_b_t_p(pl(c).x,pl(c).y, ball.x, ball.y) < 5 and _
                    ball.z < 15 and PL_team_owner_id = pl(c).team then
                        ball.speed = rnd*5 + 10
                        ball.rds = a_b_t_p (pl(c).x, pl(c).y,_
                        PITCH_MIDDLE_W, PITCH_Y + (PITCH_H * (pl(c).team xor 0)))_
                        + rnd * .5 -.25
                        ball.z_speed += 10
                        ball.z_speed_init = 15
                        PL_team_owner_id = pl(c).team
                        PL_ball_owner_id = pl(c).id
                    end if
                'else return to the net
                else
                    'keep running to the net until the distance is more than 5
                    'else keep position
                    reset_gk_net_position (c)
                end if
    else
        'routine for other players (defenders, midfielders, attackers)#########
        'if the pl(c) is the nearest to the ball 
        'run to the ball and restore original speed of the player
        
        if get_nrst_pl_ball(pl(c).team) = c then
            'Human control
            if Human_control and pl(c).team = 0 then
                pl(c).speed = 0
                get_user_input_ways(c)
                if is_ball_controllable_by_human(c) then
                    reset_ball_z()
                    'if this is the first touch then centre the ball on the player
                    if PL_ball_owner_id <> c then
                        ball.x = pl(c).x
                        ball.y = pl(c).y
                        ball.x +=  cos(pl(c).rds)*pl(c).speed
                        ball.y +=  -sin(pl(c).rds)*pl(c).speed
                    end if
                    ball.rds = pl(c).rds
                    ball.speed = pl(c).speed+rnd*2
                    
                    PL_ball_owner_id = c
                    PL_team_owner_id = pl(c).team
                    
                    get_user_input_action(c)
                end if
                exit select
            end if
            pl(c).speed = pl(c).speed_default
            pl(c).rds =  a_b_t_p(pl(c).x,pl(c).y, ball.x,ball.y)
            
            ' try to catch the ball with SLIDING###############################
            if (decision > 90 and is_ball_slidable(c)) then
                pl(c).speed = 15
                pl(c).delay =  20
                pl(c).action = sliding
                continue for
            end if
            'try to hit the ball with HEADKICK################################
            if (decision > 80 and is_ball_headkickable(c)) then
                pl(c).speed = 12
                pl(c).delay = 10
                pl(c).action = jumping
                continue for
            end if
            'if the ball is very near and at the same z level of the pl the
            'pl became owner of the ball
            '#PLAYER OWNER OF THE BALL#
            if d_b_t_p(pl(c).x,pl(c).y, ball.x,ball.y) < 8 and ball.z < 8 _
            and (not pl(c).delay) then
                PL_team_owner_id = pl(c).team
                PL_target_id = -1
                get_pl_behavior(c)
                continue for
            end if
    else
        ' if the pl owns the id that is receiving the ball, him runs to the
        'ball with a little speed help
        if c = PL_target_id then
            pl(c).rds = a_b_t_p(pl(c).x,pl(c).y, ball.x, ball.y)
            'pl(c).speed = pl(c).speed_default * 1.2
        else
            'else runs the tactic
            run_tactic(c)
        end if
    end if
end if
case jumping
    pl(c).speed *= 0.85 'friction of the pl body with the air
    pl(c).delay -= 1
    'if the delay time has passed 
    if pl(c).delay < 1 then
        pl(c).action = running
        'maybe the pl after the headkick will fall
        if (int(rnd*10)> 5) then
            pl(c).action = falled
            pl(c).active = 0
            'pl(c).delay = PL_DELAY_FALLED
        end if
        pl(c).delay = PL_DELAY_FALLED
    end if
    'Oh yeah, I can headkicking, the ball is so near!
    if (d_b_t_p(pl(c).x,pl(c).y, ball.x,ball.y) < 20 and ball.z < 20 and ball.z > 6) then
        ball.rds = pl(c).rds + (PI/2 - PI/4)
        ball.speed = (pl(c).speed/2) + rnd * 2 + 2
        if (int(rnd*10)> 5) then
            ball.z_speed_init = 9 : ball.z_speed=ball.z_speed_init
        end if
        PL_ball_owner_id = c
        pl(c).speed = pl(c).speed_default
        PL_team_owner_id = pl(c).team
    end if
case sliding
    pl(c).speed *= 0.80 'friction of the pl body with the grass
    pl(c).delay -= 1
    
    for d = 0 to (PL_N_TOT*2-1)
        if d = c or pl(d).active = 0 then continue for 'doesn't check himself obviously :)
        if d_b_t_p (pl(c).x, pl(c).y,pl(d).x, pl(d).y) < PL_MIN_SLIDE_DIST then
            pl(d).active = 0
            pl(d).action = falling
            pl(d).delay = PL_DELAY_FALLING
            pl(c).action = running
            'maybe the REFEREE WHISTLES A FOUL
            if int(rnd*100) < RND_SLIDE_FOUL and pl(c).team <> pl(d).team then
                if pl(c).team = 0 then
                    'if is into penalty area the referee whistles a penalty kick
                   if is_pl_into_opponent_penalty_area (d) then
                        match_event = penalty_t1
                    else
                        match_event = foul_t0    
                   end if
                else
                    if is_pl_into_opponent_penalty_area (d) then
                        match_event = penalty_t0
                   else
                        match_event = foul_t1
                   end if
                end if
                Match_event_delay = MATCH_EVENT_DEFAULT_DELAY
                PL_team_owner_id = -1
                PL_ball_owner_id = -1
                PL_target_id = -1
                exit sub
            end if
        end if
    next
    
    'if the pl has catched the ball
    if (d_b_t_p(pl(c).x,pl(c).y, ball.x,ball.y) < 10 and ball.z < 4) then
        pl(c).action = running
        pl(c).delay = 0
        pl(c).speed = pl(c).speed_default
        PL_ball_owner_id = c
    end if
    
    if pl(c).delay < 1 then
        pl(c).speed = pl(c).speed_default
        pl(c).delay = 0
        pl(c).action = running
    end if
    
case falling 'falling ... delays and goto falled
    pl(c).speed *=0.1
    pl(c).delay -= 1
    if pl(c).delay < 1 then
        pl(c).action = falled 
        pl(c).delay = PL_DELAY_FALLED
    end if
case falled
    pl(c).delay -= 1
    pl(c).speed = 0
    if pl(c).delay < 1 then
        pl(c).active = 1
        pl(c).action = running
        pl(c).delay = PL_DELAY_FALLED
        pl(c).speed = pl(c).speed_default
    end if
case gk_jumping 'Only for GoalKeeper - Jumping to catch the ball
    pl(c).speed *= 0.75 'friction of the pl body with the air
    pl(c).delay -= 1
    
    'the Gk can touch the ball only if it is near him and into the penalty area
    if d_b_t_p(pl(c).x,pl(c).y, ball.x, ball.y) < 30 and ball.z < 25 and _
    pl(c).active = 1 and is_ball_into_penalty_area (c) then
        select case decision
        case 0 to 30 'o yeah! the Gk get away the ball also if him doesnt' catch it
            ball.speed *= 0.55
            ball.z_speed *= 0.8
            ball.z_speed_init = ball.z_speed
            ball.rds = PI*2 - ball.rds + (rnd * PI_2 - _2PI_2_8)
            PL_target_id = -1 ' The GK is not passing to anyone
            PL_ball_owner_id = -1 ' The owner of the ball is nobody
            PL_team_owner_id = pl(c).team 'his team is the ball owner
            pl(c).active = 0
        case 31 to 85 ' I have a good GoalKeeper! Him catch the ball
            ball.speed = 0
            PL_target_id = -1 ' The GK is not passing to anyone
            PL_ball_owner_id = c ' The pl become the ball owner
            PL_team_owner_id = pl(c).team 'his team is the ball owner
            reset_ball_z()
            ball.x = pl(c).x : ball.y = pl(c).y
            pl(c).action = gk_falled_w_ball
            reset_ball_z()
            Match_event_delay = MATCH_EVENT_DEFAULT_DELAY
            if pl(c).team = 0 then
                match_event = gk_t0_owner
            else
                match_event = gk_t1_owner
            end if
        case 86 to 100
            'ops! it may become a goal fot the opponent team
        case else
        end select
    end if
    if pl(c).delay < 1 then
        pl(c).action = falled
        pl(c).delay = 5
        pl(c).speed = pl(c).speed_default
    end if
case throw_in
    pl(c).speed = 0
    if pl(c).delay < 1 then
        pl(c).delay = 5
        pl(c).speed = pl(c).speed_default
    end if
case penalty_kicker
    pl(c).speed = 0
case gk_falled_w_ball
    pl(c).speed = 0
    ball.x = pl(c).x : ball.y = pl(c).y
case else
end select
'pl limit check, don't go outside the PITCH
if pl(c).x > PITCH_W + PITCH_X then pl(c).rds = a_b_t_p(pl(c).x, pl(c).y,PITCH_MIDDLE_W,PITCH_MIDDLE_H)
if pl(c).x < PITCH_X then pl(c).rds = a_b_t_p(pl(c).x, pl(c).y,PITCH_MIDDLE_W,PITCH_MIDDLE_H)
if pl(c).y > PITCH_H + PITCH_Y then pl(c).rds = a_b_t_p(pl(c).x, pl(c).y,PITCH_MIDDLE_W,PITCH_MIDDLE_H)
if pl(c).y < PITCH_Y then pl(c).rds = a_b_t_p(pl(c).x, pl(c).y,PITCH_MIDDLE_W,PITCH_MIDDLE_H)

'###IMPORTANT!#####
'update pl position moving him
move_player(c)
next c
END SUB



function d_t_r (degree as integer) as single
    return int (degree * PI/180)
end function

function r_t_d (radiants as integer) as integer
    return int ((radiants * 360) / (PI*2))
end function

function a_b_t_p (x1 as single, y1 as single, x2 as single, y2 as single) as single
    if (x1>x2) then
        if (y1>y2) then
            return asin ((x1-x2)/Sqr(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)))) + PI/2
        else
            return (2 * PI/4)*3 - asin ((x1-x2)/Sqr(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))))  
        end if
    else
        if (y1>y2) then
            return PI/2 - asin ((x2-x1)/Sqr(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))))
        else
            return (2 * PI/4)*3  - asin ((x1-x2)/Sqr(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))))
        end if
    end if
end function

function d_b_t_p (x1 as single, y1 as single, x2 as single, y2 as single) as single
    return Sqr(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)))
end function

function start_frame (radiants as single) as integer
    dim degree as Short
    'convert radiants to degree - not calling the function, it is much faster
    degree = int((radiants * 360) / (2*PI))
    select case degree
    case 0 to 22
        return 0
    case 23 to 67
        return 17
    case 68 to 112
        return 34
    case 113 to 157
        return 51
    case 158 to 202
        return 68
    case 203 to 247
        return 85
    case 248 to 292
        return 102
    case 292 to 337
        return 119
    case 337 to 360
        return 0
    case else
        return 0
    end select
end function

function get_tact_tile (pl_id as Integer) as Integer
    '    'this routine find were the ball is and return the tile where the player must go
    dim tile as Integer 
    dim number as Integer
    
    tile = tct_tile(pl(pl_id).number-2, get_ball_tile(pl(pl_id).team))
    select case match_event
        case penalty_t0, penalty_t1
            if tile < 5 then tile +=5
            if tile > 30 then tile -=5
        case else
    end select
    if pl(pl_id).team = 0 then 
            return tile
        else
            return TILES_N_TOT - tile
    end if 
   
end function

function  get_rds_from_tile(tile as Integer, pl_x as single, pl_y as single) as single
    dim as integer tile_row, tile_col, x_trg, y_trg
    
    tile_row = tile MOD COL_TOT_N
    tile_col = int(tile\COL_TOT_N)
    
    x_trg = (tile_row * PITCH_W\ROW_TOT_N) + PITCH_X + (PITCH_W\ROW_TOT_N)\2
    y_trg = PITCH_H - (tile_col * PITCH_H\COL_TOT_N) + PITCH_Y - (PITCH_H\COL_TOT_N)\2
    
    'just to don't allow the player to disappear
    if x_trg > PITCH_X + PITCH_W or y_trg > PITCH_Y + PITCH_H then
        x_trg = PITCH_X + PITCH_W \2
        y_trg = PITCH_Y + PITCH_H \2
    end if
    
    return a_b_t_p (pl_x,pl_y,x_trg,y_trg)   
end function

function get_dist_from_tile(tile as Integer, pl_x as single, pl_y as single) as single
    dim as integer tile_row, tile_col, x_trg, y_trg
    
    tile_col = tile MOD COL_TOT_N
    tile_row = int(tile\COL_TOT_N)
    
    x_trg = (tile_col * PITCH_W\COL_TOT_N) + PITCH_X + (PITCH_W\COL_TOT_N)\2
    y_trg = PITCH_H - (tile_row * PITCH_H\ROW_TOT_N) + PITCH_Y - (PITCH_H\ROW_TOT_N)\2
    
    return d_b_t_p (pl_x,pl_y,x_trg,y_trg)
    
end function

function get_nrst_pl_ball(n_team as Integer) as Integer
    dim max_dist as integer = 10000
    dim c as Integer
    dim id as Integer
    
    'start from id 2 or 3 to don't inlude goalkeepers
    if n_team = 0 then
        for c = 2 to PL_N_TOT * 2-1 step 2
            if d_b_t_p(pl(c).x,pl(c).y,ball.x,ball.y) < max_dist and pl(c).active = 1 then
                max_dist = d_b_t_p(pl(c).x,pl(c).y,ball.x,ball.y)
                id = c
            end if
        next c
        
        return id
    else
        for c = 3 to PL_N_TOT * 2-1 step 2
            if d_b_t_p(pl(c).x,pl(c).y,ball.x,ball.y) < max_dist and pl(c).active = 1 then
                max_dist = d_b_t_p(pl(c).x,pl(c).y,ball.x,ball.y)
                id = c
            end if
        next c
        
        return id
    end if
end function

function get_nrst_pl_pass(pl_id as Integer) as Integer
    dim max_dist as integer = 10000
    dim as Integer c, id, n_team
    n_team = pl(pl_id).team
    'don't pass to goalkeeper
    for c = 2 to PL_N_TOT * 2-1
        if c = pl_id or pl(c).team <> n_team then continue for 'don't pass himself ot to a player of the other team
        if d_b_t_p(pl(c).x,pl(c).y,pl(pl_id).x,pl(pl_id).y) < max_dist then
            max_dist = d_b_t_p(pl(c).x,pl(c).y,pl(pl_id).x,pl(pl_id).y)
            id = c
        end if
    next c
    
    return id
end function

function get_longside_pl_to_pass (pl_id as Integer) as Integer
    
    dim a(PL_N_TOT,2) as integer
    dim as Integer tile, c, id
    dim max_dist as integer = 10000
    'gets the ball's tile and search the nearest pl to pass who is in the horizontal next tile 
    tile = get_ball_tile(pl(pl_id).team)
    if tile <=29 then
        tile += COL_TOT_N
    end if
    
    if pl(pl_id).team <> 0 then tile = TILES_N_TOT - tile
    
    for c = 0 to PL_N_TOT * 2-1
        if c = pl_id or pl(c).team <> pl(pl_id).team then continue for 'don't pass himself or to a player of the other team
        if get_dist_from_tile(tile, pl(c).x, pl(c).y) < max_dist then
            max_dist = get_dist_from_tile(tile, pl(c).x, pl(c).y)
            id = c
        end if
    next c
    
    return id
    
end function

function get_shortside_pl_to_pass (pl_id as Integer) as Integer
    
    dim a(PL_N_TOT,2) as integer
    dim as Integer tile, c, id
    dim max_dist as integer = 10000
    '    'gets the ball's y and search the nearest pl to pass who is in the vert next tile 
    '
    for c = 0 to PL_N_TOT * 2-1
        'don't pass himself or to a player of the other team
        if c = pl_id or pl(c).team <> pl(pl_id).team then continue for 
        if d_b_t_p(pl(c).x,pl(c).y,pl(pl_id).x+1,PITCH_MIDDLE_W) < max_dist then
            max_dist = d_b_t_p(pl(c).x,pl(c).y,pl(pl_id).x+1,PITCH_MIDDLE_W)
            id = c
        end if
    next c
    
    return id
    
end function


function get_nrst2_pl_pass(pl_id as Integer, order as Integer) as Integer
    
    dim a(PL_N_TOT,2) as integer
    dim as Integer b, c, lowest, start, change
    dim as integer ref
    b = 0
    'list all the pl's distances from the pl_id pl
    for c = 0 to PL_N_TOT * 2-1
        if c = pl_id or pl(c).team <> pl(pl_id).team then continue for 'don't pass himself
        a(b,0)=c
        a(b,1)= d_b_t_p (pl(c).x,pl(c).y,pl(pl_id).x,pl(pl_id).y)
        
        b += 1
    next c
    'sort'em using selection sorting algorithm
    for start = 0 to 9
        ref = a(start,1)
        change = 0 
        for b = start+1 to 9
            if a(b,1) < ref then
                ref = a(b, 1)
                lowest = b
                change = 1
            end if
        next b
        if change then
            swap a(lowest, 0), a(start, 0)
            swap a(lowest, 1), a(start, 1)
        end if
    next start
    
    return a(order, 0)
    
end function

function get_farrest_pl_to_pass(pl_id as Integer) as Integer
    dim min_dist as integer = 1
    dim as Integer c, id, n_team
    n_team = pl(pl_id).team
    for c = 0 to PL_N_TOT * 2-1
        if c = pl_id or pl(c).team <> n_team then continue for 'don't pass himself
        if d_b_t_p(pl(c).x,pl(c).y,pl(pl_id).x,pl(pl_id).y) > min_dist then
            min_dist = d_b_t_p(pl(c).x,pl(c).y,pl(pl_id).x,pl(pl_id).y)
            id = c
        end if
    next c
    
    return id
end function

function get_centerest_pl_to_pass(pl_id as Integer) as Integer
    dim max_dist as integer = 10000
    dim as Integer c, id
    
    for c = 0 to PL_N_TOT * 2-1
        if c = pl_id or pl(c).team <> pl(pl_id).team then continue for 'don't pass himself
        if d_b_t_p(PITCH_MIDDLE_W,PITCH_MIDDLE_H,pl(c).x,pl(c).y) < max_dist then
            max_dist = d_b_t_p(PITCH_MIDDLE_W,PITCH_MIDDLE_H,pl(c).x,pl(c).y)
            id = c
        end if
    next c
    
    return id
end function

function get_endline_pl_to_pass(pl_id as integer) as Integer
    dim max_dist as integer = 10000
    dim as Integer c, id
    
    for c = 2 to PL_N_TOT * 2-1
        if c = pl_id then continue for 'don't pass himself
        if pl(pl_id).team <> pl(c).team then continue for 'don't pass to a player of other team
        if abs(PITCH_Y + PITCH_H * (pl(pl_id).team xor 0) - pl(c).y) < max_dist then
            max_dist = abs(PITCH_Y + PITCH_H * (pl(pl_id).team xor 0) - pl(c).y)
            id = c
        end if
    next c
    
    return id
end function

function get_ball_tile(team as Integer) as Integer
    dim as Integer col, row, tile, x, y, x2,y2
    tile = 0
    
    select case Match_event
    case ball_in_game
        'this routine find in which tile is the ball
        for row = 0 to ROW_TOT_N -1 step 1
            for col = 0 to COL_TOT_N -1 step 1
                'draw the grid
                x = col * PITCH_W \ COL_TOT_N + PITCH_X 
                y = row * PITCH_H \ ROW_TOT_N + PITCH_Y
                x2 = x + PITCH_W \ COL_TOT_N
                y2 = y + PITCH_H \ ROW_TOT_N
                'check if the ball is into a box of the grid
                if (ball.x > x) and (ball.x < x2)_
                and (ball.y>y) and (ball.y < y2) then
                exit for, for
            end if
            tile +=1
        next col
    next row
    case throw_in_lside_t0, throw_in_lside_t1, throw_in_rside_t0, throw_in_rside_t1
        tile = TILES_N_TOT - Match_event_last_tile
    case corner_tl_side_t0, corner_tl_side_t1, corner_tr_side_t0, corner_tr_side_t1, _
        corner_bl_side_t0, corner_bl_side_t1, corner_br_side_t0, corner_br_side_t1
        tile = TILES_N_TOT - Match_event_last_tile
    'in this case evey player run to the opponent net
    case throw_in_tl_side_t0, throw_in_tl_side_t1, throw_in_tr_side_t0, throw_in_tr_side_t1, _
        throw_in_bl_side_t0, throw_in_bl_side_t1, throw_in_br_side_t0, throw_in_br_side_t1, _
        gk_t0_owner, gk_t1_owner
        tile = Match_event_last_tile
    case foul_t0, foul_t1
        tile = TILES_N_TOT - Match_event_last_tile
    case penalty_t0, penalty_t1    
        tile = TILES_N_TOT - Match_event_last_tile
    end select

    if team = 0 then    
        return TILES_N_TOT - tile
    else
        return tile
    end if
end function

function get_passing_ball_speed (dist as Single) as Single
    return (sqr(dist)* 10) * FRICTION
end function

function is_in_camera_crop (x as single, y as single, diam as integer) as Integer
    if (x > camera.x - camera.w/2 - diam and x < (camera.x + camera.w\2 + diam))_
    and (y > camera.y - camera.y/2 - diam and y < (camera.y + camera.h\2 + diam)) then
    return 1
else
    return 0
end if
end function

function is_ball_slidable (c as integer) as Integer
    'if the pl slider is not receiving the ball and if
    'the ball distance is into a specified range (in this case >30 <50)
    '(...) and also important: the ball.z must be less than a fixed value
    if (PL_ball_owner_id <> c) and (PL_target_id <> c)_
    and (d_b_t_p(pl(c).x, pl(c).y,ball.x, ball.y)) < 50 _
    and (d_b_t_p(pl(c).x, pl(c).y,ball.x, ball.y)) > 30 _
    and ball.z < 5 then
    return 1
else
    return 0
end if
end function

function is_ball_headkickable (c as integer) as Integer
    'if the ball is near and its z value is greater than a fixed value
    'then the player tries to hit it with headkick
    if (PL_ball_owner_id <> c) and (d_b_t_p(pl(c).x, pl(c).y,ball.x, ball.y)) < 40 _
    and ball.z > 6 and ball.z < 30 then
    return 1
else
    return 0
end if
end function

function is_ball_into_penalty_area (c as integer) as Integer
    'this function checks if the ball is into the opponent area when the referee whistles a foul…
    if  (Ball.x > PITCH_MIDDLE_W - PITCH_PENALTY_AREA) and _
        (Ball.x < PITCH_MIDDLE_W + PITCH_PENALTY_AREA) and _
        (Ball.y > PITCH_Y + ((PITCH_H - PITCH_PENALTY_AREA/1.5) * (c xor 1))) and _
        (Ball.y < PITCH_Y + PITCH_PENALTY_AREA/1.5 + ((PITCH_H - PITCH_PENALTY_AREA/1.5) * (c xor 1))) then
        return 1
    else
        return 0
    end if
end function

function is_ball_controllable_by_human (c as Integer) as Integer
    if d_b_t_p(pl(c).x,pl(c).y, ball.x,ball.y) < 13 and ball.z < 6 then
        'in this way the pl can't touch twice the ball
        'because after his touch for passing or kicking the delay is set
        'see get_user_input_action SUB for details
        if pl(c).action = running and pl(c).delay > 1 then
            return 0
        else
            return 1
        end if
    else
        return 0
    end if
end function

function is_in_pl_fieldview (c as Integer, pl_to_pass as integer) as Integer
    ' I think I've to revwrite againt this function :(
    if a_b_t_p (pl(c).x, pl(c).y, pl(pl_to_pass).x, pl(pl_to_pass).y) > _2PI_1_8 and _
    a_b_t_p (pl(c).x, pl(c).y, pl(pl_to_pass).x, pl(pl_to_pass).y) < _2PI_7_8 then
    if abs(pl(c).rds - a_b_t_p (pl(c).x, pl(c).y, pl(pl_to_pass).x, pl(pl_to_pass).y)) < PI_2 then
        return 1
    else
        return 0
    end if
else
    if a_b_t_p (pl(c).x, pl(c).y, pl(pl_to_pass).x, pl(pl_to_pass).y) < _2PI_1_8 and _
    abs(pl(c).rds - a_b_t_p (pl(c).x, pl(c).y, pl(pl_to_pass).x, pl(pl_to_pass).y) + _2PI_1_8) < PI_2 then
    return 1
end if
if a_b_t_p (pl(c).x, pl(c).y, pl(pl_to_pass).x, pl(pl_to_pass).y) > _2PI_7_8 and _
abs(pl(c).rds - a_b_t_p (pl(c).x, pl(c).y, pl(pl_to_pass).x, pl(pl_to_pass).y) - _2PI_1_8) < PI_2 then
return 1
end if
return 0
end if
return 0
end function

function is_pl_into_opponent_penalty_area (c as integer) as Integer
    'this function checks if the ball is into the opponent area when the referee whistles a foul…
    if  (pl(c).x > PITCH_MIDDLE_W - PITCH_PENALTY_AREA) and _
        (pl(c).x < PITCH_MIDDLE_W + PITCH_PENALTY_AREA) and _
        (pl(c).y > PITCH_Y + ((PITCH_H - PITCH_PENALTY_AREA/1.5) * (pl(c).team xor 0))) and _
        (pl(c).y < PITCH_Y + PITCH_PENALTY_AREA/1.5 + ((PITCH_H - PITCH_PENALTY_AREA/1.5) * (pl(c).team xor 0))) then
        return 1
    else
        return 0
    end if
end function


function get_pl_to_pass(c as integer) as Integer
    dim a as integer 'counter for the pl to check
    dim max_dist as single = 300 'maximum distance from the passing line
    dim pl_to_pass as integer = 0 'this is useful for the return value of the function
    dim dist as single 'distance between pl(c) and pl(a)
    dim dist_to_passline as single 'distance between passing line and pl(a)
    dim alfa as single 'know angle (angle between pl(c) and pl(a))
    dim as single teta 'unknow angle
    
    'doesn't try to pass to the goalkeeper
    for a = 2 to PL_N_TOT*2 - 1
        'doesn't chek himself or a player of the other team
        if a = c or pl(a).team <> pl(c).team then continue for
        
        if is_in_pl_fieldview (c, a) then
            'here there is the formula to find the shortest perpendicular
            'segment from the given line
            alfa = abs(pl(c).rds)
            teta = PI - (PI_2 + alfa) 'here the unknow angle
            dist = d_b_t_p(pl(c).x, pl(c).y, pl(a).x, pl(a).y)
            dist_to_passline = abs (dist * (sin(teta)/sin(PI_2)))
            if dist_to_passline < max_dist and dist_to_passline < MAX_DIST_PASS then
                max_dist = dist_to_passline
                pl_to_pass = a
            end if
        end if
    next a
    
    return pl_to_pass 'it will return 0 (see above) if there isn't no one pl to pass
    'or the right id of the pl to pass
    
end function

function print_match_event(event as Integer) as String
    Select case match_event
    case 0
        return "NONE"
    case ball_in_game
        return "ball_in_game"
    case penalty_t0
        return "penalty_t0"
    case penalty_t1
        return "penalty_t1"
    case throw_in_lside_t0
        return "throw_in_lside_t0"
    case throw_in_lside_t1
        return "throw_in_lside_t1"
    case throw_in_rside_t0
        return "throw_in_rside_t0"
    case throw_in_rside_t1
        return "throw_in_rside_t1"
    case throw_in_tl_side_t0
        return "throw_in_tl_side_t0"
    case throw_in_tl_side_t1
        return "throw_in_tl_side_t1"
    case throw_in_tr_side_t0
        return "throw_in_tr_side_t0"
    case throw_in_tr_side_t1
        return "throw_in_tr_side_t1"
    case throw_in_bl_side_t0
        return "throw_in_bl_side_t0"
    case throw_in_bl_side_t1
        return "throw_in_bl_side_t1"
    case throw_in_br_side_t0
        return "throw_in_br_side_t0"
    case throw_in_br_side_t1
        return "throw_in_br_side_t1"
    case corner_tl_side_t0
        return "corner_tl_side_t0"
    case corner_tl_side_t1
        return "corner_tl_side_t1"
    case corner_tr_side_t0
        return "corner_tr_side_t0"
    case corner_tr_side_t1
        return "corner_tr_side_t1"
    case corner_bl_side_t0
        return "corner_bl_side_t0"
    case corner_bl_side_t1
        return "corner_bl_side_t1"
    case corner_br_side_t0
        return "corner_br_side_t0"
    case corner_br_side_t1
        return "corner_br_side_t1"
    case gk_t0_owner
        return "gk_t0_owner"
    case gk_t1_owner
        return "gk_t1_owner"
    case ball_on_centre_t0
        return "ball_on_centre_t0"
    case ball_on_centre_t1
        return "ball_on_centre_t1"
    case foul_t0
        return "foul_t0"
    case foul_t1
        return "foul_t1"
    case presentation
        return "presentation"
    case happy_t0
        return "happy_t0"
    case happy_t1
        return "happy_t1"
    case else
        return "<UNDEFINED!!!>"
    end select
end function

'GFX INIT--------------------------------------------------------------------------------
ScreenRes SCREEN_W,SCREEN_H,24,2,0 ' Sets the graphic mode
SCREENSET 1, 0
CLS
WindowTitle GAME_NAME + " " + Str(GAME_VERSION) + " by " + str(GAME_AUTHOR)
'MAIN------------------------------------------------------------------------------------
'hides the mouse
SetMouse 320, 240, 0

'IMPORTANT: respect this order 1) load_behavior; 2) load_tact
load_behavior()
load_tact()

load_bitmap()
'kits are now custom painted by me, but You may use #define colors on the top of the file
dim c_1 as Uinteger
dim c_2 as Uinteger
dim c_3 as Uinteger
c_1 = &h550000:c_2 = &hFFFFFF:c_3 = &hFF20FF
paint_kits  (C_ORANGE, C_WHITE, C_BLUE, _
C_WHITE, C_BLACK, C_GRAY)

'check if the bitmaps have been correctly loaded
'check_bitmap()

DO
    update_main_menu()
    draw_main_menu()
    SLEEP SLEEP_TIME, 1
LOOP UNTIL MULTIKEY(SC_ENTER)

init_players_proprietes()
put_ball_on_centre()
Match_time_start = Timer
DO
    If InKey = Chr(255,107) Then Exit Do 'if the user clicks the X button on the window then ... bye bye JASC
    get_user_input()
    update_match_event()
    
    check_ball_limits()
    update_ball()
    update_camera_position()
   
    'graphic output
    screenlock ' Lock the screen
    screenset workpage, workpage xor 1 ' Swap work pages.
    cls
    
    draw_pitch()
    draw_debug()
    draw_top_net()
    draw_players()
    'draw_ball()
    draw_bottom_net()
    draw_bottom_info()
    
    draw string (20,20), str(int((Timer - Match_time_start)/2)) + " mins", C_WHITE
   
    
    workpage xor = 1 ' Swap work pages.
    screensync 'wait for vsync
    screenunlock ' Unlock the page to display what has been drawn on the screen
    
    SLEEP SLEEP_TIME, 1 ' Slow down the program to prevent CPU overheating :)
    'this is a very early version of the timer
    if Timer - Match_time_start > 180 then exit do
LOOP UNTIL MULTIKEY(SC_ESCAPE) or Exit_flag = 1
draw_aknowledgements()
delete_bitmap()
END
