[STANDALONE] Dodgeball Game

dodgebal-lq-compressed

:man_playing_handball: Dodgeball Game

Want to let of some steam against friends or foes, maybe by throwing dodgeballs at them? This unique addition to your server gives players the possibility to play with up to 10 people in a short but high intensity dodgeball game.

:movie_camera: Detailed Preview: Youtube

:shopping_cart: Get it here: gamzkystore.com

:question: Support: Discord

Key Features:

  • Completely standalone, it works on any framework and no additional resources are needed.
  • Optional to use ox-target for joining the game, this is configurable.
  • A free unencrypted map-edit is included which adds a playing-field to the Vespucci Beach.
  • Pickup dodgeballs and throw them at your opponent, your team wins when all the opponents have been eliminated.
  • A range of possible match-ups, from 1 vs 1 games up to a full 5 vs 5 game.
  • Also easy to adapt to a different location using the highly customizable configuration.
  • Other features, like interaction keys, the POV when playing the game, the amount of dodgeballs and more is editable in the configuration as well.
  • The normal version is encrypted, but key functions are still accessible via bridge code.

The code snippets below are accessible in the encrypted version:

Config
Config = {}

-- If set to true, you can start a dodgeball game on your own. If set to false, you need at least another player to start the game. Some prints are also enabled with this variable
Config.Debug = false

