⚙️Configuration

Here's a preview of all the config files of the script

config.lua
Config = {}

--- [[ Markhor Bridge ]] ---
--- [[ Markhor Bridge ]] ---


--- This resource depends on Markhor Bridge.
--- With Markhor Bridge, all necessary settings (such as framework, inventory, interact, etc.) are automatically set.
--- You don't have to do anything except install Markhor Bridge.


--- [[ Markhor Bridge ]] ---
--- [[ Markhor Bridge ]] ---

Config.language = "EN" -- Choose Language -> "EN" / "NL".
Config.minMinutes = 1 -- Minimum number of minutes a user can select.
Config.maxMinutes = 10 -- Maximum number of minutes a user can select.

Config.menuKey = 38 -- Key to open the menu, default: E.
Config.maxTabs = 3 -- Maximum number of tabs in the leaderboard before the tracks are put in the dropdown menu.

-- Check-in place, this is the place where a track can be chosen and a party can be created.
Config.checkIn = {
    vec = vector3(-247.78, -2014.2, 30.15),
    heading = 242.5,
    sprite = 150, 
    color = 8, 
    name = 'airsoft',
    marker = {
        type = 5,
        sizeX = 1.0,
        sizeY = 1.0,
        sizeZ = 1.0,
        drawDistance = 100.0,
        color = {r = 0, g = 255, b = 255, a = 100}
    }
}

-- Grouping point is the place where everyone needs to be to start the match.
Config.groupingPoint = {
    vec = vector3(-272.88, -2032.28, 30.15), 
    heading = 119.08, 
    sprite = 171, 
    color = 2, 
    name = 'Grouping point',
    marker = {
        type = 1,
        sizeX = 15.0,
        sizeY = 15.0,
        sizeZ = 1.0,
        drawDistance = 100.0,
        color = {r = 0, g = 255, b = 0, a = 100}
    }
}

-- Rewards that take place after the end of the game. You can add random items or money. Weapons are not possible.
-- The TDM rewards will be awarded to each player on the winning team. Only the winner receives the FFA reward.
Config.enableRewards = true -- Enable or disable the rewards
Config.minPlayersReward = 1 -- Minimum players to give rewards
Config.rewards = {
    ["TDM"] = {
        {item = 'bank', type = 'account', label = 'Bank', min = 100, max = 500},
        {item = 'water', type = 'item', label = 'Water', min = 2, max = 15},
    },
    ["FFA"] = {
        {item = 'bank', type = 'account', label = 'Bank', min = 500, max = 1000},
        {item = 'bread', type = 'item', label = 'Bread', min = 5, max = 15},
        {item = 'black_money', type = 'account',  label = 'Black Money', min = 100, max = 500},
    },
}

-- Add all maps like the examples given. Each map must have the following variables:
-- name             -> This name will be the display name of the folder.
-- playerMinLimit   -> Minimum number of players required to play this map.
-- playerMaxLimit   -> Maximum number of players for this map.
-- tdm redspawn     -> Spawn point for the red team in the game mode TDM.
-- tdm bluespawn    -> Spawn point for the blue team in the game mode TDM.
-- ffa spawns       -> Spawn points for the game mode FFA. These points are randomly selected after a respawn.
Config.maps = {
    {
        name = 'Arena',    
        playerMinLimit = 1,
        playerMaxLimit = 20,
        tdm = {
            redSpawn = {vec = vector3(1277.88, 811.027, 2640.73038), heading = 175.04},
            blueSpawn = {vec = vector3(1287.65, 705.13, 2640.74), heading = 359.73},
        },
        ffa = {
            spawns = {
                {vec = vector3(1277.88, 811.027, 2640.73038), heading = 175.04},
                {vec = vector3(1287.65, 705.13, 2640.74), heading = 359.73},
                {vec = vector3(1323.196, 768.4758, 2647.801617), heading = 109.34},

            },
        },
    },
    {
        name = 'Nuketown',

        playerMinLimit = 1,
        playerMaxLimit = 10,
        tdm = {
            redSpawn = {vec = vector3(2982.20, -784.94, 2405.39), heading = 39.42},
            blueSpawn = {vec = vector3(2926.78, -719.04, 2405.38), heading = 234.42},
        },
        ffa = {
            spawns = {
                {vec = vector3(2982.20, -784.94, 2405.39), heading = 39.42},
                {vec = vector3(2926.78, -719.04, 2405.38), heading = 234.42},
                {vec = vector3(2922.34, -769.67, 2405.38), heading = 260.38},
                {vec = vector3(2982.89, -780.91, 2405.39), heading = 74.98},
                {vec = vector3(2964.08, -744.17, 2405.16), heading = 357.41},
                {vec = vector3(2948.58, -791.17, 2405.38), heading = 355.37},
            },
        },
    }
}

