1
1
local Superman = {}
2
2
3
3
-- Settings
4
+
4
5
local ZERO_TOLERANCE = 0.00001
5
6
local MAX_ANGLE_SPEED = 6 -- In degrees per frame
6
7
local MAX_SPEED = 2.5
@@ -21,37 +22,21 @@ local IDLE_ANIMATION = "Coplook_loop"
21
22
local IDLE_ANIM_LOOP = true
22
23
local MAX_Y_ROTATION = 70
23
24
local ROTATION_Y_SPEED = 3.8
25
+ local warningTextColor = tocolor (255 , 0 , 0 , 255 )
26
+
27
+ -- Static variables
24
28
25
- -- Static global variables
26
- local thisResource = getThisResource ()
27
29
local serverGravity = getGravity ()
28
30
29
31
--
30
32
-- Utility functions
31
33
--
32
- local function isPlayerFlying (player )
33
- local data = getElementData (player , " superman:flying" )
34
34
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 )
41
37
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
52
39
end
53
- addEvent (" setPlayerFlyingC" , true )
54
- addEventHandler (" setPlayerFlyingC" , root , setPlayerFlying )
55
40
56
41
local function iterateFlyingPlayers ()
57
42
local current = 1
@@ -70,14 +55,14 @@ local function iterateFlyingPlayers()
70
55
end
71
56
end
72
57
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
81
66
end
82
67
83
68
function angleDiff (angle1 , angle2 )
@@ -91,22 +76,6 @@ function angleDiff(angle1, angle2)
91
76
end
92
77
end
93
78
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
-
110
79
local function isnan (x )
111
80
math .inf = 1 / 0
112
81
@@ -136,26 +105,24 @@ function Superman.Start()
136
105
local self = Superman
137
106
138
107
-- 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 )
142
110
addEventHandler (" onClientRender" , root , Superman .processControls )
143
111
addEventHandler (" onClientRender" , root , Superman .processFlight )
144
112
addEventHandler (" onClientPlayerDamage" , localPlayer , Superman .onDamage , false )
145
113
addEventHandler (" onClientPlayerVehicleEnter" , localPlayer , Superman .onEnter )
146
- addEventHandler (" onClientElementDataChange" , root , Superman .onDataChange )
147
- addEventHandler (" onClientElementStreamIn" , root , Superman .onStreamIn )
148
114
addEventHandler (" onClientElementStreamOut" , root , Superman .onStreamOut )
149
115
150
116
bindKey (" jump" , " down" , Superman .onJump )
151
117
152
118
addCommandHandler (" superman" , Superman .cmdSuperman )
153
119
154
120
-- Initializate attributes
121
+
155
122
self .rotations = {}
156
123
self .previousVelocity = {}
157
124
end
158
- addEventHandler (" onClientResourceStart" , getResourceRootElement ( thisResource ) , Superman .Start , false )
125
+ addEventHandler (" onClientResourceStart" , resourceRoot , Superman .Start , false )
159
126
160
127
function Superman .Stop ()
161
128
local self = Superman
@@ -168,30 +135,14 @@ function Superman.Stop()
168
135
end
169
136
end
170
137
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
-
187
138
-- onEnter: superman cant enter vehicles
188
139
-- 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.
189
140
function showWarning ()
190
141
local x , y , z = getPedBonePosition (localPlayer , 6 )
191
142
local sx , sy , dist = getScreenFromWorldPosition (x , y , z + 0.3 )
192
143
193
144
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" )
195
146
end
196
147
end
197
148
@@ -200,46 +151,44 @@ function hideWarning()
200
151
end
201
152
202
153
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
204
155
addEventHandler (" onClientRender" , root , showWarning )
205
156
warningTimer = setTimer (hideWarning , 5000 , 1 )
206
157
end
207
158
end
208
159
209
160
function Superman .onDamage ()
210
- local self = Superman
211
-
212
161
if isPlayerFlying (localPlayer ) then
213
162
cancelEvent ()
214
163
end
215
164
end
216
165
217
- -- onStreamIn: Reset rotation attribute for player
218
- function Superman .onStreamIn ()
219
- local self = Superman
220
- end
221
-
222
166
function Superman .onStreamOut ()
223
167
local self = Superman
224
168
225
- if source and isElement ( source ) and getElementType ( source ) == " player " and isPlayerFlying (source ) then
169
+ if isPlayerFlying (source ) then
226
170
self .rotations [source ] = nil
227
171
self .previousVelocity [source ] = nil
228
172
end
229
173
end
230
174
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
234
181
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 )
237
184
end
238
185
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 )
239
188
240
189
-- onJump: Combo to start flight without any command
241
- function Superman . onJump ( key , keyState )
242
- local self = Superman
190
+
191
+ function Superman . onJump ()
243
192
local task = getPedSimplestTask (localPlayer )
244
193
245
194
if not isPlayerFlying (localPlayer ) then
@@ -251,34 +200,32 @@ function Superman.onJump(key, keyState)
251
200
end
252
201
253
202
function Superman .cmdSuperman ()
254
- local self = Superman
255
-
256
203
if isPedInVehicle (localPlayer ) or isPlayerFlying (localPlayer ) then
257
204
return
258
205
end
259
206
260
207
setElementVelocity (localPlayer , 0 , 0 , TAKEOFF_VELOCITY )
261
208
setTimer (Superman .startFlight , TAKEOFF_FLIGHT_DELAY , 1 )
262
- setElementData (localPlayer , " superman:takingOff " , true )
209
+ setSupermanData (localPlayer , SUPERMAN_TAKE_OFF_DATA_KEY , true )
263
210
end
264
211
265
212
function Superman .startFlight ()
266
213
local self = Superman
267
214
268
- setElementData (localPlayer , " superman:takingOff " , false )
215
+ setSupermanData (localPlayer , SUPERMAN_TAKE_OFF_DATA_KEY , false )
269
216
270
217
if isPlayerFlying (localPlayer ) then
271
218
return
272
219
end
273
220
274
- triggerServerEvent (" superman:start" , localPlayer )
275
- setPlayerFlying (localPlayer , true )
221
+ setSupermanData (localPlayer , SUPERMAN_FLY_DATA_KEY , true )
276
222
setElementVelocity (localPlayer , 0 , 0 , 0 )
277
223
self .currentSpeed = 0
278
224
self .extraVelocity = {x = 0 , y = 0 , z = 0 }
279
225
end
280
226
281
227
-- Controls processing
228
+
282
229
local jump , oldJump = false , false
283
230
284
231
function Superman .processControls ()
@@ -449,7 +396,7 @@ function Superman.processFlight()
449
396
self :restorePlayer (player )
450
397
if player == localPlayer then
451
398
setGravity (serverGravity )
452
- triggerServerEvent ( " superman:stop " , localPlayer )
399
+ setSupermanData ( localPlayer , SUPERMAN_FLY_DATA_KEY , false )
453
400
end
454
401
elseif distanceToGround and distanceToGround < LANDING_DISTANCE then
455
402
self :processLanding (player , Velocity , distanceToGround )
@@ -488,11 +435,10 @@ function Superman:processIdleFlight(player)
488
435
489
436
Sight .z = math.deg (Sight .z ) + 180
490
437
491
- setPedRotation (localPlayer , Sight .z )
492
438
setElementRotation (localPlayer , 0 , 0 , Sight .z )
493
439
else
494
440
local Zangle = getPedCameraRotation (player )
495
- setPedRotation ( player , Zangle )
441
+
496
442
setElementRotation (player , 0 , 0 , Zangle )
497
443
end
498
444
end
@@ -515,7 +461,7 @@ function Superman:processMovingFlight(player, Velocity)
515
461
local Rotation = Vector3D :new (0 , 0 , 0 )
516
462
517
463
if Velocity .x == 0 and Velocity .y == 0 then
518
- Rotation .z = getPedRotation (player )
464
+ Rotation .z = getElementRotation (player )
519
465
else
520
466
Rotation .z = math.deg (math.atan (Velocity .x / Velocity .y ))
521
467
@@ -574,7 +520,7 @@ function Superman:processMovingFlight(player, Velocity)
574
520
Rotation .y = self .rotations [player ]
575
521
576
522
-- Apply the calculated rotation
577
- setPedRotation ( player , Rotation . z )
523
+
578
524
setElementRotation (player , Rotation .x , Rotation .y , Rotation .z )
579
525
580
526
-- Save the current velocity
@@ -600,7 +546,7 @@ function Superman:processLanding(player, Velocity, distanceToGround)
600
546
local Rotation = Vector3D :new (0 , 0 , 0 )
601
547
602
548
if Velocity .x == 0 and Velocity .y == 0 then
603
- Rotation .z = getPedRotation (player )
549
+ Rotation .z = getElementRotation (player )
604
550
else
605
551
Rotation .z = math.deg (math.atan (Velocity .x / Velocity .y ))
606
552
if Velocity .y > 0 then
@@ -614,7 +560,7 @@ function Superman:processLanding(player, Velocity, distanceToGround)
614
560
Rotation .x = Rotation .x - 40
615
561
616
562
-- Apply the calculated rotation
617
- setPedRotation ( player , Rotation . z )
563
+
618
564
setElementRotation (player , Rotation .x , Rotation .y , Rotation .z )
619
565
end
620
566
0 commit comments