mirror of
https://github.com/citizenfx/cfx-server-data.git
synced 2025-01-06 21:02:57 +08:00
Compare commits
6 Commits
60da977c02
...
dbdd474310
Author | SHA1 | Date | |
---|---|---|---|
|
dbdd474310 | ||
|
ea6f1d8133 | ||
|
e7f7519e45 | ||
|
5ca4612547 | ||
|
4fff23e2ff | ||
|
51cc79eda2 |
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,5 +1,3 @@
|
||||
CitizenMP.Server.exe
|
||||
CitizenMP.Server.exe.config
|
||||
NLog.config
|
||||
*.cfg
|
||||
/cache/
|
||||
/resources/\[local\]/
|
||||
|
31
README.md
Normal file
31
README.md
Normal file
@ -0,0 +1,31 @@
|
||||
# cfx-server-data
|
||||
_The data repository for Cfx.re servers_
|
||||
|
||||
## Usage
|
||||
1. Make sure to `git clone`. Don't "Download ZIP", as that'll make it _much_ harder to update to newer versions.
|
||||
2. Put custom resources in `resources/[local]/` if you don't want to be affected by any random messups.
|
||||
|
||||
### Advanced usage
|
||||
You can also consider using the repository as a submodule + symlink for your own Git repository:
|
||||
|
||||
**Linux**:
|
||||
```
|
||||
$ git submodule add https://github.com/citizenfx/cfx-server-data.git vendor/server-data
|
||||
$ ln -s vendor/server-data/resources/ 'resources/[base]/'
|
||||
```
|
||||
|
||||
**Windows**:
|
||||
```
|
||||
> git submodule add https://github.com/citizenfx/cfx-server-data.git vendor/server-data
|
||||
> mklink /d resources\[base] vendor\server-data\resources
|
||||
```
|
||||
|
||||
## Policy
|
||||
You can make pull requests to propose changes that benefit _everyone_. Add new useful resources, change/improve
|
||||
existing ones - anything goes, as long as you make sure to:
|
||||
|
||||
1. Not break existing users/APIs.
|
||||
2. Not change default behavior without a toggle.
|
||||
3. Use best practices (convars over config files, native commands wherever possible, etc.)
|
||||
|
||||
Modifying or rewriting existing resources in this repository for local use only is _strongly_ discouraged.
|
@ -0,0 +1,6 @@
|
||||
resource_type 'map' { gameTypes = { ['basic-gamemode'] = true } }
|
||||
|
||||
map 'map.lua'
|
||||
|
||||
fx_version 'adamant'
|
||||
game 'gta5'
|
@ -0,0 +1,6 @@
|
||||
resource_type 'map' { gameTypes = { ['basic-gamemode'] = true } }
|
||||
|
||||
map 'map.lua'
|
||||
|
||||
fx_version 'adamant'
|
||||
game 'gta5'
|
8
resources/[gamemodes]/[maps]/redm-map-one/fxmanifest.lua
Normal file
8
resources/[gamemodes]/[maps]/redm-map-one/fxmanifest.lua
Normal file
@ -0,0 +1,8 @@
|
||||
resource_type 'map' { gameTypes = { ['basic-gamemode'] = true } }
|
||||
|
||||
map 'map.lua'
|
||||
|
||||
fx_version 'adamant'
|
||||
game 'rdr3'
|
||||
|
||||
rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.'
|
2
resources/[gamemodes]/[maps]/redm-map-one/map.lua
Normal file
2
resources/[gamemodes]/[maps]/redm-map-one/map.lua
Normal file
@ -0,0 +1,2 @@
|
||||
spawnpoint 'player_three' { x = -262.849, y = 793.404, z = 118.087 }
|
||||
spawnpoint 'player_zero' { x = -262.849, y = 793.404, z = 118.087 }
|
6
resources/[gamemodes]/basic-gamemode/fxmanifest.lua
Normal file
6
resources/[gamemodes]/basic-gamemode/fxmanifest.lua
Normal file
@ -0,0 +1,6 @@
|
||||
resource_type 'gametype' { name = 'Freeroam' }
|
||||
|
||||
client_script 'basic_client.lua'
|
||||
|
||||
game 'common'
|
||||
fx_version 'adamant'
|
@ -1,3 +0,0 @@
|
||||
resource_type 'map' { gameTypes = { race = true } }
|
||||
|
||||
map 'map.lua'
|
@ -1,31 +0,0 @@
|
||||
spawnpoint 'ig_brucie' { 1127.99, -569.018, 12.5918, heading = 270 }
|
||||
spawnpoint 'ig_brucie' { 1122.99, -569.018, 12.5918, heading = 270 }
|
||||
spawnpoint 'ig_brucie' { 1119.99, -569.018, 12.5918, heading = 270 }
|
||||
spawnpoint 'ig_brucie' { 1116.99, -569.018, 12.5918, heading = 270 }
|
||||
|
||||
checkpoint { pos = { 1175.38, -568.361, 12.9386 } }
|
||||
checkpoint { pos = { 1192.41, -484.373, 12.9902 } }
|
||||
checkpoint { pos = { 1370.24, -454.326, 16.1487 } }
|
||||
checkpoint { pos = { 1380.32, -319.673, 19.2937 } }
|
||||
checkpoint { pos = { 1153.19, -334.017, 17.6384 } }
|
||||
--[[checkpoint { pos = { 1120.66, -272.068, 19.6985 } }
|
||||
checkpoint { pos = { 1014.76, -270.757, 20.9716 } }
|
||||
checkpoint { pos = { 1018.3, -367.436, 18.9644 } }
|
||||
checkpoint { pos = { 634.072, -400.678, 40.1211 } }
|
||||
checkpoint { pos = { 218.425, -400.586, 14.506 } }
|
||||
checkpoint { pos = { 27.9617, -408.632, 13.7693 } }
|
||||
checkpoint { pos = { -0.9286, -625.767, 13.7056 } }
|
||||
checkpoint { pos = { -114.801, -646.633, 13.8117 } }
|
||||
checkpoint { pos = { -123.565, -785.028, 4.2556 } }
|
||||
checkpoint { pos = { 114.514, -730.95, 4.0023 } }
|
||||
checkpoint { pos = { 267.888, -668.781, 4.0181 } }
|
||||
checkpoint { pos = { 337.305, -509.17, 3.7381 } }
|
||||
checkpoint { pos = { 309.906, -407.719, 4.0468 } }
|
||||
checkpoint { pos = { 296.932, -253.16, 3.9989 } }
|
||||
checkpoint { pos = { 157.697, -234.079, 13.8108 } }
|
||||
checkpoint { pos = { 140.173, -389.505, 13.7984 } }
|
||||
checkpoint { pos = { 340.356, -415.681, 31.418 } }
|
||||
checkpoint { pos = { 566.093, -415.848, 39.5434 } }
|
||||
checkpoint { pos = { 909.641, -422.129, 36.4247 } }
|
||||
checkpoint { pos = { 1049.37, -416.408, 17.3975 } }
|
||||
checkpoint { pos = { 1091.72, -553.691, 12.5552 } }]]
|
@ -1,9 +0,0 @@
|
||||
resource_type 'gametype' { name = 'Race' }
|
||||
|
||||
dependencies {
|
||||
"spawnmanager",
|
||||
"mapmanager"
|
||||
}
|
||||
|
||||
client_script 'race_client.lua'
|
||||
server_script 'race_server.lua'
|
@ -1,469 +0,0 @@
|
||||
local curCheckpoint, nextCheckpoint
|
||||
local goGoGo
|
||||
|
||||
local playerCar
|
||||
local weFinished
|
||||
local resultsShown
|
||||
|
||||
local checkpoints = {}
|
||||
local playerScores = {}
|
||||
|
||||
local function initializeMap()
|
||||
echo("[RACE] initializeMap\n")
|
||||
|
||||
TriggerServerEvent('race:updateCheckpoints', checkpoints)
|
||||
end
|
||||
|
||||
local function resetGameMode()
|
||||
curCheckpoint = nil
|
||||
nextCheckpoint = nil
|
||||
|
||||
SetMultiplayerHudTime('')
|
||||
|
||||
checkpointCount = 0
|
||||
playerScores = {}
|
||||
|
||||
if IsThisMachineTheServer() then
|
||||
-- load the initial map
|
||||
initializeMap()
|
||||
end
|
||||
|
||||
goGoGo = false
|
||||
weFinished = false
|
||||
resultsShown = false
|
||||
end
|
||||
|
||||
local function updatePositions()
|
||||
local players = {}
|
||||
|
||||
for id, data in pairs(playerScores) do
|
||||
data.playerId = id
|
||||
|
||||
table.insert(players, data)
|
||||
end
|
||||
|
||||
table.sort(players, function(a, b)
|
||||
if a.finishPosition or b.finishPosition then
|
||||
if not b.finishPosition then
|
||||
return true
|
||||
end
|
||||
|
||||
if not a.finishPosition then
|
||||
return false
|
||||
end
|
||||
|
||||
return a.finishPosition < b.finishPosition
|
||||
end
|
||||
|
||||
if a.cp == b.cp then
|
||||
local aPed = a.ped
|
||||
local bPed = b.ped
|
||||
|
||||
local aPos
|
||||
local bPos
|
||||
|
||||
if not DoesCharExist(aPed) or not DoesCharExist(bPed) then
|
||||
aPos = { 0, 0 }
|
||||
bPos = { 0, 0 }
|
||||
else
|
||||
aPos = a.ped.position
|
||||
bPos = b.ped.position
|
||||
end
|
||||
|
||||
local nextCp = checkpoints[a.cp + 1]
|
||||
|
||||
if not nextCp then
|
||||
return a.cp > b.cp
|
||||
end
|
||||
|
||||
local aDist = GetDistanceBetweenCoords2d(aPos[1], aPos[2], nextCp.pos[1], nextCp.pos[2])
|
||||
local bDist = GetDistanceBetweenCoords2d(bPos[1], bPos[2], nextCp.pos[1], nextCp.pos[2])
|
||||
|
||||
return aDist < bDist
|
||||
end
|
||||
|
||||
return a.cp > b.cp
|
||||
end)
|
||||
|
||||
if not playerScores[GetPlayerId().serverId] then
|
||||
return
|
||||
end
|
||||
|
||||
local lastPosition = selfLastPosition
|
||||
|
||||
local i = 1
|
||||
|
||||
for _, v in ipairs(players) do
|
||||
playerScores[v.playerId].position = i
|
||||
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
local selfPosition = playerScores[GetPlayerId().serverId].position
|
||||
selfLastPosition = selfPosition
|
||||
|
||||
if selfPosition ~= lastPosition then
|
||||
TriggerEvent('chatMessage', '', { 0, 0, 0 }, 'position changed to ' .. tostring(selfPosition) .. ' from ' .. tostring(lastPosition))
|
||||
end
|
||||
|
||||
|
||||
-- positions updated, we hope
|
||||
end
|
||||
|
||||
AddEventHandler('race:onPlayerFinished', function(player, data)
|
||||
local selfId = GetPlayerId().serverId
|
||||
|
||||
if not playerScores[player] then
|
||||
local ped = sPlayer.ped
|
||||
|
||||
playerScores[player] = {
|
||||
cp = #checkpoints,
|
||||
ped = ped,
|
||||
vehicle = ped.vehicle
|
||||
}
|
||||
end
|
||||
|
||||
playerScores[player].finishPosition = data.position
|
||||
|
||||
if selfId == player then
|
||||
exports.obituary:printObituary('New world record!')
|
||||
|
||||
TriggerEvent('chatMessage', '', { 0, 0, 0 }, 'you finished!')
|
||||
|
||||
weFinished = true
|
||||
|
||||
tearDownCheckpoint(curCheckpoint)
|
||||
tearDownCheckpoint(nextCheckpoint)
|
||||
|
||||
-- todo: spectate?
|
||||
|
||||
CreateThread(function()
|
||||
Wait(500)
|
||||
|
||||
if playerCar then
|
||||
FreezeCarPosition(playerCar, true)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local sPlayer = GetPlayerByServerId(player)
|
||||
|
||||
if sPlayer then
|
||||
exports.obituary:printObituary('<b>%s</b> finished in %s seconds', sPlayer.name, tostring(data.finishSeconds))
|
||||
end
|
||||
end)
|
||||
|
||||
AddEventHandler('onClientGameTypeStart', function()
|
||||
CreateThread(function()
|
||||
--[[while true do
|
||||
Wait(500)
|
||||
|
||||
local player = GetPlayerId()
|
||||
|
||||
TriggerServerEvent('race:updatePos', player.ped.position)
|
||||
end]]
|
||||
end)
|
||||
|
||||
CreateThread(function()
|
||||
while true do
|
||||
Wait(250)
|
||||
|
||||
updatePositions()
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
function GetPlayerInteger(i)
|
||||
local serverId = i.serverId
|
||||
local players = GetPlayers()
|
||||
|
||||
for k, v in ipairs(players) do
|
||||
if v.serverId == serverId then
|
||||
return k
|
||||
end
|
||||
end
|
||||
|
||||
return 1
|
||||
end
|
||||
|
||||
local function spawnVehicle(spawnPoint)
|
||||
local carModel
|
||||
|
||||
if not spawnPoint.carModel then
|
||||
carModel = 'admiral'
|
||||
else
|
||||
carModel = spawnPoint.carModel
|
||||
end
|
||||
|
||||
if not tonumber(carModel) then
|
||||
carModel = GetHashKey(carModel, _r)
|
||||
end
|
||||
|
||||
-- is the model actually a model?
|
||||
if not IsModelInCdimage(carModel) then
|
||||
error("invalid spawn model")
|
||||
end
|
||||
|
||||
-- is is even a vehicle?
|
||||
if not IsThisModelAVehicle(carModel) then
|
||||
error("this model ain't a vehicle!")
|
||||
end
|
||||
|
||||
-- spawn a vehicle for our lovely player
|
||||
RequestModel(carModel)
|
||||
LoadAllObjectsNow()
|
||||
|
||||
playerCar = CreateCar(carModel, spawnPoint.x, spawnPoint.y, spawnPoint.z, 0, 1)
|
||||
SetCarHeading(playerCar, spawnPoint.heading)
|
||||
SetCarOnGroundProperly(playerCar)
|
||||
|
||||
WarpCharIntoCar(GetPlayerId().ped, playerCar)
|
||||
|
||||
if not goGoGo then
|
||||
FreezeCarPosition(playerCar, true)
|
||||
end
|
||||
|
||||
LockCarDoors(playerCar, 4)
|
||||
|
||||
-- and done, hopefully.
|
||||
end
|
||||
|
||||
AddEventHandler('race:itsGoTime', function()
|
||||
if playerCar then
|
||||
-- let go of the brakes
|
||||
FreezeCarPosition(playerCar, false)
|
||||
end
|
||||
|
||||
-- gogogo
|
||||
goGoGo = true
|
||||
end)
|
||||
|
||||
string.lpad = function(str, len, char)
|
||||
if char == nil then char = ' ' end
|
||||
return string.rep(char, len - #str) .. str
|
||||
end
|
||||
|
||||
AddEventHandler('race:results', function(time)
|
||||
if playerCar then
|
||||
FreezeCarPosition(playerCar, true)
|
||||
end
|
||||
|
||||
tearDownCheckpoint(curCheckpoint)
|
||||
tearDownCheckpoint(nextCheckpoint)
|
||||
|
||||
SetMultiplayerHudTime('')
|
||||
|
||||
updatePositions()
|
||||
|
||||
local players = {}
|
||||
|
||||
for id, data in pairs(playerScores) do
|
||||
table.insert(players, data)
|
||||
end
|
||||
|
||||
table.sort(players, function(a, b) return a.position < b.position end)
|
||||
|
||||
TriggerEvent('chatMessage', '', { 0, 0, 0 }, 'RESULTS')
|
||||
|
||||
for i, p in ipairs(players) do
|
||||
local name = '**INVALID**'
|
||||
local sp = GetPlayerByServerId(p.playerId)
|
||||
|
||||
if sp then
|
||||
name = sp.name
|
||||
end
|
||||
|
||||
TriggerEvent('chatMessage', '', { 0, 0, 0 }, tostring(i) .. '. ' .. name)
|
||||
end
|
||||
end)
|
||||
|
||||
AddEventHandler('race:hurryUp', function(time)
|
||||
CreateThread(function()
|
||||
echo("resultsShown: " .. tostring(resultsShown) .. " , weF: " .. tostring(weFinished) .. "\n")
|
||||
|
||||
while not resultsShown and not weFinished do
|
||||
Wait(1000)
|
||||
|
||||
time = time - 1000
|
||||
|
||||
SetMultiplayerHudTime('00:' .. tostring(math.floor(time / 1000)):lpad(2, '0'))
|
||||
echo(tostring(math.floor(time / 1000)):lpad(2, '0') .. ':' .. tostring(math.floor((time % 1000) / 100)):lpad(2, '0') .. "\n")
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
AddEventHandler('race:showGoMessage', function(message)
|
||||
TriggerEvent('chatMessage', '', { 0, 0, 0 }, message)
|
||||
end)
|
||||
|
||||
AddEventHandler('onClientMapStart', function(res)
|
||||
resetGameMode()
|
||||
|
||||
requestedGo = true
|
||||
|
||||
TriggerServerEvent('race:requestGo')
|
||||
end)
|
||||
|
||||
AddEventHandler('onClientMapStop', function(res)
|
||||
DoScreenFadeOut(50)
|
||||
end)
|
||||
|
||||
AddEventHandler('race:weGotPorn', function()
|
||||
echo("[RACE] race:weGotPorn\n")
|
||||
|
||||
if not requestedGo then
|
||||
return
|
||||
end
|
||||
|
||||
requestedGo = false
|
||||
|
||||
exports.spawnmanager:setAutoSpawn(false)
|
||||
|
||||
exports.spawnmanager:spawnPlayer(GetPlayerInteger(GetPlayerId()), function(spawnPoint)
|
||||
spawnVehicle(spawnPoint)
|
||||
end)
|
||||
|
||||
TriggerServerEvent('race:requestCheckpoint', '1234')
|
||||
end)
|
||||
|
||||
local function setUpCheckpoint(cp, next)
|
||||
local nextPos, typeNum
|
||||
|
||||
if next then
|
||||
nextPos = next.pos
|
||||
typeNum = 2
|
||||
else
|
||||
nextPos = { 0.0, 0.0, 0.0 }
|
||||
typeNum = 3
|
||||
end
|
||||
|
||||
-- 2 = regular 'ground', 3 = finish 'ground', others are different 3dmarker types
|
||||
cp.handle = CreateCheckpoint(typeNum, cp.pos[1], cp.pos[2], cp.pos[3] + 2.5, nextPos[1], nextPos[2], nextPos[3], 1.0001, _r)
|
||||
cp.blip = AddBlipForCoord(cp.pos[1], cp.pos[2], cp.pos[3], _i)
|
||||
|
||||
if cp == nextCheckpoint then
|
||||
ChangeBlipScale(cp.blip, 0.8)
|
||||
end
|
||||
|
||||
ChangeBlipSprite(cp.blip, 3)
|
||||
end
|
||||
|
||||
function tearDownCheckpoint(cp)
|
||||
if not cp then
|
||||
return
|
||||
end
|
||||
|
||||
if cp.blip then
|
||||
RemoveBlip(cp.blip)
|
||||
cp.blip = nil
|
||||
end
|
||||
|
||||
if cp.handle then
|
||||
DeleteCheckpoint(cp.handle)
|
||||
cp.handle = nil
|
||||
end
|
||||
end
|
||||
|
||||
AddEventHandler('race:setCheckpoint', function(cur, next, later)
|
||||
if curCheckpoint then
|
||||
tearDownCheckpoint(curCheckpoint)
|
||||
end
|
||||
|
||||
if nextCheckpoint then
|
||||
tearDownCheckpoint(nextCheckpoint)
|
||||
end
|
||||
|
||||
curCheckpoint = cur
|
||||
nextCheckpoint = next
|
||||
|
||||
if cur then
|
||||
setUpCheckpoint(curCheckpoint, nextCheckpoint)
|
||||
|
||||
-- make a background thread waiting for the checkpoint to be reached
|
||||
CreateThread(function()
|
||||
local localCur = curCheckpoint
|
||||
|
||||
-- so we exit if the checkpoint target is changed
|
||||
while curCheckpoint == localCur do
|
||||
Wait(25)
|
||||
|
||||
if playerCar then
|
||||
local px, py, pz = GetCarCoordinates(playerCar)
|
||||
local distance = GetDistanceBetweenCoords2d(px, py, localCur.pos[1], localCur.pos[2])
|
||||
|
||||
if distance < 10 then
|
||||
-- pass the fact we reached the checkpoint to the server
|
||||
TriggerServerEvent('race:gotCP', '1234')
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
if next then
|
||||
setUpCheckpoint(nextCheckpoint, later)
|
||||
end
|
||||
end)
|
||||
|
||||
AddEventHandler('race:confirmCP', function()
|
||||
PlayAudioEvent('FRONTEND_GAME_PICKUP_CHECKPOINT')
|
||||
end)
|
||||
|
||||
AddEventHandler('race:updateStatus', function(player, curCP)
|
||||
if curCP == -1 then
|
||||
playerScores[player] = nil
|
||||
end
|
||||
|
||||
local sPlayer = GetPlayerByServerId(player)
|
||||
|
||||
if not sPlayer then
|
||||
return
|
||||
end
|
||||
|
||||
local ped = sPlayer.ped
|
||||
|
||||
playerScores[player] = {
|
||||
cp = curCP,
|
||||
ped = ped,
|
||||
vehicle = ped.vehicle
|
||||
}
|
||||
|
||||
TriggerEvent('chatMessage', '', { 0, 0, 0 }, sPlayer.name .. ' now has cp ' .. curCP)
|
||||
|
||||
updatePositions()
|
||||
end)
|
||||
|
||||
AddEventHandler('onClientMapStop', function()
|
||||
if playerCar then
|
||||
MarkCarAsNoLongerNeeded(playerCar)
|
||||
playerCar = nil
|
||||
end
|
||||
|
||||
if curCheckpoint and curCheckpoint.handle then
|
||||
DeleteCheckpoint(curCheckpoint.handle)
|
||||
end
|
||||
|
||||
if nextCheckpoint and nextCheckpoint.handle then
|
||||
DeleteCheckpoint(nextCheckpoint.handle)
|
||||
end
|
||||
end)
|
||||
|
||||
AddEventHandler('getMapDirectives', function(add)
|
||||
-- call the remote callback
|
||||
add('checkpoint', function(state, data)
|
||||
table.insert(checkpoints, data)
|
||||
|
||||
state.add('pos', data.pos)
|
||||
|
||||
-- delete callback follows on the next line
|
||||
end, function(state, arg)
|
||||
for i, sp in ipairs(checkpoints) do
|
||||
if sp.pos[1] == state.pos[1] and sp.pos[2] == state.pos[2] and sp.pos[3] == state.pos[3] then
|
||||
table.remove(checkpoints, i)
|
||||
return
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
@ -1,209 +0,0 @@
|
||||
local checkpoints = {}
|
||||
local raceId = 0
|
||||
|
||||
RegisterServerEvent('race:updateCheckpoints')
|
||||
|
||||
AddEventHandler('race:updateCheckpoints', function(cps)
|
||||
if #checkpoints > 0 then
|
||||
return
|
||||
end
|
||||
|
||||
checkpoints = cps
|
||||
|
||||
TriggerClientEvent('race:weGotPorn', -1)
|
||||
end)
|
||||
|
||||
local playerData = {}
|
||||
|
||||
local function ensurePlayerData(id)
|
||||
if playerData[id] then
|
||||
return
|
||||
end
|
||||
|
||||
playerData[id] = {
|
||||
curCheckpoint = 0
|
||||
}
|
||||
end
|
||||
|
||||
local raceStarted = false
|
||||
local playerCount = 0
|
||||
|
||||
local function startRace()
|
||||
raceStarted = true
|
||||
|
||||
print("really starting race")
|
||||
|
||||
local function raceCountdown(num)
|
||||
local time = (4000 - (num * 1000))
|
||||
|
||||
print("setting countdown for " .. tostring(time))
|
||||
|
||||
SetTimeout(time, function()
|
||||
print("trig'd countdown for " .. tostring(time))
|
||||
|
||||
if num == 0 then
|
||||
TriggerClientEvent('race:itsGoTime', -1, 0)
|
||||
TriggerClientEvent('race:showGoMessage', -1, 'GO')
|
||||
else
|
||||
TriggerClientEvent('race:showGoMessage', -1, tostring(num))
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
raceCountdown(3) -- 3...
|
||||
raceCountdown(2) -- 2...
|
||||
raceCountdown(1) -- 1...
|
||||
raceCountdown(0) -- GOGOGO
|
||||
end
|
||||
|
||||
local function incrementPlayerCount()
|
||||
playerCount = playerCount + 1
|
||||
|
||||
if playerCount > 4 then
|
||||
startRace()
|
||||
end
|
||||
|
||||
if playerCount == 1 then
|
||||
SetTimeout(3000, function()
|
||||
if raceStarted then
|
||||
return
|
||||
end
|
||||
|
||||
print("starting race")
|
||||
|
||||
startRace()
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
local playersFinished
|
||||
local raceEnded
|
||||
|
||||
AddEventHandler('onMapStart', function()
|
||||
playerCount = 0
|
||||
playersFinished = 0
|
||||
raceId = raceId + 1
|
||||
raceStarted = false
|
||||
raceEnded = false
|
||||
|
||||
playerData = {}
|
||||
checkpoints = {}
|
||||
|
||||
print("mmmmmm race")
|
||||
end)
|
||||
|
||||
local function endRace()
|
||||
raceEnded = true
|
||||
|
||||
TriggerClientEvent('race:results', -1, '1234')
|
||||
|
||||
SetTimeout(7500, function()
|
||||
TriggerEvent('mapmanager:roundEnded')
|
||||
end)
|
||||
end
|
||||
|
||||
AddEventHandler('race:onPlayerFinished', function(player)
|
||||
print(GetPlayerName(player) .. ' finished')
|
||||
|
||||
local data = playerData[player]
|
||||
local finishSeconds = os.clock() - data.startTime
|
||||
|
||||
local position = playersFinished + 1
|
||||
data.position = position
|
||||
playersFinished = position
|
||||
|
||||
TriggerClientEvent('race:onPlayerFinished', -1, player, {
|
||||
finishSeconds = finishSeconds,
|
||||
position = position
|
||||
})
|
||||
|
||||
if playersFinished == playerCount then
|
||||
endRace()
|
||||
elseif playersFinished == 1 then
|
||||
local thisRaceId = raceId
|
||||
|
||||
TriggerClientEvent('race:hurryUp', -1, 30000)
|
||||
|
||||
SetTimeout(30000, function()
|
||||
if raceId ~= thisRaceId or raceEnded then
|
||||
return
|
||||
end
|
||||
|
||||
endRace()
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
AddEventHandler('playerActivated', function()
|
||||
if #checkpoints > 0 then
|
||||
TriggerClientEvent('race:weGotPorn', source)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterServerEvent('race:requestGo')
|
||||
|
||||
AddEventHandler('race:requestGo', function()
|
||||
if #checkpoints > 0 then
|
||||
TriggerClientEvent('race:weGotPorn', source)
|
||||
end
|
||||
end)
|
||||
|
||||
AddEventHandler('playerDropped', function(player)
|
||||
if playerData[player] and playerData[player].curCheckpoint > 0 then
|
||||
TriggerClientEvent('race:updateStatus', -1, player, -1)
|
||||
|
||||
playerCount = playerCount - 1
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterServerEvent('race:gotCP')
|
||||
|
||||
AddEventHandler('race:gotCP', function()
|
||||
ensurePlayerData(source)
|
||||
|
||||
local data = playerData[source]
|
||||
|
||||
local next = data.curCheckpoint + 1
|
||||
|
||||
if next > #checkpoints then
|
||||
print("omg finished")
|
||||
|
||||
TriggerEvent('race:onPlayerFinished', source)
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
data.curCheckpoint = next
|
||||
|
||||
TriggerClientEvent('race:confirmCP', source) -- for sound effects
|
||||
TriggerClientEvent('race:setCheckpoint', source, checkpoints[next], checkpoints[next + 1], checkpoints[next + 2])
|
||||
TriggerClientEvent('race:updateStatus', -1, source, next - 1)
|
||||
end)
|
||||
|
||||
RegisterServerEvent('race:requestCheckpoint')
|
||||
|
||||
AddEventHandler('race:requestCheckpoint', function()
|
||||
print('is it even in here')
|
||||
|
||||
ensurePlayerData(source)
|
||||
|
||||
print(source, 'requesting cp')
|
||||
|
||||
if playerData[source].curCheckpoint == 0 then
|
||||
incrementPlayerCount()
|
||||
|
||||
print(source, 'requesting cp 0')
|
||||
|
||||
local curCP = 1
|
||||
playerData[source].curCheckpoint = curCP
|
||||
playerData[source].startTime = os.clock()
|
||||
|
||||
TriggerClientEvent('race:setCheckpoint', source, checkpoints[curCP], checkpoints[curCP + 1], checkpoints[curCP + 2])
|
||||
TriggerClientEvent('race:updateStatus', -1, source, 0)
|
||||
|
||||
-- should have raceReallyStarted since 4-second countdown
|
||||
if raceStarted then
|
||||
TriggerClientEvent('race:itsGoTime', -1, 0)
|
||||
end
|
||||
end
|
||||
end)
|
@ -1,18 +0,0 @@
|
||||
description 'output lists for game content'
|
||||
|
||||
SetResourceInfo('uiPage', 'client/html/index.html')
|
||||
|
||||
client_script 'client/channelfeed.lua'
|
||||
|
||||
export 'printTo'
|
||||
export 'addChannel'
|
||||
export 'removeChannel'
|
||||
|
||||
files
|
||||
{
|
||||
'client/html/index.html',
|
||||
'client/html/feed.js',
|
||||
'client/html/feed.css',
|
||||
'client/fonts/roboto-regular.ttf',
|
||||
'client/fonts/roboto-condensed.ttf',
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
local eventBuffer = {}
|
||||
|
||||
AddUIHandler('getNew', function(data, cb)
|
||||
local localBuf = eventBuffer
|
||||
eventBuffer = {}
|
||||
|
||||
cb(localBuf)
|
||||
end)
|
||||
|
||||
function printTo(channel, data)
|
||||
table.insert(eventBuffer, {
|
||||
meta = 'print',
|
||||
channel = channel,
|
||||
data = data
|
||||
})
|
||||
|
||||
PollUI()
|
||||
end
|
||||
|
||||
function addChannel(id, options)
|
||||
if not options.template then
|
||||
return
|
||||
end
|
||||
|
||||
options.id = id
|
||||
|
||||
table.insert(eventBuffer, {
|
||||
meta = 'addChannel',
|
||||
data = options
|
||||
})
|
||||
|
||||
PollUI()
|
||||
end
|
||||
|
||||
function removeChannel(id)
|
||||
table.insert(eventBuffer, {
|
||||
meta = 'removeChannel',
|
||||
data = id
|
||||
})
|
||||
end
|
Binary file not shown.
Binary file not shown.
@ -1,118 +0,0 @@
|
||||
(function() {
|
||||
var getLock = 0;
|
||||
|
||||
var channels = {};
|
||||
|
||||
var zoomLevel = '100%';
|
||||
|
||||
$(function()
|
||||
{
|
||||
zoomLevel = Math.round(($(window).height() / 720) * 100) + '%'; // yay dynamic typing
|
||||
});
|
||||
|
||||
function refetchData()
|
||||
{
|
||||
getLock = 0;
|
||||
|
||||
$.get('http://channelfeed/getNew', function(data)
|
||||
{
|
||||
if (getLock > 1)
|
||||
{
|
||||
setTimeout(refetchData, 50);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
getLock++;
|
||||
|
||||
data.forEach(function(item)
|
||||
{
|
||||
switch (item.meta)
|
||||
{
|
||||
case 'print':
|
||||
var channel = item.channel;
|
||||
|
||||
if (!(channel in channels))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
channel = channels[channel];
|
||||
|
||||
var elem = $($.Mustache.render(item.channel, item.data, { method: channel.method })).appendTo(channel.$elem);
|
||||
|
||||
setTimeout(function()
|
||||
{
|
||||
elem.fadeOut(400, function()
|
||||
{
|
||||
elem.remove();
|
||||
});
|
||||
}, 7500);
|
||||
|
||||
break;
|
||||
|
||||
case 'addChannel':
|
||||
var channel = item.data;
|
||||
|
||||
if (channel.id in channels)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
channel.$elem = $('<div></div>').attr('id', 'channel-' + channel.id).appendTo('#channels');
|
||||
|
||||
if (channel.styles !== undefined)
|
||||
{
|
||||
channel.$elem.css(channel.styles);
|
||||
}
|
||||
|
||||
channel.$elem = $('<div></div>').css('zoom', zoomLevel).appendTo(channel.$elem);
|
||||
|
||||
if (channel.styleUrl !== undefined)
|
||||
{
|
||||
$('<link>').appendTo('head').attr({ type: 'text/css', rel: 'stylesheet' }).attr('href', channel.styleUrl);
|
||||
}
|
||||
|
||||
$.Mustache.add(channel.id, channel.template);
|
||||
|
||||
channels[channel.id] = channel;
|
||||
|
||||
break;
|
||||
case 'removeChannel':
|
||||
var channelId = item.data;
|
||||
|
||||
if (channelId in channels)
|
||||
{
|
||||
channel.$elem.parent().remove();
|
||||
|
||||
delete channels[channelId];
|
||||
}
|
||||
|
||||
break;
|
||||
case 'clear':
|
||||
var channel = item.channel;
|
||||
|
||||
if (!(channel in channels))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
channel = channels[channel];
|
||||
|
||||
channel.$elem.html();
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('message', function(event)
|
||||
{
|
||||
if (event.data.type != 'poll')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
refetchData();
|
||||
});
|
||||
})();
|
@ -1,13 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="nui://game/ui/jquery.js" type="text/javascript"></script>
|
||||
<script src="nui://game/ui/mustache.js" type="text/javascript"></script>
|
||||
<script src="nui://game/ui/jquery.mustache.js" type="text/javascript"></script>
|
||||
<script src="feed.js" type="text/javascript"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="channels">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -7,4 +7,7 @@ chat_theme 'gtao' {
|
||||
msgTemplates = {
|
||||
default = '<b>{0}</b><span>{1}</span>'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
game 'common'
|
||||
fx_version 'adamant'
|
@ -3,10 +3,10 @@
|
||||
}
|
||||
|
||||
.chat-window {
|
||||
--size: calc((((2.7vw / 1.77777) * 1.2)) * 6);
|
||||
--size: calc(((2.7vh * 1.2)) * 6);
|
||||
|
||||
position: absolute;
|
||||
right: calc(1.56vw);
|
||||
right: calc(2.77vh);
|
||||
top: calc(50% - (var(--size) / 2));
|
||||
height: var(--size) !important;
|
||||
|
||||
@ -33,10 +33,10 @@
|
||||
font-family: Font2, sans-serif;
|
||||
color: #fff;
|
||||
|
||||
font-size: calc(1.8vw / 1.77777); /* 13px in 720p, calc'd by width */
|
||||
font-size: calc(1.8vh); /* 13px in 720p, calc'd by width */
|
||||
filter: url(#svgDropShadowFilter);
|
||||
|
||||
line-height: calc((2.7vw / 1.77777) * 1.2);
|
||||
line-height: calc(2.7vh * 1.2);
|
||||
|
||||
margin-bottom: 0;
|
||||
}
|
||||
@ -55,7 +55,7 @@
|
||||
|
||||
line-height: 1;
|
||||
|
||||
font-size: calc(2.7vw / 1.77777); /* 13px in 720p, calc'd by width */
|
||||
font-size: calc(2.7vh);
|
||||
}
|
||||
|
||||
.msg > span > span > span {
|
||||
@ -69,8 +69,8 @@
|
||||
|
||||
.chat-input {
|
||||
position: absolute;
|
||||
right: calc(1.56vw);
|
||||
bottom: calc(1.56vw);
|
||||
right: calc(2.77vh);
|
||||
bottom: calc(2.77vh);
|
||||
|
||||
background: inherit !important;
|
||||
|
||||
@ -86,7 +86,7 @@
|
||||
|
||||
.chat-input > div {
|
||||
background-color: rgba(0, 0, 0, .6);
|
||||
padding: calc(0.15625vw / 2);
|
||||
padding: calc(0.28vh / 2);
|
||||
}
|
||||
|
||||
.chat-input .prefix {
|
||||
@ -97,20 +97,32 @@
|
||||
|
||||
.chat-input > div + div {
|
||||
position: absolute;
|
||||
bottom: calc(1.65vh + 0.15625vw + 0.15625vw + 0.15625vw + (0.15625vw / 2));
|
||||
bottom: calc(1.65vh + 0.28vh + 0.28vh + 0.28vh + (0.28vh / 2));
|
||||
width: 99.6%;
|
||||
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.suggestions {
|
||||
border: calc(0.15625vw / 2) solid rgba(180, 180, 180, .6);
|
||||
border: calc(0.28vh / 2) solid rgba(180, 180, 180, .6);
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
textarea {
|
||||
background: transparent;
|
||||
border: calc(0.15625vw / 2) solid rgba(180, 180, 180, .6);
|
||||
padding: calc(0.15625vw / 2);
|
||||
padding-left: calc(3.5% + (0.15625vw / 2));
|
||||
}
|
||||
border: calc(0.28vh / 2) solid rgba(180, 180, 180, .6);
|
||||
padding: calc(0.28vh / 2);
|
||||
padding-left: calc(3.5% + (0.28vh / 2));
|
||||
}
|
||||
|
||||
@media screen and (min-aspect-ratio: 21/9) {
|
||||
.chat-window, .chat-input {
|
||||
right: calc(12.8vw);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-aspect-ratio: 32/9) {
|
||||
.chat-window, .chat-input {
|
||||
right: calc(25vw);
|
||||
}
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
local isRDR = not TerraingridActivate and true or false
|
||||
|
||||
local chatInputActive = false
|
||||
local chatInputActivating = false
|
||||
local chatHidden = true
|
||||
@ -194,7 +196,7 @@ Citizen.CreateThread(function()
|
||||
Wait(0)
|
||||
|
||||
if not chatInputActive then
|
||||
if IsControlPressed(0, 245) --[[ INPUT_MP_TEXT_CHAT_ALL ]] then
|
||||
if IsControlPressed(0, isRDR and `INPUT_MP_TEXT_CHAT_ALL` or 245) --[[ INPUT_MP_TEXT_CHAT_ALL ]] then
|
||||
chatInputActive = true
|
||||
chatInputActivating = true
|
||||
|
||||
@ -205,7 +207,7 @@ Citizen.CreateThread(function()
|
||||
end
|
||||
|
||||
if chatInputActivating then
|
||||
if not IsControlPressed(0, 245) then
|
||||
if not IsControlPressed(0, isRDR and `INPUT_MP_TEXT_CHAT_ALL` or 245) then
|
||||
SetNuiFocus(true)
|
||||
|
||||
chatInputActivating = false
|
@ -1,26 +1,30 @@
|
||||
description 'chat management stuff'
|
||||
|
||||
ui_page 'html/index.html'
|
||||
|
||||
client_script 'cl_chat.lua'
|
||||
server_script 'sv_chat.lua'
|
||||
|
||||
files {
|
||||
'html/index.html',
|
||||
'html/index.css',
|
||||
'html/config.default.js',
|
||||
'html/config.js',
|
||||
'html/App.js',
|
||||
'html/Message.js',
|
||||
'html/Suggestions.js',
|
||||
'html/vendor/vue.2.3.3.min.js',
|
||||
'html/vendor/flexboxgrid.6.3.1.min.css',
|
||||
'html/vendor/animate.3.5.2.min.css',
|
||||
'html/vendor/latofonts.css',
|
||||
'html/vendor/fonts/LatoRegular.woff2',
|
||||
'html/vendor/fonts/LatoRegular2.woff2',
|
||||
'html/vendor/fonts/LatoLight2.woff2',
|
||||
'html/vendor/fonts/LatoLight.woff2',
|
||||
'html/vendor/fonts/LatoBold.woff2',
|
||||
'html/vendor/fonts/LatoBold2.woff2',
|
||||
}
|
||||
description 'chat management stuff'
|
||||
|
||||
ui_page 'html/index.html'
|
||||
|
||||
client_script 'cl_chat.lua'
|
||||
server_script 'sv_chat.lua'
|
||||
|
||||
files {
|
||||
'html/index.html',
|
||||
'html/index.css',
|
||||
'html/config.default.js',
|
||||
'html/config.js',
|
||||
'html/App.js',
|
||||
'html/Message.js',
|
||||
'html/Suggestions.js',
|
||||
'html/vendor/vue.2.3.3.min.js',
|
||||
'html/vendor/flexboxgrid.6.3.1.min.css',
|
||||
'html/vendor/animate.3.5.2.min.css',
|
||||
'html/vendor/latofonts.css',
|
||||
'html/vendor/fonts/LatoRegular.woff2',
|
||||
'html/vendor/fonts/LatoRegular2.woff2',
|
||||
'html/vendor/fonts/LatoLight2.woff2',
|
||||
'html/vendor/fonts/LatoLight.woff2',
|
||||
'html/vendor/fonts/LatoBold.woff2',
|
||||
'html/vendor/fonts/LatoBold2.woff2',
|
||||
}
|
||||
|
||||
fx_version 'adamant'
|
||||
games { 'rdr3', 'gta5' }
|
||||
rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.'
|
Binary file not shown.
@ -1 +0,0 @@
|
||||
server_script 'irc.lua'
|
@ -1,4 +0,0 @@
|
||||
local reflection = clr.System.Reflection
|
||||
local assembly = reflection.Assembly.LoadFrom('resources/[gameplay]/irc/ChatSharp.dll')
|
||||
|
||||
dofile('resources/[gameplay]/irc/irc_run.lua')
|
@ -1,91 +0,0 @@
|
||||
local chatSharp = clr.ChatSharp
|
||||
|
||||
local client = chatSharp.IrcClient('irc.rizon.net', chatSharp.IrcUser('citimate', 'mateyate'), false)
|
||||
|
||||
-- temporary workaround for connections that never triggered playerActivated but triggered playerDropped
|
||||
local activatedPlayers = {}
|
||||
|
||||
client.ConnectionComplete:add(function(s : object, e : System.EventArgs) : void
|
||||
client:JoinChannel('#meow')
|
||||
end)
|
||||
|
||||
-- why is 'received' even misspelled here?
|
||||
client.ChannelMessageRecieved:add(function(s : object, e : ChatSharp.Events.PrivateMessageEventArgs) : void
|
||||
local msg = e.PrivateMessage
|
||||
|
||||
TriggerClientEvent('chatMessage', -1, msg.User.Nick, { 0, 0x99, 255 }, msg.Message)
|
||||
end)
|
||||
|
||||
AddEventHandler('playerActivated', function()
|
||||
client:SendMessage('* ' .. GetPlayerName(source) .. '(' .. GetPlayerGuid(source) .. '@' .. GetPlayerEP(source) .. ') joined the server', '#fourdeltaone')
|
||||
table.insert(activatedPlayers, GetPlayerGuid(source))
|
||||
end)
|
||||
|
||||
AddEventHandler('playerDropped', function()
|
||||
-- find out if this connection ever triggered playerActivated
|
||||
for index,guid in pairs(activatedPlayers) do
|
||||
if guid == playerGuid then
|
||||
-- show player dropping connection in chat
|
||||
client:SendMessage('* ' .. GetPlayerName(source) .. '(' .. GetPlayerGuid(source) .. '@' .. GetPlayerEP(source) .. ') left the server', '#fourdeltaone')
|
||||
table.remove(activatedPlayers, index)
|
||||
return
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
AddEventHandler('chatMessage', function(source, name, message)
|
||||
print('hey there ' .. name)
|
||||
|
||||
local displayMessage = gsub(message, '^%d', '')
|
||||
|
||||
-- ignore zero-length messages
|
||||
if string.len(displayMessage) == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
-- ignore chat messages that are actually commands
|
||||
if string.sub(displayMessage, 1, 1) == "/" then
|
||||
return
|
||||
end
|
||||
|
||||
client:SendMessage('[' .. tostring(GetPlayerName(source)) .. ']: ' .. displayMessage, '#fourdeltaone')
|
||||
end)
|
||||
|
||||
AddEventHandler('onPlayerKilled', function(playerId, attackerId, reason, position)
|
||||
local player = GetPlayerByServerId(playerId)
|
||||
local attacker = GetPlayerByServerId(attackerId)
|
||||
|
||||
local reasonString = 'killed'
|
||||
|
||||
if reason == 0 or reason == 56 or reason == 1 or reason == 2 then
|
||||
reasonString = 'meleed'
|
||||
elseif reason == 3 then
|
||||
reasonString = 'knifed'
|
||||
elseif reason == 4 or reason == 6 or reason == 18 or reason == 51 then
|
||||
reasonString = 'bombed'
|
||||
elseif reason == 5 or reason == 19 then
|
||||
reasonString = 'burned'
|
||||
elseif reason == 7 or reason == 9 then
|
||||
reasonString = 'pistoled'
|
||||
elseif reason == 10 or reason == 11 then
|
||||
reasonString = 'shotgunned'
|
||||
elseif reason == 12 or reason == 13 or reason == 52 then
|
||||
reasonString = 'SMGd'
|
||||
elseif reason == 14 or reason == 15 or reason == 20 then
|
||||
reasonString = 'assaulted'
|
||||
elseif reason == 16 or reason == 17 then
|
||||
reasonString = 'sniped'
|
||||
elseif reason == 49 or reason == 50 then
|
||||
reasonString = 'ran over'
|
||||
end
|
||||
|
||||
client:SendMessage('* ' .. attacker.name .. ' ' .. reasonString .. ' ' .. player.name, '#fourdeltaone')
|
||||
end)
|
||||
|
||||
client:ConnectAsync()
|
||||
|
||||
AddEventHandler('onResourceStop', function(name)
|
||||
if name == GetInvokingResource() then
|
||||
client:Quit('Resource stopping.')
|
||||
end
|
||||
end)
|
@ -1,5 +0,0 @@
|
||||
dependency 'obituary'
|
||||
|
||||
description 'death messages using the obituary resource'
|
||||
|
||||
client_script 'deathmessages.lua'
|
@ -1,42 +0,0 @@
|
||||
AddEventHandler('onPlayerDied', function(playerId, reason, position)
|
||||
local player = GetPlayerByServerId(playerId)
|
||||
|
||||
if player then
|
||||
exports.obituary:printObituary('<b>%s</b> died.', player.name)
|
||||
end
|
||||
end)
|
||||
|
||||
AddEventHandler('onPlayerKilled', function(playerId, attackerId, reason, position)
|
||||
local player = GetPlayerByServerId(playerId)
|
||||
local attacker = GetPlayerByServerId(attackerId)
|
||||
|
||||
local reasonString = 'killed'
|
||||
|
||||
if reason == 0 or reason == 56 or reason == 1 or reason == 2 then
|
||||
reasonString = 'meleed'
|
||||
elseif reason == 3 then
|
||||
reasonString = 'knifed'
|
||||
elseif reason == 4 or reason == 6 or reason == 18 or reason == 51 then
|
||||
reasonString = 'bombed'
|
||||
elseif reason == 5 or reason == 19 then
|
||||
reasonString = 'burned'
|
||||
elseif reason == 7 or reason == 9 then
|
||||
reasonString = 'pistoled'
|
||||
elseif reason == 10 or reason == 11 then
|
||||
reasonString = 'shotgunned'
|
||||
elseif reason == 12 or reason == 13 or reason == 52 then
|
||||
reasonString = 'SMGd'
|
||||
elseif reason == 14 or reason == 15 or reason == 20 then
|
||||
reasonString = 'assaulted'
|
||||
elseif reason == 16 or reason == 17 then
|
||||
reasonString = 'sniped'
|
||||
elseif reason == 49 or reason == 50 then
|
||||
reasonString = 'ran over'
|
||||
end
|
||||
|
||||
echo("obituary-deaths: onPlayerKilled\n")
|
||||
|
||||
if player and attacker then
|
||||
exports.obituary:printObituary('<b>%s</b> %s <b>%s</b>.', attacker.name, reasonString, player.name)
|
||||
end
|
||||
end)
|
@ -1,7 +0,0 @@
|
||||
dependency 'channelfeed'
|
||||
|
||||
client_script 'obituary.lua'
|
||||
|
||||
export 'printObituary'
|
||||
|
||||
files 'obituary.css'
|
@ -1,46 +0,0 @@
|
||||
@font-face {
|
||||
font-family: 'Roboto Condensed';
|
||||
src: url('nui://channelfeed/client/fonts/roboto-condensed.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: url('nui://channelfeed/client/fonts/roboto-regular.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
#channel-obituary
|
||||
{
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#channel-obituary > div
|
||||
{
|
||||
width: 100%;
|
||||
|
||||
font-family: 'Roboto';
|
||||
}
|
||||
|
||||
#channel-obituary div.item
|
||||
{
|
||||
background-color: rgba(50, 50, 50, .6);
|
||||
padding: 4px;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
border-radius: 4px;
|
||||
color: #eee;
|
||||
margin-bottom: 3px;
|
||||
|
||||
font-size: 65%;
|
||||
}
|
||||
|
||||
#channel-obituary div.item b
|
||||
{
|
||||
font-family: 'Roboto Condensed';
|
||||
font-size: 125%;
|
||||
font-weight: normal;
|
||||
color: #09f;
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
AddEventHandler('onClientResourceStart', function(name)
|
||||
if name == GetCurrentResource() then
|
||||
local x, y = GetHudPosition('HUD_RADAR')
|
||||
local w, h = GetHudSize('HUD_RADAR')
|
||||
|
||||
x = x - 0.01
|
||||
w = w + 0.02
|
||||
|
||||
if GetIsWidescreen() then
|
||||
x = x / 1.333
|
||||
w = w / 1.333
|
||||
end
|
||||
|
||||
exports.channelfeed:addChannel('obituary', {
|
||||
method = 'append',
|
||||
styleUrl = 'nui://obituary/obituary.css',
|
||||
styles = { -- temporary
|
||||
left = tostring(x * 100) .. '%',
|
||||
bottom = 'calc(' .. tostring((1 - y) * 100) .. '% + 10px)',
|
||||
width = tostring(w * 100) .. '%'
|
||||
},
|
||||
template = '<div class="item">{{{text}}}</div>'
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
function printObituary(format, ...)
|
||||
local args = table.pack(...)
|
||||
|
||||
for i = 1, args.n do
|
||||
if type(args[i]) == 'string' then
|
||||
args[i] = args[i]:gsub('<', '<')
|
||||
end
|
||||
end
|
||||
|
||||
echo("obituary: printObituary\n")
|
||||
|
||||
exports.channelfeed:printTo('obituary', {
|
||||
text = string.format(format, table.unpack(args))
|
||||
})
|
||||
end
|
||||
|
||||
--[[AddEventHandler('chatMessage', function(name, color, message)
|
||||
exports.channelfeed:printTo('obituary', {
|
||||
text = message:gsub('<', '<')
|
||||
})
|
||||
end)]]
|
||||
|
||||
AddEventHandler('onClientResourceStop', function()
|
||||
-- todo: remove channel
|
||||
end)
|
@ -24,4 +24,5 @@ files {
|
||||
}
|
||||
|
||||
-- support the latest resource manifest
|
||||
resource_manifest_version '05cfa83c-a124-4cfa-a768-c24a5811d8f9'
|
||||
fx_version 'adamant'
|
||||
game 'gta5'
|
0
resources/[local]/.gitkeep
Normal file
0
resources/[local]/.gitkeep
Normal file
@ -8,7 +8,8 @@ server_scripts {
|
||||
"mapmanager_server.lua"
|
||||
}
|
||||
|
||||
resource_manifest_version "77731fab-63ca-442c-a67b-abc70f28dfa5"
|
||||
fx_version 'adamant'
|
||||
games { 'gta5', 'rdr3' }
|
||||
|
||||
server_export "getCurrentGameType"
|
||||
server_export "getCurrentMap"
|
||||
@ -16,4 +17,6 @@ server_export "changeGameType"
|
||||
server_export "changeMap"
|
||||
server_export "doesMapSupportGameType"
|
||||
server_export "getMaps"
|
||||
server_export "roundEnded"
|
||||
server_export "roundEnded"
|
||||
|
||||
rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.'
|
@ -62,6 +62,10 @@ AddEventHandler('onResourceStop', function(res)
|
||||
end)
|
||||
|
||||
AddEventHandler('getMapDirectives', function(add)
|
||||
if not CreateScriptVehicleGenerator then
|
||||
return
|
||||
end
|
||||
|
||||
add('vehicle_generator', function(state, name)
|
||||
return function(opts)
|
||||
local x, y, z, heading
|
||||
|
@ -12,12 +12,27 @@ local function refreshResources()
|
||||
if GetNumResourceMetadata(resource, 'resource_type') > 0 then
|
||||
local type = GetResourceMetadata(resource, 'resource_type', 0)
|
||||
local params = json.decode(GetResourceMetadata(resource, 'resource_type_extra', 0))
|
||||
|
||||
if type == 'map' then
|
||||
maps[resource] = params
|
||||
elseif type == 'gametype' then
|
||||
gametypes[resource] = params
|
||||
|
||||
local valid = false
|
||||
|
||||
local games = GetNumResourceMetadata(resource, 'game')
|
||||
if games > 0 then
|
||||
for j = 0, games - 1 do
|
||||
local game = GetResourceMetadata(resource, 'game', j)
|
||||
|
||||
if game == GetConvar('gamename', 'gta5') or game == 'common' then
|
||||
valid = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if valid then
|
||||
if type == 'map' then
|
||||
maps[resource] = params
|
||||
elseif type == 'gametype' then
|
||||
gametypes[resource] = params
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -8,3 +8,8 @@ export 'loadSpawns'
|
||||
export 'setAutoSpawn'
|
||||
export 'setAutoSpawnCallback'
|
||||
export 'forceRespawn'
|
||||
|
||||
fx_version 'adamant'
|
||||
games { 'rdr3', 'gta5' }
|
||||
|
||||
rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.'
|
@ -187,6 +187,10 @@ local function freezePlayer(id, freeze)
|
||||
end
|
||||
|
||||
function loadScene(x, y, z)
|
||||
if not NewLoadSceneStart then
|
||||
return
|
||||
end
|
||||
|
||||
NewLoadSceneStart(x, y, z, 0.0, 0.0, 0.0, 20.0, 0)
|
||||
|
||||
while IsNewLoadSceneActive() do
|
||||
@ -258,14 +262,18 @@ function spawnPlayer(spawnIdx, cb)
|
||||
|
||||
-- release the player model
|
||||
SetModelAsNoLongerNeeded(spawn.model)
|
||||
|
||||
-- RDR3 player model bits
|
||||
if N_0x283978a15512b2fe then
|
||||
N_0x283978a15512b2fe(PlayerPedId(), true)
|
||||
end
|
||||
end
|
||||
|
||||
-- preload collisions for the spawnpoint
|
||||
RequestCollisionAtCoord(spawn.x, spawn.y, spawn.z)
|
||||
|
||||
-- spawn the player
|
||||
--ResurrectNetworkPlayer(GetPlayerId(), spawn.x, spawn.y, spawn.z, spawn.heading)
|
||||
local ped = GetPlayerPed(-1)
|
||||
local ped = PlayerPedId()
|
||||
|
||||
-- V requires setting coords as well
|
||||
SetEntityCoordsNoOffset(ped, spawn.x, spawn.y, spawn.z, false, false, false, true)
|
||||
@ -328,7 +336,7 @@ Citizen.CreateThread(function()
|
||||
while true do
|
||||
Citizen.Wait(50)
|
||||
|
||||
local playerPed = GetPlayerPed(-1)
|
||||
local playerPed = PlayerPedId()
|
||||
|
||||
if playerPed and playerPed ~= -1 then
|
||||
-- check if we want to autospawn
|
@ -1,3 +0,0 @@
|
||||
dependency 'yarn'
|
||||
--server_only 'yes'
|
||||
server_script 'webpack_builder.js'
|
5
resources/[system]/[builders]/webpack/fxmanifest.lua
Normal file
5
resources/[system]/[builders]/webpack/fxmanifest.lua
Normal file
@ -0,0 +1,5 @@
|
||||
dependency 'yarn'
|
||||
server_script 'webpack_builder.js'
|
||||
|
||||
fx_version 'adamant'
|
||||
game 'common'
|
@ -1,2 +0,0 @@
|
||||
--server_only 'yes'
|
||||
server_script 'yarn_builder.js'
|
4
resources/[system]/[builders]/yarn/fxmanifest.lua
Normal file
4
resources/[system]/[builders]/yarn/fxmanifest.lua
Normal file
@ -0,0 +1,4 @@
|
||||
fx_version 'adamant'
|
||||
game 'common'
|
||||
|
||||
server_script 'yarn_builder.js'
|
@ -41,7 +41,7 @@ const yarnBuildTask = {
|
||||
currentBuildingModule = resourceName;
|
||||
const process = child_process.fork(
|
||||
require.resolve('./yarn_cli.js'),
|
||||
['install'],
|
||||
['install', '--ignore-scripts'],
|
||||
{
|
||||
cwd: path.resolve(GetResourcePath(resourceName))
|
||||
});
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,2 +0,0 @@
|
||||
client_script 'client.lua'
|
||||
server_script 'server.lua'
|
6
resources/[system]/hardcap/fxmanifest.lua
Normal file
6
resources/[system]/hardcap/fxmanifest.lua
Normal file
@ -0,0 +1,6 @@
|
||||
client_script 'client.lua'
|
||||
server_script 'server.lua'
|
||||
|
||||
fx_version 'adamant'
|
||||
games { 'gta5', 'rdr3' }
|
||||
rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.'
|
@ -1,2 +0,0 @@
|
||||
client_script 'rconlog_client.lua'
|
||||
server_script 'rconlog_server.lua'
|
7
resources/[system]/rconlog/fxmanifest.lua
Normal file
7
resources/[system]/rconlog/fxmanifest.lua
Normal file
@ -0,0 +1,7 @@
|
||||
client_script 'rconlog_client.lua'
|
||||
server_script 'rconlog_server.lua'
|
||||
|
||||
fx_version 'adamant'
|
||||
games { 'gta5', 'rdr3' }
|
||||
|
||||
rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.'
|
@ -15,4 +15,7 @@ files {
|
||||
'html/res/futurastd-medium.woff',
|
||||
'html/res/futurastd-medium.ttf',
|
||||
'html/res/futurastd-medium.svg',
|
||||
}
|
||||
}
|
||||
|
||||
fx_version 'adamant'
|
||||
game 'gta5'
|
@ -8,7 +8,7 @@ Citizen.CreateThread(function()
|
||||
if IsControlPressed(0, 27)--[[ INPUT_PHONE ]] then
|
||||
if not listOn then
|
||||
local players = {}
|
||||
ptable = GetPlayers()
|
||||
local ptable = GetActivePlayers()
|
||||
for _, i in ipairs(ptable) do
|
||||
local wantedLevel = GetPlayerWantedLevel(i)
|
||||
r, g, b = GetPlayerRgbColour(i)
|
||||
@ -35,18 +35,6 @@ Citizen.CreateThread(function()
|
||||
end
|
||||
end)
|
||||
|
||||
function GetPlayers()
|
||||
local players = {}
|
||||
|
||||
for i = 0, 31 do
|
||||
if NetworkIsPlayerActive(i) then
|
||||
table.insert(players, i)
|
||||
end
|
||||
end
|
||||
|
||||
return players
|
||||
end
|
||||
|
||||
function sanitize(txt)
|
||||
local replacements = {
|
||||
['&' ] = '&',
|
||||
|
2
resources/[system]/sessionmanager-rdr3/.gitignore
vendored
Normal file
2
resources/[system]/sessionmanager-rdr3/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
node_modules/
|
||||
yarn.lock
|
8
resources/[system]/sessionmanager-rdr3/fxmanifest.lua
Normal file
8
resources/[system]/sessionmanager-rdr3/fxmanifest.lua
Normal file
@ -0,0 +1,8 @@
|
||||
fx_version 'adamant'
|
||||
game 'common'
|
||||
|
||||
dependencies {
|
||||
'yarn'
|
||||
}
|
||||
|
||||
server_script 'sm_server.js'
|
6
resources/[system]/sessionmanager-rdr3/package.json
Normal file
6
resources/[system]/sessionmanager-rdr3/package.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@citizenfx/protobufjs": "6.8.8"
|
||||
}
|
||||
}
|
169
resources/[system]/sessionmanager-rdr3/rline.proto
Normal file
169
resources/[system]/sessionmanager-rdr3/rline.proto
Normal file
@ -0,0 +1,169 @@
|
||||
syntax = "proto3";
|
||||
package rline;
|
||||
|
||||
message RpcErrorData {
|
||||
string ErrorCodeString = 1;
|
||||
int32 ErrorCode = 2;
|
||||
string DomainString = 3;
|
||||
int32 DomainCode = 4;
|
||||
bytes DataEx = 5;
|
||||
};
|
||||
|
||||
message RpcError {
|
||||
int32 ErrorCode = 1;
|
||||
string ErrorMessage = 2;
|
||||
RpcErrorData Data = 3;
|
||||
};
|
||||
|
||||
message RpcHeader {
|
||||
string RequestId = 1;
|
||||
string MethodName = 2;
|
||||
RpcError Error = 3;
|
||||
string srcTid = 4;
|
||||
};
|
||||
|
||||
message RpcMessage {
|
||||
RpcHeader Header = 1;
|
||||
bytes Content = 2;
|
||||
};
|
||||
|
||||
message RpcResponseContainer {
|
||||
bytes Content = 1;
|
||||
};
|
||||
|
||||
message RpcResponseMessage {
|
||||
RpcHeader Header = 1;
|
||||
RpcResponseContainer Container = 2;
|
||||
};
|
||||
|
||||
message TokenStuff {
|
||||
string tkn = 1;
|
||||
};
|
||||
|
||||
message InitSessionResponse {
|
||||
bytes sesid = 1;
|
||||
TokenStuff token = 2;
|
||||
};
|
||||
|
||||
message MpGamerHandleDto {
|
||||
string gh = 1;
|
||||
};
|
||||
|
||||
message MpPeerAddressDto {
|
||||
string addr = 1;
|
||||
};
|
||||
|
||||
message InitPlayer2_Parameters {
|
||||
MpGamerHandleDto gh = 1;
|
||||
MpPeerAddressDto peerAddress = 2;
|
||||
int32 discriminator = 3;
|
||||
int32 seamlessType = 4;
|
||||
uint32 connectionReason = 5;
|
||||
};
|
||||
|
||||
message InitPlayerResult {
|
||||
uint32 code = 1;
|
||||
};
|
||||
|
||||
message Restriction {
|
||||
int32 u1 = 1;
|
||||
int32 u2 = 2;
|
||||
int32 u3 = 3;
|
||||
}
|
||||
|
||||
message GetRestrictionsData {
|
||||
repeated Restriction restriction = 1;
|
||||
repeated string unk2 = 2;
|
||||
};
|
||||
|
||||
message GetRestrictionsResult {
|
||||
GetRestrictionsData data = 1;
|
||||
};
|
||||
|
||||
message PlayerIdSto {
|
||||
int32 acctId = 1;
|
||||
int32 platId = 2;
|
||||
};
|
||||
|
||||
message MpSessionRequestIdDto {
|
||||
PlayerIdSto requestor = 1;
|
||||
int32 index = 2;
|
||||
int32 hash = 3;
|
||||
};
|
||||
|
||||
message QueueForSession_Seamless_Parameters {
|
||||
MpSessionRequestIdDto requestId = 1;
|
||||
uint32 optionFlags = 2;
|
||||
int32 x = 3;
|
||||
int32 y = 4;
|
||||
};
|
||||
|
||||
message QueueForSessionResult {
|
||||
uint32 code = 1;
|
||||
};
|
||||
|
||||
message QueueEntered_Parameters {
|
||||
uint32 queueGroup = 1;
|
||||
MpSessionRequestIdDto requestId = 2;
|
||||
uint32 optionFlags = 3;
|
||||
};
|
||||
|
||||
message GuidDto {
|
||||
fixed64 a = 1;
|
||||
fixed64 b = 2;
|
||||
};
|
||||
|
||||
message MpTransitionIdDto {
|
||||
GuidDto value = 1;
|
||||
};
|
||||
|
||||
message MpSessionIdDto {
|
||||
GuidDto value = 1;
|
||||
};
|
||||
|
||||
message SessionSubcommandEnterSession {
|
||||
int32 index = 1;
|
||||
int32 hindex = 2;
|
||||
uint32 sessionFlags = 3;
|
||||
uint32 mode = 4;
|
||||
int32 size = 5;
|
||||
int32 teamIndex = 6;
|
||||
MpTransitionIdDto transitionId = 7;
|
||||
uint32 sessionManagerType = 8;
|
||||
int32 slotCount = 9;
|
||||
};
|
||||
|
||||
message SessionSubcommandLeaveSession {
|
||||
uint32 reason = 1;
|
||||
};
|
||||
|
||||
message SessionSubcommandAddPlayer {
|
||||
PlayerIdSto id = 1;
|
||||
MpGamerHandleDto gh = 2;
|
||||
MpPeerAddressDto addr = 3;
|
||||
int32 index = 4;
|
||||
};
|
||||
|
||||
message SessionSubcommandRemovePlayer {
|
||||
PlayerIdSto id = 1;
|
||||
};
|
||||
|
||||
message SessionSubcommandHostChanged {
|
||||
int32 index = 1;
|
||||
};
|
||||
|
||||
message SessionCommand {
|
||||
uint32 cmd = 1;
|
||||
string cmdname = 2;
|
||||
SessionSubcommandEnterSession EnterSession = 3;
|
||||
SessionSubcommandLeaveSession LeaveSession = 4;
|
||||
SessionSubcommandAddPlayer AddPlayer = 5;
|
||||
SessionSubcommandRemovePlayer RemovePlayer = 6;
|
||||
SessionSubcommandHostChanged HostChanged = 7;
|
||||
};
|
||||
|
||||
message scmds_Parameters {
|
||||
MpSessionIdDto sid = 1;
|
||||
int32 ncmds = 2;
|
||||
repeated SessionCommand cmds = 3;
|
||||
};
|
276
resources/[system]/sessionmanager-rdr3/sm_server.js
Normal file
276
resources/[system]/sessionmanager-rdr3/sm_server.js
Normal file
@ -0,0 +1,276 @@
|
||||
const protobuf = require("@citizenfx/protobufjs");
|
||||
|
||||
const playerDatas = {};
|
||||
let slotsUsed = 0;
|
||||
|
||||
function assignSlotId() {
|
||||
for (let i = 0; i < 32; i++) {
|
||||
if (!(slotsUsed & (1 << i))) {
|
||||
slotsUsed |= (1 << i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
let hostIndex = -1;
|
||||
|
||||
protobuf.load(GetResourcePath(GetCurrentResourceName()) + "/rline.proto", function(err, root) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
return;
|
||||
}
|
||||
|
||||
const RpcMessage = root.lookupType("rline.RpcMessage");
|
||||
const RpcResponseMessage = root.lookupType("rline.RpcResponseMessage");
|
||||
const InitSessionResponse = root.lookupType("rline.InitSessionResponse");
|
||||
const InitPlayer2_Parameters = root.lookupType("rline.InitPlayer2_Parameters");
|
||||
const InitPlayerResult = root.lookupType("rline.InitPlayerResult");
|
||||
const GetRestrictionsResult = root.lookupType("rline.GetRestrictionsResult");
|
||||
const QueueForSession_Seamless_Parameters = root.lookupType("rline.QueueForSession_Seamless_Parameters");
|
||||
const QueueForSessionResult = root.lookupType("rline.QueueForSessionResult");
|
||||
const QueueEntered_Parameters = root.lookupType("rline.QueueEntered_Parameters");
|
||||
const scmds_Parameters = root.lookupType("rline.scmds_Parameters");
|
||||
|
||||
function toArrayBuffer(buf) {
|
||||
var ab = new ArrayBuffer(buf.length);
|
||||
var view = new Uint8Array(ab);
|
||||
for (var i = 0; i < buf.length; ++i) {
|
||||
view[i] = buf[i];
|
||||
}
|
||||
return ab;
|
||||
}
|
||||
|
||||
function emitMsg(target, data) {
|
||||
emitNet('__cfx_internal:pbRlScSession', target, toArrayBuffer(data));
|
||||
}
|
||||
|
||||
function emitSessionCmds(target, cmd, cmdname, msg) {
|
||||
const stuff = {};
|
||||
stuff[cmdname] = msg;
|
||||
|
||||
emitMsg(target, RpcMessage.encode({
|
||||
Header: {
|
||||
MethodName: 'scmds'
|
||||
},
|
||||
Content: scmds_Parameters.encode({
|
||||
sid: {
|
||||
value: {
|
||||
a: 2,
|
||||
b: 2
|
||||
}
|
||||
},
|
||||
ncmds: 1,
|
||||
cmds: [
|
||||
{
|
||||
cmd,
|
||||
cmdname,
|
||||
...stuff
|
||||
}
|
||||
]
|
||||
}).finish()
|
||||
}).finish());
|
||||
}
|
||||
|
||||
function emitAddPlayer(target, msg) {
|
||||
emitSessionCmds(target, 2, 'AddPlayer', msg);
|
||||
}
|
||||
|
||||
function emitRemovePlayer(target, msg) {
|
||||
emitSessionCmds(target, 3, 'RemovePlayer', msg);
|
||||
}
|
||||
|
||||
function emitHostChanged(target, msg) {
|
||||
emitSessionCmds(target, 5, 'HostChanged', msg);
|
||||
}
|
||||
|
||||
onNet('playerDropped', () => {
|
||||
try {
|
||||
const oData = playerDatas[source];
|
||||
delete playerDatas[source];
|
||||
|
||||
if (oData && hostIndex === oData.slot) {
|
||||
const pda = Object.entries(playerDatas);
|
||||
|
||||
if (pda.length > 0) {
|
||||
hostIndex = pda[0][1].slot | 0; // TODO: actually use <=31 slot index *and* check for id
|
||||
|
||||
for (const [ id, data ] of Object.entries(playerDatas)) {
|
||||
emitHostChanged(id, {
|
||||
index: hostIndex
|
||||
});
|
||||
}
|
||||
} else {
|
||||
hostIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!oData) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (oData.slot > -1) {
|
||||
slotsUsed &= ~(1 << oData.slot);
|
||||
}
|
||||
|
||||
for (const [ id, data ] of Object.entries(playerDatas)) {
|
||||
emitRemovePlayer(id, {
|
||||
id: oData.id
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
console.log(e.stack);
|
||||
}
|
||||
});
|
||||
|
||||
function makeResponse(type, data) {
|
||||
return {
|
||||
Header: {
|
||||
},
|
||||
Container: {
|
||||
Content: type.encode(data).finish()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const handlers = {
|
||||
async InitSession(source, data) {
|
||||
return makeResponse(InitSessionResponse, {
|
||||
sesid: Buffer.alloc(16),
|
||||
/*token: {
|
||||
tkn: 'ACSTOKEN token="meow",signature="meow"'
|
||||
}*/
|
||||
});
|
||||
},
|
||||
|
||||
async InitPlayer2(source, data) {
|
||||
const req = InitPlayer2_Parameters.decode(data);
|
||||
|
||||
playerDatas[source] = {
|
||||
gh: req.gh,
|
||||
peerAddress: req.peerAddress,
|
||||
discriminator: req.discriminator,
|
||||
slot: -1
|
||||
};
|
||||
|
||||
return makeResponse(InitPlayerResult, {
|
||||
code: 0
|
||||
});
|
||||
},
|
||||
|
||||
async GetRestrictions(source, data) {
|
||||
return makeResponse(GetRestrictionsResult, {
|
||||
data: {
|
||||
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
async ConfirmSessionEntered(source, data) {
|
||||
return {};
|
||||
},
|
||||
|
||||
async QueueForSession_Seamless(source, data) {
|
||||
const req = QueueForSession_Seamless_Parameters.decode(data);
|
||||
|
||||
playerDatas[source].req = req.requestId;
|
||||
playerDatas[source].id = req.requestId.requestor;
|
||||
playerDatas[source].slot = assignSlotId();
|
||||
|
||||
setTimeout(() => {
|
||||
emitMsg(source, RpcMessage.encode({
|
||||
Header: {
|
||||
MethodName: 'QueueEntered'
|
||||
},
|
||||
Content: QueueEntered_Parameters.encode({
|
||||
queueGroup: 69,
|
||||
requestId: req.requestId,
|
||||
optionFlags: req.optionFlags
|
||||
}).finish()
|
||||
}).finish());
|
||||
|
||||
if (hostIndex === -1) {
|
||||
hostIndex = playerDatas[source].slot | 0;
|
||||
}
|
||||
|
||||
emitSessionCmds(source, 0, 'EnterSession', {
|
||||
index: playerDatas[source].slot | 0,
|
||||
hindex: hostIndex,
|
||||
sessionFlags: 0,
|
||||
mode: 0,
|
||||
size: Object.entries(playerDatas).filter(a => a[1].id).length,
|
||||
//size: 2,
|
||||
//size: Object.entries(playerDatas).length,
|
||||
teamIndex: 0,
|
||||
transitionId: {
|
||||
value: {
|
||||
a: 0,//2,
|
||||
b: 0
|
||||
}
|
||||
},
|
||||
sessionManagerType: 0,
|
||||
slotCount: 32
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
// tell player about everyone, and everyone about player
|
||||
const meData = playerDatas[source];
|
||||
|
||||
const aboutMe = {
|
||||
id: meData.id,
|
||||
gh: meData.gh,
|
||||
addr: meData.peerAddress,
|
||||
index: playerDatas[source].slot | 0
|
||||
};
|
||||
|
||||
for (const [ id, data ] of Object.entries(playerDatas)) {
|
||||
if (id == source || !data.id) continue;
|
||||
|
||||
emitAddPlayer(source, {
|
||||
id: data.id,
|
||||
gh: data.gh,
|
||||
addr: data.peerAddress,
|
||||
index: data.slot | 0
|
||||
});
|
||||
|
||||
emitAddPlayer(id, aboutMe);
|
||||
}
|
||||
}, 150);
|
||||
}, 50);
|
||||
|
||||
return makeResponse(QueueForSessionResult, {
|
||||
code: 1
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
async function handleMessage(source, method, data) {
|
||||
if (handlers[method]) {
|
||||
return await handlers[method](source, data);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
onNet('__cfx_internal:pbRlScSession', async (data) => {
|
||||
const s = source;
|
||||
|
||||
try {
|
||||
const message = RpcMessage.decode(new Uint8Array(data));
|
||||
const response = await handleMessage(s, message.Header.MethodName, message.Content);
|
||||
|
||||
if (!response || !response.Header) {
|
||||
return;
|
||||
}
|
||||
|
||||
response.Header.RequestId = message.Header.RequestId;
|
||||
|
||||
emitMsg(s, RpcResponseMessage.encode(response).finish());
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
console.log(e.stack);
|
||||
}
|
||||
});
|
||||
});
|
@ -1,2 +0,0 @@
|
||||
client_script 'client.lua'
|
||||
server_script 'server.lua'
|
@ -1,208 +0,0 @@
|
||||
local function getPickupType(i)
|
||||
if i == 2 then
|
||||
return 30
|
||||
elseif i == 1 then
|
||||
return 31
|
||||
end
|
||||
|
||||
local w = GenerateRandomIntInRange(5, 17, _i)
|
||||
|
||||
if w == 8 or w == 6 then
|
||||
w = 4
|
||||
end
|
||||
|
||||
return w
|
||||
end
|
||||
|
||||
local function createPickup(ptype, etype, unk, x, y, z)
|
||||
if ptype == 30 then
|
||||
CreatePickupWithAmmo(0x972daa10, etype, 0, x, y, z, _i)
|
||||
elseif ptype == 31 then
|
||||
CreatePickupWithAmmo(0x3fc62578, etype, 0, x, y, z, _i)
|
||||
else
|
||||
CreatePickupWithAmmo(GetWeapontypeModel(ptype, _i), etype, 60, x, y, z, _i)
|
||||
end
|
||||
end
|
||||
|
||||
local pickupSeed
|
||||
|
||||
local function createPickups()
|
||||
echo("creating algo pickups\n")
|
||||
|
||||
SetRandomSeed(pickupSeed)
|
||||
|
||||
createPickup( getPickupType( 2 ), 23, 200, -563.10640000, 293.52680000, 5.65930000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, 79.41570000, -839.53680000, 3.99560000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, -277.35550000, -533.76340000, 3.92420000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, -491.51540000, -173.97790000, 6.90340000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, -235.68930000, 739.30850000, 6.12510000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, -539.49120000, 1362.38800000, 16.47050000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, -180.02360000, -823.41240000, 4.11750000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, 173.60920000, 236.49170000, 13.76010000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, 89.24590000, 1152.34900000, 13.57080000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, 63.60470000, -439.60590000, 13.75830000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, -226.95040000, 1714.70300000, 14.75500000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, 130.44570000, 467.39240000, 13.91780000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, -529.52310000, -339.29980000, 5.04460000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, -477.98870000, 1707.35300000, 7.46380000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, -636.54130000, -45.71210000, 3.81230000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, 140.68720000, -857.79680000, 3.77320000 )
|
||||
--createPickup( getPickupType( 2 ), 23, 200, -108.89000000, 64499, 4.11910000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, 348.54010000, -431.52940000, 3.54320000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, 166.63900000, 1080.60900000, 13.62470000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, -145.57280000, 1694.71300000, 15.72350000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, 64.54370000, 261.20720000, 14.53200000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, -507.19360000, 533.97330000, 5.67160000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, -410.23560000, -141.84080000, 11.61790000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, -248.26890000, -589.95000000, 3.78540000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, 115.38710000, 741.87240000, 13.56160000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, 49.21290000, 1350.85200000, 15.25260000 )
|
||||
createPickup( getPickupType( 2 ), 23, 200, 332.02520000, -158.35070000, 8.06910000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -462.60650000, 775.56370000, 8.98430000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -66.39730000, 1550.17700000, 17.64730000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -47.94850000, 35.91300000, 13.84780000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -210.80500000, 1410.40400000, 19.35510000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, 136.81580000, 387.45690000, 14.02680000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -604.36200000, 339.06450000, 3.67190000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -135.90700000, 819.94900000, 17.62560000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -437.64390000, 430.90700000, 8.93740000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -522.79810000, 1018.30500000, 8.79210000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -593.54960000, 1165.60900000, 8.94090000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, 89.78390000, 1251.53900000, 14.86610000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -108.15450000, 1271.20900000, 19.43000000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -5.26000000, -447.87000000, 13.75820000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, 171.83730000, -807.45750000, 3.97040000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, 0.32430000, -761.24270000, 4.08570000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -526.37620000, 593.51290000, 12.12300000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -554.97370000, 806.93090000, 8.05520000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, 13.89740000, 1147.71300000, 13.24760000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, 179.53490000, 691.26530000, 7.18630000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -463.63800000, 899.77910000, 8.96270000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -467.32180000, 1556.19000000, 17.47570000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -284.66330000, 1600.64600000, 19.41570000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -311.56230000, 1733.49700000, 12.12580000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -99.43640000, 1350.29900000, 19.41500000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -534.05160000, 1610.99600000, 8.39809000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, 91.99830000, -318.91000000, 13.61250000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -619.61000000, -115.38000000, 5.59590000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, 361.06920000, -477.77790000, 4.81800000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -404.86420000, 1487.26800000, 17.86060000 )
|
||||
createPickup( getPickupType( 1 ), 23, 200, -572.86970000, 227.56950000, 3.66220000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 150.65500000, 913.75690000, 7.35240000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -151.58120000, 1004.30900000, 5.22660000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -126.16370000, 554.53360000, 13.76430000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -389.27630000, 1763.59200000, 8.23320000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -414.94510000, 376.06220000, 11.07520000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -348.11940000, 631.42010000, 13.58580000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -561.26700000, 1457.39500000, 16.53680000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -656.75510000, 1140.68700000, 8.81430000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 286.89990000, -392.37890000, 3.97690000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 267.28000000, -686.88580000, 3.87500000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 185.85650000, 801.42330000, 7.45320000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -33.85220000, 772.73390000, 13.64890000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -658.17000000, 809.31000000, 3.10420000 )
|
||||
--createPickup( getPickupType( 0 ), 23, 200, 65123, 1658.10000000, 20.08190000 )
|
||||
--createPickup( getPickupType( 0 ), 23, 200, 65307, 1445.20000000, 19.45000000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -579.01340000, 1414.69400000, 14.47110000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -570.93210000, 158.32300000, 3.66220000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -641.65510000, -195.11170000, 3.94450000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -373.43770000, 1563.55700000, 19.15690000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -242.26720000, -515.22510000, 3.93780000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 83.27290000, 128.63830000, 13.74580000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 100.85700000, -751.07600000, 3.95820000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 148.27850000, -520.31800000, 13.76100000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -145.85800000, -436.54300000, 13.71600000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 30.52840000, -319.98200000, 13.72060000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -121.35400000, -765.42500000, 4.20210000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -301.78400000, -408.61900000, 3.82400000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -221.12500000, -244.63100000, 13.55080000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 345.52040000, -409.60800000, 3.69260000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -187.78400000, -104.23300000, 13.59230000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 23.03970000, -41.08220000, 13.81190000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -105.90000000, 129.42250000, 13.72260000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -470.49600000, 190.20460000, 8.85820000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -108.92700000, 371.07960000, 13.80730000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -308.23960000, 455.43910000, 13.69960000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 113.34910000, 650.53870000, 13.71280000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -69.89160000, 1147.73100000, 13.76710000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 29.31370000, 761.22520000, 13.50620000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 52.12710000, 889.81030000, 13.65160000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -616.57000000, 1001.96400000, 8.91920000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -491.81600000, 949.22980000, 8.96670000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 5.79550000, 1028.96500000, 13.72000000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -542.94400000, 1303.59300000, 16.25890000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -273.10860000, 1211.38200000, 17.78520000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -292.14300000, 1331.30300000, 23.60140000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -364.25800000, 1371.32500000, 14.19140000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -34.57900000, 1410.33300000, 19.42230000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -161.42200000, 1555.53300000, 17.37360000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 210.82320000, -105.36900000, 13.76120000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -124.28630000, -530.18220000, 13.76020000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -220.20000000, -883.72000000, 3.67810000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -107.78000000, -821.86000000, 4.12670000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 78.03000000, -670.74000000, 13.76770000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 151.18900000, -613.04700000, 9.63030000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -27.54000000, -823.69000000, 4.45430000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 200.28920000, -698.77010000, 3.95350000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -195.15000000, -711.21000000, 3.96790000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 100.96000000, -512.62000000, 15.08830000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 306.47000000, -623.30000000, 4.19430000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -79.41310000, 614.20590000, 13.76610000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -385.48000000, 738.49000000, 13.76610000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -434.99950000, 1101.79400000, 9.24650000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -31.37680000, 959.19130000, 13.92130000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -268.25000000, 751.37000000, 10.86610000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -199.04800000, 880.55260000, 5.15900000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -330.31000000, 1134.31000000, 12.49350000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -174.81230000, 938.15850000, 10.64700000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -115.90590000, 1043.57100000, 5.15920000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -315.16000000, 867.71000000, 8.89900000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -564.60000000, 1183.60000000, 9.01900000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -498.02150000, 1183.31100000, 13.21080000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -414.29530000, 1365.34600000, 15.55880000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -468.98060000, 1468.96400000, 17.86100000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -112.28410000, 1672.74500000, 17.61140000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -219.91810000, 1277.23200000, 22.09290000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 2.40000000, 1197.70000000, 16.47760000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -25.70000000, 1250.90000000, 19.43250000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -65.74770000, 1498.05800000, 17.44880000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -383.30600000, 319.06300000, 13.75090000 )
|
||||
--createPickup( getPickupType( 0 ), 23, 200, 65250, 344.20000000, 13.66590000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -212.60000000, 346.70000000, 14.03540000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -66.26470000, 278.22370000, 13.76360000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -181.14000000, 491.28420000, 13.71490000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -24.70000000, 405.20000000, 14.76350000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 51.61110000, 464.46720000, 13.69600000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 27.60000000, 374.20000000, 13.70190000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -603.98900000, 612.11540000, 3.85550000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -337.70000000, 215.40000000, 13.74920000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -383.50000000, 556.30000000, 13.77870000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -442.96920000, 590.37180000, 10.25190000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 141.80000000, 211.20000000, 13.76310000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -192.30000000, 162.40000000, 13.98940000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -348.60300000, -188.71300000, 13.64900000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -273.48200000, -157.81400000, 13.88300000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -117.97000000, -335.54000000, 13.73490000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -12.45000000, -218.40000000, 13.63990000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 179.94720000, -254.52090000, 11.85560000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 264.98180000, -302.83180000, 5.59270000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 162.58500000, -158.31150000, 13.92630000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 113.02140000, -39.66420000, 13.76250000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -126.60700000, -117.37200000, 13.81500000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 207.01740000, 20.70740000, 13.71320000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -254.45000000, -43.88000000, 13.76330000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -347.84500000, 105.27390000, 13.81310000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -345.03400000, -100.46700000, 13.70210000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -445.05100000, 131.98950000, 8.83120000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -490.37520000, 25.33320000, 6.86600000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -572.51200000, 86.31020000, 3.81230000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, 29.85000000, -601.28000000, 13.69580000 )
|
||||
createPickup( getPickupType( 0 ), 23, 200, -184.29000000, 102.09000000, 13.76770000 )
|
||||
end
|
||||
|
||||
AddEventHandler('createGunPickups', function(seed)
|
||||
pickupSeed = seed
|
||||
|
||||
RemoveAllPickupsOfType(23)
|
||||
createPickups()
|
||||
end)
|
@ -1,9 +0,0 @@
|
||||
math.randomseed(GetInstanceId())
|
||||
|
||||
local randomBase = math.random()
|
||||
|
||||
RegisterServerEvent('playerActivated')
|
||||
|
||||
AddEventHandler('playerActivated', function()
|
||||
TriggerClientEvent('createGunPickups', source, randomBase)
|
||||
end)
|
Before Width: | Height: | Size: 283 KiB After Width: | Height: | Size: 283 KiB |
5
resources/[test]/fivem/fxmanifest.lua
Normal file
5
resources/[test]/fivem/fxmanifest.lua
Normal file
@ -0,0 +1,5 @@
|
||||
-- compatibility wrapper
|
||||
fx_version 'adamant'
|
||||
game 'common'
|
||||
|
||||
dependency 'basic-gamemode'
|
@ -1,4 +0,0 @@
|
||||
description 'early init for game script'
|
||||
|
||||
client_script 'init.lua'
|
||||
server_script 'server.lua'
|
@ -1,42 +0,0 @@
|
||||
CreateThread(function()
|
||||
local bit = function()
|
||||
return math.random()
|
||||
end
|
||||
|
||||
local function freezePlayer(id, freeze)
|
||||
local player = ConvertIntToPlayerindex(id)
|
||||
SetPlayerControlForNetwork(player, not freeze, false)
|
||||
|
||||
local ped = GetPlayerChar(player, _i)
|
||||
|
||||
if not freeze then
|
||||
if not IsCharVisible(ped) then
|
||||
SetCharVisible(ped, true)
|
||||
end
|
||||
|
||||
if not IsCharInAnyCar(ped) then
|
||||
SetCharCollision(ped, true)
|
||||
end
|
||||
|
||||
FreezeCharPosition(ped, false)
|
||||
SetCharNeverTargetted(ped, false)
|
||||
SetPlayerInvincible(player, false)
|
||||
else
|
||||
FreezeCharPosition(ped, true)
|
||||
SetCharNeverTargetted(ped, true)
|
||||
SetPlayerInvincible(player, true)
|
||||
|
||||
if not IsCharFatallyInjured(ped) then
|
||||
--ClearCharTasksImmediately(ped)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local player = CreatePlayer(0, -2000.5 + bit(), -2000.5 + bit(), 240.5 + bit(), _i)
|
||||
|
||||
freezePlayer(GetPlayerId(), true)
|
||||
|
||||
SetLoadingText("this is too lovely")
|
||||
|
||||
TriggerEvent('playerInfoCreated')
|
||||
end)
|
@ -1,4 +0,0 @@
|
||||
-- prevent stopping gameInit on the server
|
||||
AddEventHandler('onResourceStop', function(name)
|
||||
if name == 'gameInit' then CancelEvent() end
|
||||
end)
|
@ -1,2 +0,0 @@
|
||||
client_script 'omg.lua'
|
||||
server_script 'srv.lua'
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user