-- These are the outfits selected when starting the match
Config.Outfits = {
	ffa = {
		male = {['helmet_1'] = -1, ['tshirst_2'] = 5, ['bags_1'] = 103, ['pants_2'] = 11, ['pants_1'] = 28, ['decals_1'] = 0, ['helmet_2'] = 0, ['shoes_2'] = 5, ['torso_2'] = 4, ['bags_2'] = 1, ['chain_2'] = 0, ['tshirt_1'] = 14, ['chain_1'] = 0, ['bproof_1'] = -1, ['torso_1'] = 69, ['shoes_1'] = 8, ['decals_2'] = 0, ['arms'] = 0},
		female = {['helmet_1'] = -1, ['tshirst_2'] = 7, ['bags_1'] = 110, ['pants_2'] = 1, ['pants_1'] = 23, ['decals_1'] = 0, ['helmet_2'] = 0, ['shoes_2'] = 3, ['torso_2'] = 4, ['bags_2'] = 1, ['chain_2'] = 0, ['tshirt_1'] = 55, ['chain_1'] = 0, ['bproof_1'] = -1, ['torso_1'] = 63, ['shoes_1'] = 58, ['decals_2'] = 0, ['arms'] = 0}
	},
	red = {
		male = {['helmet_1'] = -1, ['tshirst_2'] = 4, ['bags_1'] = 103, ['pants_2'] = 2, ['pants_1'] = 28, ['decals_1'] = 0, ['helmet_2'] = 0, ['shoes_2'] = 11, ['torso_2'] = 3, ['bags_2'] = 3, ['chain_2'] = 0, ['tshirt_1'] = 14, ['chain_1'] = 0, ['bproof_1'] = -1, ['torso_1'] = 69, ['shoes_1'] = 8, ['decals_2'] = 0, ['arms'] = 0},
		female = {['helmet_1'] = -1, ['tshirst_2'] = 2, ['bags_1'] = 110, ['pants_2'] = 7, ['pants_1'] = 23, ['decals_1'] = 0, ['helmet_2'] = 0, ['shoes_2'] = 5, ['torso_2'] = 3, ['bags_2'] = 3, ['chain_2'] = 0, ['tshirt_1'] = 55, ['chain_1'] = 0, ['bproof_1'] = -1, ['torso_1'] = 63, ['shoes_1'] = 58, ['decals_2'] = 0, ['arms'] = 0}
	},
	blue = {
		male = {['helmet_1'] = -1, ['tshirst_2'] = 5, ['bags_1'] = 103, ['pants_2'] = 11, ['pants_1'] = 28, ['decals_1'] = 0, ['helmet_2'] = 0, ['shoes_2'] = 5, ['torso_2'] = 4, ['bags_2'] = 1, ['chain_2'] = 0, ['tshirt_1'] = 14, ['chain_1'] = 0, ['bproof_1'] = -1, ['torso_1'] = 69, ['shoes_1'] = 8, ['decals_2'] = 0, ['arms'] = 0},
		female = {['helmet_1'] = -1, ['tshirst_2'] = 7, ['bags_1'] = 110, ['pants_2'] = 1, ['pants_1'] = 23, ['decals_1'] = 0, ['helmet_2'] = 0, ['shoes_2'] = 3, ['torso_2'] = 4, ['bags_2'] = 1, ['chain_2'] = 0, ['tshirt_1'] = 55, ['chain_1'] = 0, ['bproof_1'] = -1, ['torso_1'] = 63, ['shoes_1'] = 58, ['decals_2'] = 0, ['arms'] = 0}
	}
}

