Skip to content

Commit e1c06c3

Browse files
authored
superman: more initial improvements (#577)
1 parent 1ff08f9 commit e1c06c3

File tree

8 files changed

+368
-151
lines changed

8 files changed

+368
-151
lines changed

[gameplay]/superman/client.lua renamed to [gameplay]/superman/CHandleSuperman.lua

Lines changed: 44 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
local Superman = {}
22

33
-- Settings
4+
45
local ZERO_TOLERANCE = 0.00001
56
local MAX_ANGLE_SPEED = 6 -- In degrees per frame
67
local MAX_SPEED = 2.5
@@ -21,37 +22,21 @@ local IDLE_ANIMATION = "Coplook_loop"
2122
local IDLE_ANIM_LOOP = true
2223
local MAX_Y_ROTATION = 70
2324
local ROTATION_Y_SPEED = 3.8
25+
local warningTextColor = tocolor(255, 0, 0, 255)
26+
27+
-- Static variables
2428

25-
-- Static global variables
26-
local thisResource = getThisResource()
2729
local serverGravity = getGravity()
2830

2931
--
3032
-- Utility functions
3133
--
32-
local function isPlayerFlying(player)
33-
local data = getElementData(player, "superman:flying")
3434

35-
if not data or data == false then
36-
return false
37-
else
38-
return true
39-
end
40-
end
35+
local function isPlayerFlying(playerElement)
36+
local playerFlying = getSupermanData(playerElement, SUPERMAN_FLY_DATA_KEY)
4137

42-
local function setPlayerFlying(player, state)
43-
if not player then return end
44-
45-
if state == true then
46-
state = true
47-
else
48-
state = false
49-
end
50-
51-
setElementData(player, "superman:flying", state)
38+
return playerFlying
5239
end
53-
addEvent("setPlayerFlyingC", true)
54-
addEventHandler("setPlayerFlyingC", root, setPlayerFlying)
5540

5641
local function iterateFlyingPlayers()
5742
local current = 1
@@ -70,14 +55,14 @@ local function iterateFlyingPlayers()
7055
end
7156
end
7257

73-
function Superman:restorePlayer(player)
74-
setPlayerFlying(player, false)
75-
setPedAnimation(player, false)
76-
setElementVelocity(player, 0, 0, 0)
77-
setElementRotation(player, 0, 0, 0)
78-
setElementCollisionsEnabled(player, true)
79-
self.rotations[player] = nil
80-
self.previousVelocity[player] = nil
58+
function Superman:restorePlayer(playerElement)
59+
setSupermanData(playerElement, SUPERMAN_FLY_DATA_KEY, false)
60+
setPedAnimation(playerElement, false)
61+
setElementVelocity(playerElement, 0, 0, 0)
62+
setElementRotation(playerElement, 0, 0, 0)
63+
setElementCollisionsEnabled(playerElement, true)
64+
self.rotations[playerElement] = nil
65+
self.previousVelocity[playerElement] = nil
8166
end
8267

8368
function angleDiff(angle1, angle2)
@@ -91,22 +76,6 @@ function angleDiff(angle1, angle2)
9176
end
9277
end
9378

94-
local function isElementInWater(ped)
95-
local pedPosition = Vector3D:new(getElementPosition(ped))
96-
97-
if pedPosition.z <= 0 then
98-
return true
99-
end
100-
101-
local waterLevel = getWaterLevel(pedPosition.x, pedPosition.y, pedPosition.z)
102-
103-
if not isElementStreamedIn(ped) or not waterLevel or waterLevel < pedPosition.z then
104-
return false
105-
else
106-
return true
107-
end
108-
end
109-
11079
local function isnan(x)
11180
math.inf = 1 / 0
11281

@@ -136,26 +105,24 @@ function Superman.Start()
136105
local self = Superman
137106

138107
-- Register events
139-
addEventHandler("onClientResourceStop", getResourceRootElement(thisResource), Superman.Stop, false)
140-
addEventHandler("onPlayerJoin", root, Superman.onJoin)
141-
addEventHandler("onPlayerQuit", root, Superman.onQuit)
108+
109+
addEventHandler("onClientResourceStop", resourceRoot, Superman.Stop, false)
142110
addEventHandler("onClientRender", root, Superman.processControls)
143111
addEventHandler("onClientRender", root, Superman.processFlight)
144112
addEventHandler("onClientPlayerDamage", localPlayer, Superman.onDamage, false)
145113
addEventHandler("onClientPlayerVehicleEnter", localPlayer, Superman.onEnter)
146-
addEventHandler("onClientElementDataChange", root, Superman.onDataChange)
147-
addEventHandler("onClientElementStreamIn", root, Superman.onStreamIn)
148114
addEventHandler("onClientElementStreamOut", root, Superman.onStreamOut)
149115

150116
bindKey("jump", "down", Superman.onJump)
151117

152118
addCommandHandler("superman", Superman.cmdSuperman)
153119

154120
-- Initializate attributes
121+
155122
self.rotations = {}
156123
self.previousVelocity = {}
157124
end
158-
addEventHandler("onClientResourceStart", getResourceRootElement(thisResource), Superman.Start, false)
125+
addEventHandler("onClientResourceStart", resourceRoot, Superman.Start, false)
159126

160127
function Superman.Stop()
161128
local self = Superman
@@ -168,30 +135,14 @@ function Superman.Stop()
168135
end
169136
end
170137

171-
function Superman.onJoin(player)
172-
local self = Superman
173-
local playerElement = player or source
174-
175-
setPlayerFlying(playerElement, false)
176-
end
177-
178-
function Superman.onQuit(reason, player)
179-
local self = Superman
180-
local playerElement = player or source
181-
182-
if isPlayerFlying(playerElement) then
183-
self:restorePlayer(playerElement)
184-
end
185-
end
186-
187138
-- onEnter: superman cant enter vehicles
188139
-- There's a fix (serverside) for players glitching other players' vehicles by warping into them while superman is active, causing them to flinch into air and get stuck.
189140
function showWarning()
190141
local x, y, z = getPedBonePosition(localPlayer, 6)
191142
local sx, sy, dist = getScreenFromWorldPosition(x, y, z + 0.3)
192143

193144
if sx and sy and dist and dist < 100 then
194-
dxDrawText("You can not warp into a vehicle when superman is activated.", sx, sy, sx, sy, tocolor(255, 0, 0, 255), 1.1, "default-bold", "center")
145+
dxDrawText("You can not warp into a vehicle when superman is activated.", sx, sy, sx, sy, warningTextColor, 1.1, "default-bold", "center")
195146
end
196147
end
197148

@@ -200,46 +151,44 @@ function hideWarning()
200151
end
201152

202153
function Superman.onEnter()
203-
if (isPlayerFlying(localPlayer) or getElementData(localPlayer, "superman:takingOff")) and not isTimer(warningTimer) then
154+
if (isPlayerFlying(localPlayer) or getSupermanData(localPlayer, SUPERMAN_TAKE_OFF_DATA_KEY)) and not isTimer(warningTimer) then
204155
addEventHandler("onClientRender", root, showWarning)
205156
warningTimer = setTimer(hideWarning, 5000, 1)
206157
end
207158
end
208159

209160
function Superman.onDamage()
210-
local self = Superman
211-
212161
if isPlayerFlying(localPlayer) then
213162
cancelEvent()
214163
end
215164
end
216165

217-
-- onStreamIn: Reset rotation attribute for player
218-
function Superman.onStreamIn()
219-
local self = Superman
220-
end
221-
222166
function Superman.onStreamOut()
223167
local self = Superman
224168

225-
if source and isElement(source) and getElementType(source) == "player" and isPlayerFlying(source) then
169+
if isPlayerFlying(source) then
226170
self.rotations[source] = nil
227171
self.previousVelocity[source] = nil
228172
end
229173
end
230174

231-
-- onDataChange: Check if somebody who is out of stream stops being superman
232-
function Superman.onDataChange(dataName, oldValue)
233-
local self = Superman
175+
function onClientSupermanDataChange(dataKey, _, newValue)
176+
local flyDataKey = (dataKey == SUPERMAN_FLY_DATA_KEY)
177+
178+
if (not flyDataKey) then
179+
return false
180+
end
234181

235-
if dataName == "superman:flying" and isElement(source) and getElementType(source) == "player" and oldValue ~= getElementData(source, dataName) and oldValue == true and getElementData(source, dataName) == false then
236-
self:restorePlayer(source)
182+
if (not newValue) then
183+
Superman:restorePlayer(source)
237184
end
238185
end
186+
if (not SUPERMAN_USE_ELEMENT_DATA) then addEvent("onClientSupermanDataChange", false) end
187+
addEventHandler(SUPERMAN_USE_ELEMENT_DATA and "onClientElementDataChange" or "onClientSupermanDataChange", root, onClientSupermanDataChange)
239188

240189
-- onJump: Combo to start flight without any command
241-
function Superman.onJump(key, keyState)
242-
local self = Superman
190+
191+
function Superman.onJump()
243192
local task = getPedSimplestTask(localPlayer)
244193

245194
if not isPlayerFlying(localPlayer) then
@@ -251,34 +200,32 @@ function Superman.onJump(key, keyState)
251200
end
252201

253202
function Superman.cmdSuperman()
254-
local self = Superman
255-
256203
if isPedInVehicle(localPlayer) or isPlayerFlying(localPlayer) then
257204
return
258205
end
259206

260207
setElementVelocity(localPlayer, 0, 0, TAKEOFF_VELOCITY)
261208
setTimer(Superman.startFlight, TAKEOFF_FLIGHT_DELAY, 1)
262-
setElementData(localPlayer, "superman:takingOff", true)
209+
setSupermanData(localPlayer, SUPERMAN_TAKE_OFF_DATA_KEY, true)
263210
end
264211

265212
function Superman.startFlight()
266213
local self = Superman
267214

268-
setElementData(localPlayer, "superman:takingOff", false)
215+
setSupermanData(localPlayer, SUPERMAN_TAKE_OFF_DATA_KEY, false)
269216

270217
if isPlayerFlying(localPlayer) then
271218
return
272219
end
273220

274-
triggerServerEvent("superman:start", localPlayer)
275-
setPlayerFlying(localPlayer, true)
221+
setSupermanData(localPlayer, SUPERMAN_FLY_DATA_KEY, true)
276222
setElementVelocity(localPlayer, 0, 0, 0)
277223
self.currentSpeed = 0
278224
self.extraVelocity = {x = 0, y = 0, z = 0}
279225
end
280226

281227
-- Controls processing
228+
282229
local jump, oldJump = false, false
283230

284231
function Superman.processControls()
@@ -449,7 +396,7 @@ function Superman.processFlight()
449396
self:restorePlayer(player)
450397
if player == localPlayer then
451398
setGravity(serverGravity)
452-
triggerServerEvent("superman:stop", localPlayer)
399+
setSupermanData(localPlayer, SUPERMAN_FLY_DATA_KEY, false)
453400
end
454401
elseif distanceToGround and distanceToGround < LANDING_DISTANCE then
455402
self:processLanding(player, Velocity, distanceToGround)
@@ -488,11 +435,10 @@ function Superman:processIdleFlight(player)
488435

489436
Sight.z = math.deg(Sight.z) + 180
490437

491-
setPedRotation(localPlayer, Sight.z)
492438
setElementRotation(localPlayer, 0, 0, Sight.z)
493439
else
494440
local Zangle = getPedCameraRotation(player)
495-
setPedRotation(player, Zangle)
441+
496442
setElementRotation(player, 0, 0, Zangle)
497443
end
498444
end
@@ -515,7 +461,7 @@ function Superman:processMovingFlight(player, Velocity)
515461
local Rotation = Vector3D:new(0, 0, 0)
516462

517463
if Velocity.x == 0 and Velocity.y == 0 then
518-
Rotation.z = getPedRotation(player)
464+
Rotation.z = getElementRotation(player)
519465
else
520466
Rotation.z = math.deg(math.atan(Velocity.x / Velocity.y))
521467

@@ -574,7 +520,7 @@ function Superman:processMovingFlight(player, Velocity)
574520
Rotation.y = self.rotations[player]
575521

576522
-- Apply the calculated rotation
577-
setPedRotation(player, Rotation.z)
523+
578524
setElementRotation(player, Rotation.x, Rotation.y, Rotation.z)
579525

580526
-- Save the current velocity
@@ -600,7 +546,7 @@ function Superman:processLanding(player, Velocity, distanceToGround)
600546
local Rotation = Vector3D:new(0, 0, 0)
601547

602548
if Velocity.x == 0 and Velocity.y == 0 then
603-
Rotation.z = getPedRotation(player)
549+
Rotation.z = getElementRotation(player)
604550
else
605551
Rotation.z = math.deg(math.atan(Velocity.x / Velocity.y))
606552
if Velocity.y > 0 then
@@ -614,7 +560,7 @@ function Superman:processLanding(player, Velocity, distanceToGround)
614560
Rotation.x = Rotation.x - 40
615561

616562
-- Apply the calculated rotation
617-
setPedRotation(player, Rotation.z)
563+
618564
setElementRotation(player, Rotation.x, Rotation.y, Rotation.z)
619565
end
620566

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
local function supermanCancelAirKill()
2+
local supermanFlying = getSupermanData(source, SUPERMAN_FLY_DATA_KEY)
3+
local supermanTakingOff = getSupermanData(source, SUPERMAN_TAKE_OFF_DATA_KEY)
4+
5+
if (not supermanFlying and not supermanTakingOff) then
6+
return false
7+
end
8+
9+
cancelEvent()
10+
end
11+
addEventHandler("onPlayerStealthKill", root, supermanCancelAirKill)
12+
13+
-- Fix for players glitching other players' vehicles by warping into them while superman is active, causing them to flinch into air and get stuck.
14+
15+
local function supermanEnterVehicle()
16+
local supermanFlying = getSupermanData(source, SUPERMAN_FLY_DATA_KEY)
17+
local supermanTakingOff = getSupermanData(source, SUPERMAN_TAKE_OFF_DATA_KEY)
18+
19+
if (not supermanFlying and not supermanTakingOff) then
20+
return false
21+
end
22+
23+
removePedFromVehicle(source)
24+
25+
local playerX, playerY, playerZ = getElementPosition(source)
26+
27+
setElementPosition(source, playerX, playerY, playerZ)
28+
end
29+
addEventHandler("onPlayerVehicleEnter", root, supermanEnterVehicle)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
SUPERMAN_FLY_DATA_KEY = "superman:flying"
2+
SUPERMAN_TAKE_OFF_DATA_KEY = "superman:takingOff"

[gameplay]/superman/data/CData.lua

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
local function onClientSupermanSync(supermanServerData)
2+
syncSupermansData(supermanServerData)
3+
end
4+
if (not SUPERMAN_USE_ELEMENT_DATA) then
5+
addEvent("onClientSupermanSync", true)
6+
addEventHandler("onClientSupermanSync", localPlayer, onClientSupermanSync)
7+
end
8+
9+
local function onClientSupermanSetData(dataKey, dataValue)
10+
setSupermanData(source, dataKey, dataValue)
11+
end
12+
if (not SUPERMAN_USE_ELEMENT_DATA) then
13+
addEvent("onClientSupermanSetData", true)
14+
addEventHandler("onClientSupermanSetData", root, onClientSupermanSetData)
15+
end

0 commit comments

Comments
 (0)