1
0
mirror of https://github.com/citizenfx/cfx-server-data.git synced 2025-01-06 21:02:57 +08:00

Compare commits

...

6 Commits

Author SHA1 Message Date
astatine
dbdd474310 add compatibility fivem game mode 2019-12-10 11:01:48 +01:00
astatine
ea6f1d8133 mapmanager: only load maps matching current game 2019-12-10 11:00:37 +01:00
astatine
e7f7519e45 update yarn_cli.js 2019-12-10 10:57:34 +01:00
astatine
5ca4612547 work on __resource -> fxmanifest and RDR compatibility 2019-12-10 10:57:04 +01:00
astatine
4fff23e2ff readme, .gitignore update, resources/local dir 2019-12-10 09:56:20 +01:00
astatine
51cc79eda2 reorganize resource directories 2019-12-10 09:54:29 +01:00
105 changed files with 46984 additions and 42706 deletions

4
.gitignore vendored
View File

@ -1,5 +1,3 @@
CitizenMP.Server.exe
CitizenMP.Server.exe.config
NLog.config
*.cfg
/cache/
/resources/\[local\]/

31
README.md Normal file
View 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.

View File

@ -0,0 +1,6 @@
resource_type 'map' { gameTypes = { ['basic-gamemode'] = true } }
map 'map.lua'
fx_version 'adamant'
game 'gta5'

View File

@ -0,0 +1,6 @@
resource_type 'map' { gameTypes = { ['basic-gamemode'] = true } }
map 'map.lua'
fx_version 'adamant'
game 'gta5'

View 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.'

View 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 }

View File

@ -0,0 +1,6 @@
resource_type 'gametype' { name = 'Freeroam' }
client_script 'basic_client.lua'
game 'common'
fx_version 'adamant'

View File

@ -1,3 +0,0 @@
resource_type 'map' { gameTypes = { race = true } }
map 'map.lua'

View File

@ -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 } }]]

View File

@ -1,9 +0,0 @@
resource_type 'gametype' { name = 'Race' }
dependencies {
"spawnmanager",
"mapmanager"
}
client_script 'race_client.lua'
server_script 'race_server.lua'

View File

@ -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)

View File

@ -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)

View File

@ -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',
}

View File

@ -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

View File

@ -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();
});
})();

View File

@ -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>

View File

@ -7,4 +7,7 @@ chat_theme 'gtao' {
msgTemplates = {
default = '<b>{0}</b><span>{1}</span>'
}
}
}
game 'common'
fx_version 'adamant'

View File

@ -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);
}
}

View File

@ -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

View File

@ -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.'

View File

@ -1 +0,0 @@
server_script 'irc.lua'

View File

@ -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')

View File

@ -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)

View File

@ -1,5 +0,0 @@
dependency 'obituary'
description 'death messages using the obituary resource'
client_script 'deathmessages.lua'

View File

@ -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)

View File

@ -1,7 +0,0 @@
dependency 'channelfeed'
client_script 'obituary.lua'
export 'printObituary'
files 'obituary.css'

View File

@ -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;
}

View File

@ -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('<', '&lt;')
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('<', '&lt;')
})
end)]]
AddEventHandler('onClientResourceStop', function()
-- todo: remove channel
end)

View File

@ -24,4 +24,5 @@ files {
}
-- support the latest resource manifest
resource_manifest_version '05cfa83c-a124-4cfa-a768-c24a5811d8f9'
fx_version 'adamant'
game 'gta5'

View File

View 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.'

View File

@ -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

View File

@ -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

View File

@ -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.'

View File

@ -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

View File

@ -1,3 +0,0 @@
dependency 'yarn'
--server_only 'yes'
server_script 'webpack_builder.js'

View File

@ -0,0 +1,5 @@
dependency 'yarn'
server_script 'webpack_builder.js'
fx_version 'adamant'
game 'common'

View File

@ -1,2 +0,0 @@
--server_only 'yes'
server_script 'yarn_builder.js'

View File

@ -0,0 +1,4 @@
fx_version 'adamant'
game 'common'
server_script 'yarn_builder.js'

View File

@ -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

View File

@ -1,2 +0,0 @@
client_script 'client.lua'
server_script 'server.lua'

View 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.'

View File

@ -1,2 +0,0 @@
client_script 'rconlog_client.lua'
server_script 'rconlog_server.lua'

View 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.'

View File

@ -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'

View File

@ -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 = {
['&' ] = '&amp;',

View File

@ -0,0 +1,2 @@
node_modules/
yarn.lock

View File

@ -0,0 +1,8 @@
fx_version 'adamant'
game 'common'
dependencies {
'yarn'
}
server_script 'sm_server.js'

View File

@ -0,0 +1,6 @@
{
"private": true,
"dependencies": {
"@citizenfx/protobufjs": "6.8.8"
}
}

View 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;
};

View 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);
}
});
});

View File

@ -1,2 +0,0 @@
client_script 'client.lua'
server_script 'server.lua'

View File

@ -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)

View File

@ -1,9 +0,0 @@
math.randomseed(GetInstanceId())
local randomBase = math.random()
RegisterServerEvent('playerActivated')
AddEventHandler('playerActivated', function()
TriggerClientEvent('createGunPickups', source, randomBase)
end)

View File

Before

Width:  |  Height:  |  Size: 283 KiB

After

Width:  |  Height:  |  Size: 283 KiB

View File

@ -0,0 +1,5 @@
-- compatibility wrapper
fx_version 'adamant'
game 'common'
dependency 'basic-gamemode'

View File

@ -1,4 +0,0 @@
description 'early init for game script'
client_script 'init.lua'
server_script 'server.lua'

View File

@ -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)

View File

@ -1,4 +0,0 @@
-- prevent stopping gameInit on the server
AddEventHandler('onResourceStop', function(name)
if name == 'gameInit' then CancelEvent() end
end)

View File

@ -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