-- Add here all the kits players can choose
Config.Kits = {
    {
        name = 'sb',
        label = 'Switchblade',
        weapon = 'WEAPON_SWITCHBLADE',
    },
    {
        name = 'pistol',
        label = 'Pistol',
        weapon = 'WEAPON_PISTOL_MK2',
    },
    {
        name = 'vp',
        label = 'Vintage pistol',
        weapon = 'WEAPON_VINTAGEPISTOL',
    },
    {
        name = 'sns',
        label = 'SNS pistol',
        weapon = 'WEAPON_ASSAULTRIFLE',
    },
    {
        name = 'mp',
        label = 'Machinepistol',
        weapon = 'WEAPON_MACHINEPISTOL',
    },
    {
        name = 'carbine',
        label = 'Carbine',
        weapon = 'WEAPON_CARBINERIFLE',
    },
    {
        name = 'sc',
        label = 'Special carbine',
        weapon = 'WEAPON_SPECIALCARBINE',
    },
    {
        name = 'ar',
        label = 'Assault rifle',
        weapon = 'WEAPON_ASSAULTRIFLE',
    },
    {
        name = 'br',
        label = 'Bullpup Rifle',
        weapon = 'WEAPON_BULLPUPRIFLE_MK2',
    },
    {
        name = 'gs',
        label = 'Gusenberg sweeper',
        weapon = 'WEAPON_GUSENBERG',
    },
    {
        name = 'bs',
        label = 'Bullpup Shotgun',
        weapon = 'WEAPON_BULLPUPSHOTGUN',
    },
    {
        name = 'sos',
        label = 'Sawn off shotgun',
        weapon = 'WEAPON_SAWNOFFSHOTGUN',
    },
    {
        name = 'hs',
        label = 'Heavy sniper',
        weapon = 'WEAPON_HEAVYSNIPER_MK2',
    },
	    {
        name = 'msmg',
        label = 'Mini SMG',
        weapon = 'WEAPON_MINISMG',
    },
}
language.lua
Language = {
	['EN'] = {
		["createParty"] = "Press ~INPUT_PICKUP~ to create an airsoft party!",
		["alreadyIn"] = "You're already in a party!",
		["invited"] = "You have received an invite from %s. Use the command ~y~/maaccept~w~ to accept it!",
		["inviteSent"] = "An invite has been sent to player: %s",
		["inviteExpired"] = "The invite has ~y~expired~w~!",
		["inviteAccepted"] = "You have ~g~successfully ~b~accepted~w~ the invite!",
		["playerNotFound"] = "Player not found",
		["noInvite"] = "You've received ~r~no~w~ invite!",
		["partyHelp"] = "Commands: ^2/mastart^7, /mainvite (id), /makick (id), /maclose, /maleave, /malb, /mateam, /makitlist, /makit",	
		["partyLeft"] = "You've left ~y~party ~b~~w~!",
		["groupCircle"] = "You ~r~must~w~ be in the ~g~party circle~w~ to ~b~start~w~ the game!",
		["startMatch"] = "The game will be started!",
		["partyCreated"] = "Party ~g~successful~w~ created!\nUse ~y~/mahelp ~g~ to invite players",
		["invalidMinutes"] = "Incorrect amount of minutes",
		["mapBusy"] = "This map is ~r~occupied~w~!",
		["beenKicked"] = "You've been ~r~kicked~w~ out of the party!",
		["playerKicked"] = "You've successfully ~w~kicked player ~y~%s~g~ out of the party!",
		["partyClosed"] = "You've closed the party ~g~successfully~w~!",
		["playersInCircle"] = "Not all ~y~players~w~ are in the ~g~party circle~w~. Want to ~b~kick~w~ them? ~y~(/forcestart)~w~",
		["fewPlayers"] = "There are too ~r~few ~b~players~w~! (min: %s)",
		["manyPlayers"] = "There are too ~r~many ~b~players~w~! (max: %s)",
		["receivedAccount"] = "You received ~r~$%i %s ~w~. ~g~Congratulations!",
		["receivedItem"] = "You received ~r~%ix %s ~w~. ~g~Congratulations!",
		["lessPlayersReward"] = "Too few players have entered for a reward. Minimum %s needed!",
		["currencyIcon"] = "$",
		["cantSelect"] = "You ~r~can't a ~b~team~w~ team in FFA!",
		["playerShot"] = "You've ~r~shot~w~! ~b~Spawn protection~w~ ~r~disabled~w~!",
		["spawnProtection"] = "You've ~g~5 ~w~seconds ~b~spawn protection~w~!",
		["noProtection"] = "Your ~b~spawn protection~w~ has ~r~expired~w~!",
		["kitSelect"] = "Successfully selected kit: ~y~%s~w~!",
		["kitRespawn"] = "You will respawn with the ~y~%s~w~ kit!",
		["wrongKit"] = "Incorrect kit!",
		["teamChosen"] = "~g~Successful~w~ team ~b~%s~w~ chosen!",
		["notInParty"] = "You're not in an airsoft party!",

		["minuteCount"] = "Number of minutes (%s - %s)",
		["menuTitle"] = "Map selection",
		["menuGamemodeTitle"] = "Gamemode selection",
		["isInReadyCircle"] = "~g~You're in the circle, use ~y~/mahelp ~g~ to see all commands",
		["playerWon"] = "%s wins!",
		["tdm"] = "Team Death Match",
		["ffa"] = "Free For All",
		["teamRed"] = "red",
		["teamBlue"] = "blue",
		["teamRandom"] = "random",
		["WinMessage"] = "Team %s wins!",
		["DrawMessage"] = "It's a draw!",
		["PlayerWin"] = "Player %s wins!",

		-- Command help
		["makickDesc"] = "Kick someone from the party",
		["makickArgDesc"] = "Player ID of the player to be kicked",
		["mainviteDesc"] = "Invite someone to the party",
		["mainviteArgDesc"] = "Player ID of the player to be invited",
		["maacceptDesc"] = "Accept the invitation",
		["mastartDesc"] = "Start the game",
		["macloseDesc"] = "Cancel the party",
		["maleaveDesc"] = "Leave the party",
		["mahelpDesc"] = "Help command for airsoft",
		["makitDesc"] = "Choose a kit",
		["makitArgDesc"] = "Name of the kit, check /makitlist",
		["makitlistDesc"] = "Get the kit options",
		["mateamDesc"] = "Join a team",
		["mateamArgDesc"] = "Choose team blue, red or random",
		["malbDesc"] = "Show leaderboard",

		-- Leaderboard
		["totalStarts"] = "Total times started",
		["totalPlayers"] = "Total players",
		["totalFFA"] = "Total FFA kills",
		["totalTDM"] = "Total TDM kills",
		["totalKills"] = "Total kills",

		["logReceivedAccount"] = "received $%s %s",
		["logReward"] = "received %s %s",
	},

	['NL'] = {
		["createParty"] = "Druk op ~INPUT_PICKUP~ om een kartparty aan te maken!",
		["alreadyIn"] = "Je zit al in een party!",
		["invited"] = "Je hebt een invite van %s ontvangen. Gebruik ~y~/maaccept~w~ om deze te accepteren!",
		["inviteSent"] = "Er is een invite gestuurd naar speler: %s",
		["inviteExpired"] = "De invite is ~y~verlopen~w~!",
		["inviteAccepted"] = "Je hebt de invite ~g~succesvol ~b~geaccepteerd~w~!",
		["playerNotFound"] = "Speler niet gevonden",
		["noInvite"] = "Je hebt ~r~geen~w~ invite ontvangen!",
		["partyHelp"] = "Commands: ^2/mastart^7, /mainvite (id), /makick (id), /maclose, /maleave, /malb, /mateam, /makitlist, /makit",	
		["partyLeft"] = "Je hebt de ~y~party ~b~verlaten~w~!",
		["groupCircle"] = "Je ~r~moet~w~ in de ~g~groeperingscirkel~w~ staan om de match te ~b~starten~w~!",
		["startMatch"] = "De match wordt ~y~geladen",
		["partyCreated"] = "Party ~g~succesvol~w~ aangemaakt!\nGebruik ~y~/mahelp ~w~om mensen te inviten",
		["invalidMinutes"] = "Onjuiste hoeveelheid minuten",
		["mapBusy"] = "Deze map is ~r~bezet~w~!",
		["beenKicked"] = "Je bent ~r~gekicked~w~ uit de party!",
		["playerKicked"] = "Je hebt speler ~y~%s~g~ succesvol ~w~gekicked uit de party!",
		["partyClosed"] = "Je hebt de party ~g~succesvol~w~ gesloten!",
		["playersInCircle"] = "Niet alle ~y~spelers~w~ zitten in de ~g~groeperingscirkel~w~. Wil je ze ~b~kicken~w~? ~y~(/forcestart)~w~",
		["fewPlayers"] = "Je bent met te ~r~weinig ~b~spelers~w~! (min: %s)",
		["manyPlayers"] = "Je bent met te ~r~veel ~b~spelers~w~! (max: %s)",
		["receivedAccount"] = "Je ontving ~r~$%i %s ~w~. ~g~Gefeliciteerd!",
		["receivedItem"] = "Je ontving ~r~%ix %s ~w~. ~g~Gefeliciteerd!",
		["lessPlayersReward"] = "Te weinig spelers hebben meegedaan voor een beloning. Minimaal %s nodig!",
		["cantSelect"] = "Je kunt ~r~geen ~b~team~w~ selecteren in FFA!",
		["playerShot"] = "Je hebt ~r~geschoten~w~! ~b~Spawnprotectie~w~ staat ~r~uit~w~!",
		["spawnProtection"] = "Je hebt ~g~5 ~w~seconde ~b~spawnprotectie~w~!",
		["noProtection"] = "Je ~b~spawnprotectie~w~ is ~r~verlopen~w~!",
		["kitSelect"] = "Succesvol kit ~y~%s~w~ gekozen!",
		["kitRespawn"] = "Je zult respawnen met de ~y~%s~w~ kit!",
		["wrongKit"] = "Onjuiste kit!",
		["teamChosen"] = "~g~Succesvol~w~ team ~b~%s~w~ gekozen!",
		["notInParty"] = "Je zit niet in een airsoft party!",

		["minuteCount"] = "Aantal minuten (%s - %s)",
		["menuTitle"] = "Map selectie",
		["menuGamemodeTitle"] = "Gamemode selectie",
		["isInReadyCircle"] = "~g~Je bent in de cirkel, gebruik ~y~/mahelp ~g~om de commando's te zien",
		["playerWon"] = "%s wint!",
		["tdm"] = "Team Death Match",
		["ffa"] = "Free For All",
		["teamRed"] = "red",
		["teamBlue"] = "blue",
		["teamRandom"] = "random",
		["WinMessage"] = "Team %s heeft gewonnen!",
		["DrawMessage"] = "Het is een gelijkspel!",
		["PlayerWin"] = "Speler %s heeft gewonnen!",

		-- Command help
		["makickDesc"] = "Kick iemand van de party",
		["makickArgDesc"] = "Speler ID van de speler die moet worden gekicked",
		["mainviteDesc"] = "Invite iemand voor de party",
		["mainviteArgDesc"] = "Speler ID van de speler die moet worden uitgenodigd",
		["maacceptDesc"] = "Accepteer de uitnodiging",
		["mastartDesc"] = "Start de game",
		["macloseDesc"] = "Hef de party op",
		["maleaveDesc"] = "Verlaat de party",
		["mahelpDesc"] = "Help command voor het airsoften",
		["makitDesc"] = "Kies een kit",
		["makitArgDesc"] = "Naam van de kit, gebruik /makitlist",
		["makitlistDesc"] = "Geef de verschillende kits weer",
		["mateamDesc"] = "Join een team",
		["mateamArgDesc"] = "Kies team blue, red of random",
		["malbDesc"] = "Show leaderboard",

		-- Leaderboard
		["totalStarts"] = "Aantal keer gestart",
		["totalPlayers"] = "Totaal aantal spelers",
		["totalFFA"] = "Totale FFA kills",
		["totalTDM"] = "Totale TDM kills",
		["totalKills"] = "Totale kills",

		["logReceivedAccount"] = "ontving $%s %s",
		["logReward"] = "ontving %s %s",
	}
}
functions.lua
Functions = {}