-- Configure the blip to you liking, or disable it. For configuration options see (https://docs.fivem.net/docs/game-references/blips/)
Config.Blip = {
    Enabled = true,
    Sprite = 488,
    Scale = 1.0,
    Color = 15,
    Label = 'Dodgeball',
}

-- If you want to use ox-target instead of drawing text on the screen for players to join, set this to true.
-- If you want to use the standalone version without ox-target, set this to false.
Config.UseOxTarget = false

Config.OxTarget = {
    [1] = { -- Ox-target interaction for team 1
        Icon = 'fa-solid fa-arrow-right-to-bracket',
        Text = 'Join team 1'
    },
    [2] = { -- Ox-target interaction for team 2
        Icon = 'fa-solid fa-arrow-right-to-bracket',
        Text = 'Join team 2'
    }
}

-- The buttons to use for joining a team, see (https://docs.fivem.net/docs/game-references/controls/) if you want to change this to a different key
Config.Interaction = {
    [1] = {        -- The button for joining team 1
        Label = '[~b~H~s~] Join team 1',
        Key = 74,  -- H
    },
    [2] = {        -- The button for joining team 2
        Label = '[~r~K~s~] Join Team 2',
        Key = 311, -- K
    }
}

-- If a player wants to leave before the game starts, it is possible via the interaction below
Config.CancelInteraction = {
    Label = '[~b~Q~s~] Leave the game',
    Key = 44, -- Q
}

-- The 1st player in a team has the option to start the game via the interaction below
Config.StartInteraction = {
    Label = '[~b~X~s~] Start the game',
    Key = 105, -- X
}

-- A ball can be thrown and picked up via the interaction below
Config.BallInteraction = {
    ThrowLabel = '[~b~L-MB~s~]',
    ThrowKey = 24,
    PickupLabel = '[~b~E~s~]',
    PickupKey = 38,
}

-- Force the game to be played in the specified camera mode, setting this field to false will allow any camera mode
Config.ForceCameraMode = 4
--  THIRD_PERSON_NEAR = 0,
-- 	THIRD_PERSON_MEDIUM = 1,
-- 	THIRD_PERSON_FAR = 2,
-- 	CINEMATIC = 3,
-- 	FIRST_PERSON = 4,

-- The keys which are disabled when in a dodgeball game (see https://docs.fivem.net/docs/game-references/controls/)
Config.DisabledKeys = { 22, 23, 24, 36 } -- SPACE, F, L-MB, L-CTRL

-- The hash of the ball prop, if you want to use a different prop, change the hash below
Config.BallHash = `prop_bskball_01`

-- If you dont want to freeze the ped before the game has started, set this to false
Config.FreezePedBeforeGameStart = true

-- The maximum amount of balls someone can carry with them
Config.MaximumBallPickup = 5

-- Configurable settings for the aim marker
Config.AimMarker = {
    Enabled = true,                  -- Enable the marker
    Type = 6,                        -- Marker type (see)
    Scale = 0.3,                     -- Scale of the marker
    RGBA = vector4(135, 5, 20, 150), -- (Red, Green, Blue, Alpha) Color and transparency of the marker
}

-- Some general settings for the dodgeball game, like starting positions
Config.DodgeBall = {
    StartLocation = vector3(-1144.16, -1698.4, 4.35),  -- The location where someone can join a game
    LeaveLocation = vector3(-1145.06, -1697.29, 3.35), -- The location where a player is teleported to when leaving a game
    TotalBallStartingCount = 5,                        -- The total amount of balls given to a team
    PlayerStartLocations = {                           -- The start locations and headings of each player
        [1] = {
            [1] = { Location = vector3(-1148.53, -1694.78, 3.36), Heading = 123.0 },
            [2] = { Location = vector3(-1146.92, -1697.13, 3.34), Heading = 123.0 },
            [3] = { Location = vector3(-1145.35, -1699.54, 3.33), Heading = 123.0 },
            [4] = { Location = vector3(-1143.59, -1701.81, 3.32), Heading = 123.0 },
            [5] = { Location = vector3(-1141.97, -1704.12, 3.31), Heading = 123.0 },
        },
        [2] = {
            [1] = { Location = vector3(-1158.96, -1716.14, 3.2), Heading = 305.0 },
            [2] = { Location = vector3(-1160.59, -1713.79, 3.22), Heading = 305.0 },
            [3] = { Location = vector3(-1162.25, -1711.44, 3.25), Heading = 305.0 },
            [4] = { Location = vector3(-1163.88, -1709.07, 3.27), Heading = 305.0 },
            [5] = { Location = vector3(-1165.58, -1706.68, 3.3), Heading = 305.0 },
        }
    }
}

-- You can change any text below to your liking.
Config.Locales = {
    ['join_display_text'] = 'Play dodgeball',
    ['game_already_started'] = 'The game has already started, wait for it to finish.',
    ['team_full'] = 'The team you are trying to join is full.',
    ['joined_team'] = 'You have joined team %s.', -- %s is replaced by the team number.
    ['player_left'] = 'You have left the game.',
    ['unable_to_start'] = 'You cannot start the game, only the first player can start the game.',
    ['not_enough_players'] = 'You need at least 1 opponent in order to start the game.',
    ['game_starting'] = 'The game is starting, use %s to pickup balls and %s to throw them.', -- %s is replaced by the key labels
    ['remaining_balls'] = 'You have ~b~%s~s~ remaining balls',                                -- %s is replaced by the remaining ball count
    ['no_balls_left'] = 'You don\'t have any balls left.',
    ['player_hit'] = 'You have been hit and are out of the game.',
    ['team_win'] = 'Your team ~b~won~s~ the game!',
    ['team_lose'] = 'Your team ~r~lost~s~ the game...',
    ['pickup_ball'] = 'Ball',
    ['ball_picked_up'] = 'You have picked up a ball.',
    ['maximum_balls'] = 'You cannot carry any more balls.'
}

Accessible Client Bridge Functions
Functions = {}

-- A general notification.
Functions.Notify = function(message)
    if (message == nil or message == '') then return end
    BeginTextCommandThefeedPost('STRING')
    AddTextComponentSubstringPlayerName(message)
    EndTextCommandThefeedPostTicker(false, true)
end

-- Whether or not the player can interact with the game
Functions.CanInteract = function()
    local playerPed = PlayerPedId()

    if IsPedDeadOrDying(playerPed, true) then
        return false
    end

    if IsPedInAnyVehicle(playerPed, false) then
        return false
    end

    return true
end

-- Whenever the player joins, this function is triggered and places the ped at the correct location
Functions.TeleportPlayerToStartPosition = function(startLocation, startHeading)
    local ped = PlayerPedId()
    SetEntityCoords(ped, startLocation, false, false, false, false)
    SetEntityHeading(ped, startHeading)

    if (Config.FreezePedBeforeGameStart) then
        FreezeEntityPosition(ped, true)
    end
end

-- Whenever the player is hit, if the player leaves or if the game has ended, this function is triggered and teleports the player back to the start.
Functions.LeaveGame = function()
    local ped = PlayerPedId()
    SetEntityCoords(ped, Config.DodgeBall.LeaveLocation, false, false, false, false)

    if (Config.FreezePedBeforeGameStart and IsEntityPositionFrozen(ped)) then
        FreezeEntityPosition(ped, false)
    end
end
Accessible Server Bridge Functions
Functions = {}

Functions.OnGameStart = function(teams)
    -- If you want to execute any code when the game starts, you can do it here. The tabel 'teams' contains the server-ids for each player, sorted by team.
    -- You can print the table via print(json.encode(teams)) to view the structure of the table

    if (Config.Debug) then
        print(('gs_dodgeball: Game started with teams: %s'):format(json.encode(teams)))
    end
end

Functions.OnGameFinish = function(winningTeam)
    -- If you want to execute any code when the game finishes, you can do it here.
    -- The variable winningTeam is the index of the team that won, either [1] or [2]

    if (Config.Debug) then
        print(('gs_dodgeball: Game finished and team %s has won.'):format(winningTeam))
    end
end
Code is accessible No, but core functions are accessible
Subscription-based No
Lines (approximately) ~900
Requirements None
Support Yes
3 Likes

please make use of ox lib and ox target :slight_smile:

Thanks for the suggestion! I have just updated the resource which makes this a configurable option (see Config code snippet in the post).

So you can now either draw text on the screen to join the game, or use ox-target to join the game.

is it more than one point? maybe a single game or best of series

Hi Mark,

As of now it is just a single game where, if you get hit, you are out, such that it is a quick-paced game. If you want to play multiple games like a best of five, you will have to keep track of the score manually.

Is it possible to catch the ball to make the other person out like real dodgeball?

This is not possible as of now unfortunately, I can imagine that this feature would also be quite difficult to implement.