diff --git a/ctf-gamemode/ctf_client.lua b/ctf-gamemode/ctf_client.lua index 9341b8b..bfae06a 100644 --- a/ctf-gamemode/ctf_client.lua +++ b/ctf-gamemode/ctf_client.lua @@ -2,7 +2,7 @@ File: ctf_client.lua Description: This is the main client file and its main purpose is: - - To handle the following client related logic executed via our main thread: (see Citizen.CreateThread). + - To handle the following client related logic executed via our main thread: (see CreateThread). - To perform team selection and camera manipulation if the user is in camera selection: (see boolean bInTeamSelection). - To handle certain client-side flag logic: @@ -79,11 +79,11 @@ AddEventHandler("SetObjectiveVisible", function(flagEntityNetID, bVisible) -- Call NetToEnt to get the entity handle from our net handle (flagEntityNetID), which is sent by the server. local flagEntity = NetToEnt(flagEntityNetID) - print("SetObjectiveVisible: " .. GetEntityArchetypeName(flagEntity) .. " to our player, owner is: " .. GetPlayerName(NetworkGetEntityOwner(flagEntity))) + Citizen.Trace("SetObjectiveVisible: " .. GetEntityArchetypeName(flagEntity) .. " to our player, owner is: " .. GetPlayerName(NetworkGetEntityOwner(flagEntity))) SetEntityVisible(flagEntity, bVisible) else - print("AttachFlagToPlayer: Something terrible happened, where's our flag?") + Citizen.Trace("AttachFlagToPlayer: Something terrible happened, where's our flag?") end end) @@ -359,7 +359,7 @@ function processFlagLogic(flagEntityNetID) local playerPed = PlayerPedId() if entityHasEntityInRadius(ent, playerPed) and not IsEntityDead(playerPed) then TriggerServerEvent("requestFlagUpdate") - Citizen.Wait(500) + Wait(500) end end end @@ -422,11 +422,12 @@ spawnmanager:setAutoSpawn(true) ----------------------------------------------- Threads ----------------------------------------------- -- Process the client flag logic for each flag every tick -Citizen.CreateThread(function() +CreateThread(function() while true do - if not bInTeamSelection then - if receivedServerTeams and #receivedServerTeams > 0 then - for _, team in ipairs(receivedServerTeams) do + if not isInTeamSelection() then + local teamReceived = getReceivedServerTeams() + if teamReceived and #teamReceived > 0 then + for _, team in ipairs(teamReceived) do -- Run flag logic if they are not in camera/team selection if team.id ~= TeamType.TEAM_SPECTATOR then processFlagLogic(team.flagNetworkedID) @@ -434,13 +435,13 @@ Citizen.CreateThread(function() end end end - Citizen.Wait(0) + Wait(0) end end) --- Our main thread. -- We use this thread to handle team selection and to process any flag related logic. -Citizen.CreateThread(function() +CreateThread(function() while true do if receivedServerTeams and #receivedServerTeams > 0 then if shouldGoIntoTeamSelection() and not bIsAttemptingToSwitchTeams then @@ -466,6 +467,6 @@ Citizen.CreateThread(function() -- Process all rendering logic for this frame ctfRenderingRenderThisFrame() - Citizen.Wait(0) + Wait(0) end end) diff --git a/ctf-gamemode/ctf_rendering.lua b/ctf-gamemode/ctf_rendering.lua index 4771a27..d68a708 100644 --- a/ctf-gamemode/ctf_rendering.lua +++ b/ctf-gamemode/ctf_rendering.lua @@ -6,7 +6,7 @@ - Draws instructional UI on the screen: (see drawScaleFormUI). - Contains helper methods to draw text on the screen. Event handlers: - - SendClientHudNotification: Dispatched by the server to display simple 'toast' UI notifications on the client. + - SendClientHudNotification: https://docs.fivem.net/docs/resources/example-resources/events/ctf-gamemode/SendClientHudNotification/ ]] -- Store UI configuration from ctfConfig.UI. @@ -67,7 +67,7 @@ function ctfRenderingRenderThisFrame() end if isInTeamSelection() then - DisableRadarThisFrame() + HideMinimapExteriorMapThisFrame() HideHudAndRadarThisFrame() DrawScaleformMovieFullscreen(buttonsHandle, 255, 255, 255, 255, 1) -- Draw the instructional buttons this frame @@ -121,7 +121,7 @@ end function buttonMessage(text) BeginTextCommandScaleformString("STRING") - AddTextComponentScaleform(text) + AddTextComponentSubstringKeyboardDisplay(text) EndTextCommandScaleformString() end @@ -135,20 +135,20 @@ function drawScaleFormUI(buttonsHandle) CallScaleformMovieMethod(buttonsHandle, 'CLEAR_ALL') -- Clear previous buttons - PushScaleformMovieFunction(buttonsHandle, "SET_DATA_SLOT") - PushScaleformMovieFunctionParameterInt(2) + BeginScaleformMovieMethod(buttonsHandle, "SET_DATA_SLOT") + ScaleformMovieMethodAddParamInt(2) ScaleformMovieMethodAddParamPlayerNameString("~INPUT_SPRINT~") buttonMessage(btnCaptions.Spawn) PopScaleformMovieFunctionVoid() - PushScaleformMovieFunction(buttonsHandle, "SET_DATA_SLOT") - PushScaleformMovieFunctionParameterInt(1) + BeginScaleformMovieMethod(buttonsHandle, "SET_DATA_SLOT") + ScaleformMovieMethodAddParamInt(1) ScaleformMovieMethodAddParamPlayerNameString("~INPUT_ATTACK~") buttonMessage(btnCaptions.PreviousTeam) PopScaleformMovieFunctionVoid() - PushScaleformMovieFunction(buttonsHandle, "SET_DATA_SLOT") - PushScaleformMovieFunctionParameterInt(0) + BeginScaleformMovieMethod(buttonsHandle, "SET_DATA_SLOT") + ScaleformMovieMethodAddParamInt(0) ScaleformMovieMethodAddParamPlayerNameString("~INPUT_AIM~") -- The button to display buttonMessage(btnCaptions.NextTeam) -- the message to display next to it PopScaleformMovieFunctionVoid() @@ -182,9 +182,9 @@ function drawTxt(x,y,width,height,scale, text, r,g,b,a) SetTextDropShadow() SetTextOutline() -- Let's use our previously created text entry 'textRenderingEntry' - SetTextEntry("textRenderingEntry") - AddTextComponentString(text) - DrawText(x - width/2, y - height/2 + 0.005) + BeginTextCommandDisplayText("textRenderingEntry") + AddTextComponentSubstringPlayerName(text) + EndTextCommandDisplayText(x - width/2, y - height/2 + 0.005) end --- https://forum.cfx.re/t/draw-3d-text-as-marker/2643565/2 @@ -205,9 +205,9 @@ function Draw3DText(x, y, z, scl_factor, text) SetTextDropShadow() SetTextOutline() -- Let's use our previously created text entry 'textRenderingEntry' - SetTextEntry("textRenderingEntry") + BeginTextCommandDisplayText("textRenderingEntry") SetTextCentre(1) - AddTextComponentString(text) - DrawText(_x, _y) + AddTextComponentSubstringPlayerName(text) + EndTextCommandDisplayText(_x, _y) end end diff --git a/ctf-gamemode/ctf_server.lua b/ctf-gamemode/ctf_server.lua index 79b003f..3b978de 100644 --- a/ctf-gamemode/ctf_server.lua +++ b/ctf-gamemode/ctf_server.lua @@ -12,10 +12,10 @@ - CTFGame:shutDown: Handles cleanup tasks upon game shutdown, including flag and team destruction. Event Handlers: - - playerJoining: Handles player joining events, triggering team data updates for the client. - - requestTeamData: Responds to client requests for team data. - - sendTeamDataToClient: Sends team data to clients for UI and game state updates. - - assignPlayerTeam: Assigns a team to a player. + - playerJoining: https://docs.fivem.net/docs/resources/example-resources/events/cft-gamemode/playerJoining/ + - requestTeamData: https://docs.fivem.net/docs/resources/example-resources/events/cft-gamemode/requestTeamData/ + - sendTeamDataToClient: https://docs.fivem.net/docs/resources/example-resources/events/cft-gamemode/sendTeamDataToClient/ + - assignPlayerTeam: https://docs.fivem.net/docs/resources/example-resources/events/cft-gamemode/assignPlayerTeam/ Classes: - Team: Represents a team in the CTF game mode. @@ -109,7 +109,7 @@ function Team:createBaseObject() -- wait until it has been created while not DoesEntityExist(baseEntity) do - Citizen.Wait(1) + Wait(1) end -- Now that it's created we can set its state @@ -216,12 +216,12 @@ end -- @see NetworkGetNetworkIdFromEntity -- @see EFlagStatuses function Flag:spawn() - print('Spawning flag at: ' .. self.spawnPosition) + print('^5[INFO] ^7Spawning flag at: ' .. tostring(self.spawnPosition)) -- Calls server setter CREATE_OBJECT_NO_OFFSET, to create an entity on the server local flagEntity = CreateObjectNoOffset(self.modelHash, self.spawnPosition) while not DoesEntityExist(flagEntity) do -- wait until it has been created - Citizen.Wait(1) + Wait(1) end -- Make the object fall so it doesn't stay still in the air by setting the z-velocity @@ -349,7 +349,7 @@ end --- Sets the position of the flag entity. -- @param position (vector3) The new position to set for the flag. function Flag:setPosition(position) - print("setPosition: " .. position .. " entity: " .. tostring(self.entity)) + print("^5[INFO] ^2setPosition: ^5" .. position .. " ^2entity: ^5" .. tostring(self.entity)) SetEntityCoords(self.entity, position.x, position.y, position.z, true, true, true, true) end @@ -724,9 +724,9 @@ AddEventHandler('playerDropped', function (reason) end) -- Main game loop -Citizen.CreateThread(function() +CreateThread(function() while true do ctfGame:update() - Citizen.Wait(500) -- Adjust the interval as needed + Wait(500) -- Adjust the interval as needed end end) diff --git a/tdm-gamemode/fxmanifest.lua b/tdm-gamemode/fxmanifest.lua index 9889aae..d6ac7e8 100644 --- a/tdm-gamemode/fxmanifest.lua +++ b/tdm-gamemode/fxmanifest.lua @@ -1,12 +1,13 @@ fx_version 'bodacious' game 'gta5' -author 'You' -version '1.0.0' +author 'CFX' +description 'First CFX gamemode!' +version '1.0.1' client_script 'tdm_client.lua' server_script 'tdm_server.lua' shared_script { - 'tdm_shared.lua', + 'tdm_locales.lua', 'tdm_config.lua' } diff --git a/tdm-gamemode/tdm_client.lua b/tdm-gamemode/tdm_client.lua index 5fd7e16..975f760 100644 --- a/tdm-gamemode/tdm_client.lua +++ b/tdm-gamemode/tdm_client.lua @@ -2,14 +2,14 @@ File: tdm_client.lua Description: This is the main client file and its main purpose is: - - To handle the following client related logic executed via our main thread: (see Citizen.CreateThread). + - To handle the following client related logic executed via our main thread: (see CreateThread). - To draw any instructional UI on the screen: (see drawScaleFormUI). - To perform team selection and camera manipulation if the user is in camera selection: (see boolean bInTeamSelection). - To receive team data from the server via events: (see receiveTeamData). Event handlers: - - SendClientHudNotification: Dispatched by the server to display simple 'toast' UI notifications on the client. + - SendClientHudNotification: https://docs.fivem.net/docs/resources/example-resources/events/tdm-gamemode/SendClientHudNotification/ - playerSpawned: Dispatched by FiveM resource spawnManager when the player spawns (https://docs.fivem.net/docs/resources/spawnmanager/events/playerSpawned/) We use this event to set the player's position to the base position on first spawn (or respawn after death). - gameEventTriggered: Used in conjunction with CEventNetworkEntityDamage to check if the player was killed. @@ -56,7 +56,8 @@ local UITeamTxtProps = UIConfig.teamTxtProperties local btnCaptions = UIConfig.btnCaptions -- Set the teamID to spectator on script initialization -LocalPlayer.state:set('teamID', TeamType.TEAM_SPECTATOR, true) +-- Learn more about state bags to https://docs.fivem.net/docs/scripting-manual/networking/state-bags/#player-state +LocalPlayer.state:set('teamID', tdmConfig.type.TEAM_SPECTATOR, true) -- Caching the spawnmanager export local spawnmanager = exports.spawnmanager @@ -64,7 +65,7 @@ local spawnmanager = exports.spawnmanager ---------------------------------------------- Functions ---------------------------------------------- --- Our callback method for the autoSpawnCallback down below, we give ourselves guns here. -function onPlayerSpawnCallback() +local onPlayerSpawnCallback = function() local ped = PlayerPedId() -- 'Cache' our ped so we're not invoking the native multiple times. -- Spawn the player via an export at the player team's spawn point. @@ -86,7 +87,7 @@ function onPlayerSpawnCallback() SetEntityVisible(ped, true) end -function setIntoTeamSelection(team, bIsInTeamSelection) +local setIntoTeamSelection = function(team, bIsInTeamSelection) -- Sets the player into camera selection -- Main camera handle only gets created once in order to manipulate it later local ped = PlayerPedId() -- Let's cache the Player Ped ID so we're not constantly calling PlayerPedId() @@ -106,49 +107,49 @@ function setIntoTeamSelection(team, bIsInTeamSelection) SetEntityVisible(ped, not bIsInTeamSelection) end -function buttonMessage(text) +local buttonMessage = function(text) BeginTextCommandScaleformString("STRING") - AddTextComponentScaleform(text) + AddTextComponentSubstringKeyboardDisplay(Locales[tostring(GetCurrentLanguage())][text] or text) -- Calling native every time so if player change game language, it will update automatically EndTextCommandScaleformString() end --- Draws the scaleform UI displaying controller buttons and associated messages for player instructions. -- -- @param buttonsHandle (number) The handle for the scaleform movie. -function drawScaleFormUI(buttonsHandle) +local drawScaleFormUI = function(buttonsHandle) while not HasScaleformMovieLoaded(buttonsHandle) do -- Wait for the scaleform to be fully loaded Wait(0) end CallScaleformMovieMethod(buttonsHandle, 'CLEAR_ALL') -- Clear previous buttons - PushScaleformMovieFunction(buttonsHandle, "SET_DATA_SLOT") - PushScaleformMovieFunctionParameterInt(2) + BeginScaleformMovieMethod(buttonsHandle, "SET_DATA_SLOT") + ScaleformMovieMethodAddParamInt(2) ScaleformMovieMethodAddParamPlayerNameString("~INPUT_SPRINT~") - buttonMessage(btnCaptions.Spawn) + buttonMessage('spawn') PopScaleformMovieFunctionVoid() - PushScaleformMovieFunction(buttonsHandle, "SET_DATA_SLOT") - PushScaleformMovieFunctionParameterInt(1) + BeginScaleformMovieMethod(buttonsHandle, "SET_DATA_SLOT") + ScaleformMovieMethodAddParamInt(1) ScaleformMovieMethodAddParamPlayerNameString("~INPUT_ATTACK~") - buttonMessage(btnCaptions.PreviousTeam) + buttonMessage('previous_team') PopScaleformMovieFunctionVoid() - PushScaleformMovieFunction(buttonsHandle, "SET_DATA_SLOT") - PushScaleformMovieFunctionParameterInt(0) + BeginScaleformMovieMethod(buttonsHandle, "SET_DATA_SLOT") + ScaleformMovieMethodAddParamInt(0) ScaleformMovieMethodAddParamPlayerNameString("~INPUT_AIM~") -- The button to display - buttonMessage(btnCaptions.NextTeam) -- the message to display next to it + buttonMessage('next_team') -- the message to display next to it PopScaleformMovieFunctionVoid() CallScaleformMovieMethod(buttonsHandle, 'DRAW_INSTRUCTIONAL_BUTTONS') -- Sets buttons ready to be drawn end -function removePlayerBlips() +local removePlayerBlips = function() for blipTableIdx, blipHandle in ipairs(enemyBlips) do local blipOwningEntity = GetBlipInfoIdEntityIndex(blipHandle) local playerId = GetPlayerServerId(NetworkGetPlayerIndexFromPed(blipOwningEntity)) if not DoesEntityExist(blipOwningEntity) or Player(playerId).state.teamID == LocalPlayer.state.teamID then - print("Removed orphan blip (" .. GetPlayerName(NetworkGetPlayerIndexFromPed(blipOwningEntity)) .. ")") + Citizen.Trace("Removed orphan blip (" .. GetPlayerName(NetworkGetPlayerIndexFromPed(blipOwningEntity)) .. ")") RemoveBlip(blipHandle) table.remove(enemyBlips, blipTableIdx) end @@ -160,7 +161,7 @@ function tryCreateBlips() local ped = GetPlayerPed(player) if GetBlipFromEntity(ped) == 0 then if Player(GetPlayerServerId(player)).state.teamID ~= LocalPlayer.state.teamID then - print('Added ' .. GetPlayerName(player)) + Citizen.Trace('Added ' .. GetPlayerName(player)) enemyBlips[#enemyBlips+1] = AddBlipForEntity(ped) -- Store the blip handle in the table end end @@ -181,7 +182,7 @@ end -- @param g (number) The value for green (0-255). -- @param b (number) The value for blue (0-255). -- @param alpha (number) The value for alpha/opacity (0-255). -function drawTxt(x, y, width, height, scale, text, r, g, b, a) +local drawTxt = function(x, y, width, height, scale, text, r, g, b, a) SetTextFont(2) SetTextProportional(0) SetTextScale(scale, scale) @@ -191,9 +192,9 @@ function drawTxt(x, y, width, height, scale, text, r, g, b, a) SetTextDropShadow() SetTextOutline() -- Let's use our previously created text entry 'textRenderingEntry' - SetTextEntry("textRenderingEntry") - AddTextComponentString(text) - DrawText(x - width/2, y - height/2 + 0.005) + BeginTextCommandDisplayText("textRenderingEntry") + AddTextComponentSubstringPlayerName(text) + EndTextCommandDisplayText(x - width/2, y - height/2 + 0.005) end --- Handles player input for team selection. @@ -233,19 +234,26 @@ function handleTeamSelectionControl() end -- Define a function to format the team name -function formatTeamName(receivedServerTeams, teamID) +local formatTeamName = function(receivedServerTeams, teamID) + -- Check player language and save in cache + local currentLanguage = tostring(GetCurrentLanguage()) + local teamData = receivedServerTeams[teamID] + local localizedTeamName + -- Check if receivedServerTeams is valid and contains the teamID - if receivedServerTeams and receivedServerTeams[teamID] then + if teamData and teamData.name then -- Concatenate the team name with " Team" suffix - return receivedServerTeams[teamID].name .. " Team" + localizedTeamName = Locales[currentLanguage][teamData.name] or (teamData.name .. " " .. (Locales[currentLanguage]['team'] or "Team")) else -- Return a default message if the team name cannot be formatted - return "Unknown Team" + localizedTeamName = "Unknown Team" end + + return localizedTeamName end function shouldGoIntoCameraSelection() - return LocalPlayer.state.teamID == TeamType.TEAM_SPECTATOR and not bInTeamSelection + return LocalPlayer.state.teamID == tdmConfig.type.TEAM_SPECTATOR and not bInTeamSelection end @@ -322,7 +330,7 @@ end) --- This event is dispatched by spawnmanager once the player spawns (URL at the top of the file). AddEventHandler('playerSpawned', function() if shouldGoIntoCameraSelection() then - setIntoTeamSelection(TeamType.TEAM_BLUE, true) + setIntoTeamSelection(tdmConfig.type.TEAM_BLUE, true) end end) @@ -330,7 +338,7 @@ end) -- For more information on RegisterCommand, see the following link: -- https://docs.fivem.net/natives/?_0x5FA79B0F RegisterCommand("switchteam", function(source, args, rawCommand) - setIntoTeamSelection(TeamType.TEAM_BLUE, true) + setIntoTeamSelection(tdmConfig.type.TEAM_BLUE, true) end) ---------------------------------------------- Callbacks ---------------------------------------------- @@ -347,20 +355,20 @@ spawnmanager:setAutoSpawn(true) -- Lua's coroutines basics can be found here: https://www.lua.org/pil/9.1.html -- Refresh blips every two seconds in case new players join in -Citizen.CreateThread(function() +CreateThread(function() while true do -- Cleanup any old blips removePlayerBlips() -- Recreate blips tryCreateBlips() - Citizen.Wait(2000) + Wait(2000) end end) --- Our main thread. -- We use this thread to perform Text/Sprite Rendering, handling drawing of instructional UI, team selection and camera manipulation. -Citizen.CreateThread(function() +CreateThread(function() local buttonsHandle = RequestScaleformMovie('INSTRUCTIONAL_BUTTONS') -- Request the scaleform to be loaded drawScaleFormUI(buttonsHandle) @@ -369,12 +377,12 @@ Citizen.CreateThread(function() -- Our spectator team is not in use, it's only there for team selection purposes. -- So if we're in that team and we're not in camera selection, we initiate the team selection process. if shouldGoIntoCameraSelection() then - setIntoTeamSelection(TeamType.TEAM_BLUE, true) + setIntoTeamSelection(tdmConfig.type.TEAM_BLUE, true) end -- Run the logic for picking a team if bInTeamSelection then - DisableRadarThisFrame() + HideMinimapExteriorMapThisFrame() HideHudAndRadarThisFrame() -- Draw the instructional buttons this frame @@ -407,6 +415,6 @@ Citizen.CreateThread(function() -- No wanted level ClearPlayerWantedLevel(PlayerId()) - Citizen.Wait(0) + Wait(0) end end) diff --git a/tdm-gamemode/tdm_config.lua b/tdm-gamemode/tdm_config.lua index 45a15fa..ced7f71 100644 --- a/tdm-gamemode/tdm_config.lua +++ b/tdm-gamemode/tdm_config.lua @@ -14,21 +14,27 @@ tdmConfig = {} +tdmConfig.type = { + TEAM_BLUE = 1, + TEAM_RED = 2, + TEAM_SPECTATOR = 3, +} + tdmConfig.teams = { { - id = TeamType.TEAM_RED, + id = tdmConfig.type.TEAM_RED, basePosition = vector3(2555.1860, -333.1058, 92.9928), playerModel = 'a_m_y_beachvesp_01', playerHeading = 90.0 }, { - id = TeamType.TEAM_BLUE, + id = tdmConfig.type.TEAM_BLUE, basePosition = vector3(2574.9807, -342.9044, 92.9928), playerModel = 's_m_m_armoured_02', playerHeading = 90.0 }, { - id = TeamType.TEAM_SPECTATOR, + id = tdmConfig.type.TEAM_SPECTATOR, basePosition = vector3(2574.9807, -342.9044, 92.9928), playerModel = 's_m_m_armoured_02', playerHeading = 90.0 @@ -37,11 +43,6 @@ tdmConfig.teams = { } tdmConfig.UI = { - btnCaptions = { - Spawn = "Spawn", - NextTeam = "Next Team", - PreviousTeam = "Previous Team" - }, teamTxtProperties = { x = 1.0, -- Screen X coordinate y = 0.9, -- Screen Y coordinate diff --git a/tdm-gamemode/tdm_locales.lua b/tdm-gamemode/tdm_locales.lua new file mode 100644 index 0000000..999209b --- /dev/null +++ b/tdm-gamemode/tdm_locales.lua @@ -0,0 +1,128 @@ +--[[ + File: tdm_locales.lua + Description: + This is the main file for the translation + - This will handle all the texts seen by client + + Learn more about languages in GTA with https://docs.fivem.net/natives/?_0x2BDD44CC428A7EAE +]] + +Locales = { + ['0'] = { -- american (en-US) + ['spawn'] = 'Spawn', + ['next_team'] = 'Next Team', + ['previous_team'] = 'Previous Team', + ['blue'] = 'Blue', + ['red'] = 'Red', + ['spectator'] = 'Spectator', + ['team'] = 'Team', + }, + ['1'] = { -- french (fr-FR) + ['spawn'] = 'Apparition', + ['next_team'] = 'Équipe suivante', + ['previous_team'] = 'Équipe précédente', + ['blue'] = 'Bleu', + ['red'] = 'Rouge', + ['spectator'] = 'Spectateur', + ['team'] = 'Équipe', + }, + ['2'] = { -- german (de-DE) + ['spawn'] = 'Spawn', + ['next_team'] = 'Nächstes Team', + ['previous_team'] = 'Vorheriges Team', + ['blue'] = 'Blau', + ['red'] = 'Rot', + ['spectator'] = 'Zuschauer', + ['team'] = 'Team', + }, + ['3'] = { -- italian (it-IT) + ['spawn'] = 'Apparizione', + ['next_team'] = 'Prossima squadra', + ['previous_team'] = 'Squadra precedente', + ['blue'] = 'Blu', + ['red'] = 'Rosso', + ['spectator'] = 'Spettatore', + ['team'] = 'Squadra', + }, + ['4'] = { -- spanish (es-ES) + ['spawn'] = 'Aparecer', + ['next_team'] = 'Equipo siguiente', + ['previous_team'] = 'Equipo anterior', + ['blue'] = 'Azul', + ['red'] = 'Rojo', + ['spectator'] = 'Espectador', + ['team'] = 'Equipo', + }, + ['5'] = { -- brazilian (pt-BR) + ['spawn'] = 'Aparição', + ['next_team'] = 'Próxima equipe', + ['previous_team'] = 'Equipe anterior', + ['blue'] = 'Azul', + ['red'] = 'Vermelho', + ['spectator'] = 'Espectador', + ['team'] = 'Equipe', + }, + ['6'] = { -- polish (pl-PL) + ['spawn'] = 'Pojawienie się', + ['next_team'] = 'Następny zespół', + ['previous_team'] = 'Poprzedni zespół', + ['blue'] = 'Niebieski', + ['red'] = 'Czerwony', + ['spectator'] = 'Widz', + ['team'] = 'Zespół', + }, + ['7'] = { -- russian (ru-RU) + ['spawn'] = 'Появление', + ['next_team'] = 'Следующая команда', + ['previous_team'] = 'Предыдущая команда', + ['blue'] = 'Синий', + ['red'] = 'Красный', + ['spectator'] = 'Наблюдатель', + ['team'] = 'Команда', + }, + ['8'] = { -- korean (ko-KR) + ['spawn'] = '생성', + ['next_team'] = '다음 팀', + ['previous_team'] = '이전 팀', + ['blue'] = '파랑', + ['red'] = '빨강', + ['spectator'] = '관전자', + ['team'] = '팀', + }, + ['9'] = { -- chinesetrad (zh-TW) + ['spawn'] = '生成', + ['next_team'] = '下一隊', + ['previous_team'] = '上一隊', + ['blue'] = '藍色', + ['red'] = '紅色', + ['spectator'] = '旁觀者', + ['team'] = '隊伍', + }, + ['10'] = { -- japanese (ja-JP) + ['spawn'] = 'スポーン', + ['next_team'] = '次のチーム', + ['previous_team'] = '前のチーム', + ['blue'] = '青', + ['red'] = '赤', + ['spectator'] = '観客', + ['team'] = 'チーム', + }, + ['11'] = { -- mexican (es-MX) + ['spawn'] = 'Aparecer', + ['next_team'] = 'Equipo siguiente', + ['previous_team'] = 'Equipo anterior', + ['blue'] = 'Azul', + ['red'] = 'Rojo', + ['spectator'] = 'Espectador', + ['team'] = 'Equipo', + }, + ['12'] = { -- chinesesimp (zh-CN) + ['spawn'] = '生成', + ['next_team'] = '下一队', + ['previous_team'] = '上一队', + ['blue'] = '蓝色', + ['red'] = '红色', + ['spectator'] = '旁观者', + ['team'] = '队伍', + }, +} \ No newline at end of file diff --git a/tdm-gamemode/tdm_server.lua b/tdm-gamemode/tdm_server.lua index 74a8a12..3c7009c 100644 --- a/tdm-gamemode/tdm_server.lua +++ b/tdm-gamemode/tdm_server.lua @@ -16,7 +16,7 @@ - TDMGame:getLeadingTeam: Determines the leading team based on kills count. Event Handlers: - - tdm:onPlayerKilled: Handles player kill events, updating team kills count and notifying clients. + - tdm:onPlayerKilled: https://docs.fivem.net/docs/resources/example-resources/events/tdm-gamemode/onPlayerKilled/ Variables: - teamAssignments: Stores player assignments to different teams for balancing purposes. @@ -54,7 +54,7 @@ end -- -- Example: -- ```lua --- local blueTeam = Team.new(TeamType.TEAM_RED, vector3(2555.1860, -333.1058, 92.9928), 'a_m_y_beachvesp_01') +-- local blueTeam = Team.new(tdmConfig.type.TEAM_RED, vector3(2555.1860, -333.1058, 92.9928), 'a_m_y_beachvesp_01') -- blueTeam:destroy() -- ``` function Team:destroy() @@ -74,10 +74,10 @@ end -- blueTeam:getName() -- ``` function Team:getName() - if self.id == TeamType.TEAM_BLUE then + if self.id == tdmConfig.type.TEAM_BLUE then return "Blue" end - if self.id == TeamType.TEAM_RED then + if self.id == tdmConfig.type.TEAM_RED then return "Red" end return "Spectator" @@ -197,7 +197,7 @@ end) -- https://docs.fivem.net/docs/scripting-reference/events/server-events/ RegisterServerEvent('playerJoining') AddEventHandler('playerJoining', function(source, oldID) - Player(source).state.teamID = TeamType.TEAM_RED -- Initialize to team red + Player(source).state.teamID = tdmConfig.type.TEAM_RED -- Initialize to team red TriggerEvent("sendTeamDataToClient", source) -- Trigger the event locally (on the server) end) @@ -211,7 +211,7 @@ AddEventHandler("sendTeamDataToClient", function(source) -- Iterate through each team in tdmGame.teams for _, team in ipairs(tdmGame.teams) do -- Exclude TEAM_SPECTATOR from the data - if team.id ~= TeamType.TEAM_SPECTATOR then + if team.id ~= tdmConfig.type.TEAM_SPECTATOR then -- Create a table containing team information local teamData = { id = team.id, diff --git a/tdm-gamemode/tdm_shared.lua b/tdm-gamemode/tdm_shared.lua deleted file mode 100644 index 21ce03f..0000000 --- a/tdm-gamemode/tdm_shared.lua +++ /dev/null @@ -1,5 +0,0 @@ -TeamType = { - TEAM_BLUE = 1, - TEAM_RED = 2, - TEAM_SPECTATOR = 3, -} \ No newline at end of file