--- [[ Markhor Bridge ]] ---
--- [[ Markhor Bridge ]] ---


--- This resource depends on Markhor Bridge.
--- With Markhor Bridge, all necessary settings (such as framework, inventory, interact, etc.) are automatically set.
--- You don't have to do anything except install Markhor Bridge.


--- [[ Markhor Bridge ]] ---
--- [[ Markhor Bridge ]] ---

-- With the following client called function, the text messages can be fully customized
Functions.ShowMissiontext = function(text,time)
    ClearPrints()
    SetTextEntry_2("STRING")
    AddTextComponentString(text)
    DrawSubtitleTimed(time, 1)
end

-- This server called function makes it possible to link and customize your own chat resource
Functions.ShowChatMessage = function(src, title, color, message)
    TriggerClientEvent('chatMessage', src, title, color, message)
end

-- This client called function makes it possible to link and customize your own chat resource
Functions.ShowChatMessageClient = function(title, color, message)
    TriggerEvent('chatMessage', title, color, message)
end

-- The two client called functions below are used to change players' outfits.
Functions.loadTeamSkin = function(currentTeam)
    TriggerEvent('skinchanger:getSkin', function(skin)
        TriggerEvent('mh_airsoft:syncSkin', skin)
        local newSkin = nil
        if skin.sex == 0 then
            if currentTeam == Language[Config.language].teamBlue then
                newSkin = Config.Outfits.blue.male
            elseif currentTeam == Language[Config.language].teamRed then
                newSkin = Config.Outfits.red.male
            else
                newSkin = Config.Outfits.ffa.male
            end
        else
            if currentTeam == Language[Config.language].teamBlue then
                newSkin = Config.Outfits.blue.female
            elseif currentTeam == Language[Config.language].teamRed then
                newSkin = Config.Outfits.red.female
            else
                newSkin = Config.Outfits.ffa.female
            end
        end
        TriggerEvent('skinchanger:loadClothes', skin, newSkin)
    end)
end

Functions.restoreSkin = function(oldSkin)
    TriggerEvent('skinchanger:getSkin', function(skin)
        TriggerEvent('skinchanger:loadClothes', skin, oldSkin)
    end)
end

-- To ensure that the ambulance job does not take over the death, it is important that this function is called. This instantly revives the player.
Functions.overruleRevive = function()
    TriggerEvent('mh_ambulancejob:revive')
end

-- This function can be used to check if a player has been killed. The function is called client sided in a loop, when active 0 ticks.
Functions.checkDeath = function(player)
    if NetworkIsPlayerActive(player) then
        local ped = PlayerPedId()

        if IsPedFatallyInjured(ped) and not isDead then
            isDead = true

            local killer_2, killerweapon = NetworkGetEntityKillerOfPlayer(player)
            local killer = GetPedSourceOfDeath(PlayerPedId())

            if killer_2 ~= 0 and killer_2 ~= -1 then
                killer = killer_2
            end

            -- The event below triggers Functions.overruleRevive()
            TriggerEvent('mh_airsoft:onPlayerKilled', NetworkGetNetworkIdFromEntity(killer))

        elseif not IsPedFatallyInjured(ped) then
            isDead = false
        end
    end
end

-- The four client called functions below control the weapons, which can be adjusted as soon as you work with, for example, an unknown inventory.
Functions.GiveWeapon = function(ped, weapon)
    GiveWeaponToPed(ped, weapon, 1000, false, true)
end

Functions.RemoveWeapon = function(ped, weapon)
    RemoveWeaponFromPed(ped, weapon)
end

Functions.ForceWeaponInHand = function(ped, weapon)
    SetCurrentPedWeapon(ped, weapon, true)
end

Last updated