Jump to content

como pongo un scrip solo para mods S.mod y adm


Recommended Posts

hola quisiera saber como cambio un script para poder ponerlo solo para admin, S.mods, mods

el script se llama Superman
hay 3 archivos el Client.lua,Server.lua y la meta XML

el client.lua dice esto

local Superman = {}
 
-- Settings
local ZERO_TOLERANCE = 0.00001
local MAX_ANGLE_SPEED = 6 -- In degrees per frame
local MAX_SPEED = 1.0
local EXTRA_SPEED_FACTOR = 1.85
local LOW_SPEED_FACTOR = 0.40
local ACCELERATION = 0.025
local EXTRA_ACCELERATION_FACTOR = 1.8
local LOW_ACCELERATION_FACTOR = 0.85
local TAKEOFF_VELOCITY = 1.75
local TAKEOFF_FLIGHT_DELAY = 750
local SMOKING_SPEED = 1.25
local GROUND_ZERO_TOLERANCE = 0.18
local LANDING_DISTANCE = 3.2
local FLIGHT_ANIMLIB = "swim"
local FLIGHT_ANIMATION = "Swim_Dive_Under"
local FLIGHT_ANIM_LOOP = false
local IDLE_ANIMLIB = "cop_ambient"
local IDLE_ANIMATION = "Coplook_loop"
local IDLE_ANIM_LOOP = true
local MAX_Y_ROTATION = 55
local ROTATION_Y_SPEED = 3.8
 
-- Static global variables
local thisResource = getThisResource()
local rootElement = getRootElement()
local localPlayer = getLocalPlayer()
local serverGravity = getGravity()
 

--
-- Utility functions
--
local function isPlayerFlying(player)
  local data = getElementData(player, "superman:flying")
  if not data or data == false then return false
  else return true end
end
 
local function setPlayerFlying(player, state)
  if state == true then state = true
  else state = false end
 
  setElementData(player, "superman:flying", state)
end
 
local function iterateFlyingPlayers()
  local current = 1
  local allPlayers = getElementsByType("player")
 
  return function()
    local player
   
    repeat
      player = allPlayers[current]
      current = current + 1
    until not player or (isPlayerFlying(player) and isElementStreamedIn(player))
 
    return player
  end
end
 
function Superman:restorePlayer(player)
  setPlayerFlying(player, false)
  setPedAnimation(player, false)
  setElementVelocity(player, 0, 0, 0)
  setElementRotation(player, 0, 0, 0)
  --setPedRotation(player, getPedRotation(player))
  setElementCollisionsEnabled(player, true)
  self:destroySmokeGenerators(player)
  self.rotations[player] = nil
  self.previousVelocity[player] = nil
end
 
function Superman:createSmokeGenerator(player)
  local generator = createObject(2780, getElementPosition(player))
  setElementCollisionsEnabled(generator, false)
  setObjectScale(generator, 0)
  return generator
end
 
function Superman:createSmokeGenerators(player)
  if not self.smokeGenerators[player] then
    local smokeGenerators = {}
 
    smokeGenerators[1] = self:createSmokeGenerator(player)
    attachElementToElement(smokeGenerators[1], player, 0.75, -0.2, -0.4, -40, 0, 60)
    smokeGenerators[2] = self:createSmokeGenerator(player)
    attachElementToElement(smokeGenerators[2], player, -0.75, -0.2, -0.4, -40, 0, -60)
 
    self.smokeGenerators[player] = smokeGenerators
  end
end
 
function Superman:destroySmokeGenerators(player)
  if self.smokeGenerators[player] then
    for k, v in ipairs(self.smokeGenerators[player]) do
      destroyElement(v)
    end
    self.smokeGenerators[player] = nil
  end
end
 
function angleDiff(angle1, angle2)
  angle1, angle2 = angle1 % 360, angle2 % 360
  local diff = (angle1 - angle2) % 360
  if diff <= 180 then
    return diff
  else
    return -(360 - diff)
  end
end
 
local function isPedInWater(ped)
  local pedPosition = Vector3D:new(getElementPosition(ped))
  if pedPosition.z <= 0 then return true end
 
  local waterLevel = getWaterLevel(pedPosition.x, pedPosition.y, pedPosition.z)
  if not isElementStreamedIn(ped) or not waterLevel or waterLevel < pedPosition.z then
    return false
  else
    return true
  end
end
 
local function isnan(x)
 math.inf = 1/0
 if x == math.inf or x == -math.inf or x ~= x then
  return true
 end
 return false
end
 
local function getVector2DAngle(vec)
  if vec.x == 0 and vec.y == 0 then return 0 end
  local angle = math.deg(math.atan(vec.x / vec.y)) + 90
  if vec.y < 0 then
    angle = angle + 180
  end
  return angle
end
 
--
-- Initialization and shutdown functions
--
function Superman.Start()
  local self = Superman
 
  -- Register events
  addEventHandler("onClientResourceStop", getResourceRootElement(thisResource), Superman.Stop, false)
  addEventHandler("onPlayerJoin", rootElement, Superman.onJoin)
  addEventHandler("onPlayerQuit", rootElement, Superman.onQuit)
  addEventHandler("onClientPreRender", rootElement, Superman.processControls)
  addEventHandler("onClientPreRender", rootElement, Superman.processFlight)
  addEventHandler("onClientPlayerDamage", localPlayer, Superman.onDamage, false)
  addEventHandler("onClientElementDataChange", rootElement, Superman.onDataChange)
  addEventHandler("onClientElementStreamIn", rootElement, Superman.onStreamIn)
  addEventHandler("onClientElementStreamOut", rootElement, Superman.onStreamOut)
 
  -- Bind keys
  bindKey("jump", "down", Superman.onJump)
 
  -- Register commands
  addCommandHandler("superman", Superman.cmdSuperman)
 
  -- Initializate attributes
  self.smokeGenerators = {}
  self.rotations = {}
  self.previousVelocity = {}
end
addEventHandler("onClientResourceStart", getResourceRootElement(thisResource), Superman.Start, false)
 
function Superman.Stop()
  local self = Superman
 
  setGravity(serverGravity)
 
  -- Restore all players animations, collisions, etc
  for player in iterateFlyingPlayers() do
    self:restorePlayer(player)
  end
end
 
 
 
--
-- Join/Quit
--
function Superman.onJoin(player)
  local self = Superman
  local player = player or source
 
  setPlayerFlying(player, false)
end
 
function Superman.onQuit(reason, player)
  local self = Superman
  local player = player or source
 
  if isPlayerFlying(player) then
    self:restorePlayer(player)
  end
end
 

--
-- onDamage: superman is invulnerable
--
function Superman.onDamage()
  local self = Superman
 
  if isPlayerFlying(localPlayer) then
    cancelEvent()
  end
end
 

--
-- onStreamIn: Reset rotation attribute for player
--
function Superman.onStreamIn()
  local self = Superman
end
 
function Superman.onStreamOut()
  local self = Superman
 
  if source and isElement(source) and getElementType(source) == "player" and isPlayerFlying(source) then
    self.rotations[source] = nil
    self.previousVelocity[source] = nil
  end
end
 
--
-- onDataChange: Check if somebody who is out of stream stops being superman
--
function Superman.onDataChange(dataName, oldValue)
  local self = Superman
 
  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
    self:restorePlayer(source)
  end
end
 
--
-- onJump: Combo to start flight without any command
--
function Superman.onJump(key, keyState)
  local self = Superman
 
  local task = getPlayerSimplestTask(localPlayer)
  if not isPlayerFlying(localPlayer) then
 if task == "TASK_SIMPLE_IN_AIR" then
   setElementVelocity(localPlayer, 0, 0, TAKEOFF_VELOCITY)
      setTimer(Superman.startFlight, 100, 1)
 end
  end
end
 
--
-- Commands
--
function Superman.cmdSuperman()
  local self = Superman
 
  if isPedInVehicle(localPlayer) or isPlayerFlying(localPlayer) then return end
  setElementVelocity(localPlayer, 0, 0, TAKEOFF_VELOCITY)
  setTimer(Superman.startFlight, TAKEOFF_FLIGHT_DELAY, 1)
end
 
function Superman.startFlight()
  local self = Superman
 
  if isPlayerFlying(localPlayer) then return end
 
  triggerServerEvent("superman:start", rootElement)
  setPlayerFlying(localPlayer, true)
  setElementVelocity(localPlayer, 0, 0, 0)
  self.currentSpeed = 0
  self.extraVelocity = { x = 0, y = 0, z = 0 }
end
 

--
-- Controls processing
--
function Superman.processControls()
  local self = Superman
 
  if not isPlayerFlying(localPlayer) then return end
 
  if getElementHealth(localPlayer) < 100.0 then setElementHealth(localPlayer, 100.0) end
 
  -- Calculate the requested movement direction
  local Direction = Vector3D:new(0, 0, 0)
  if getControlState("forwards") then
    Direction.y = 1
  elseif getControlState("backwards") then
    Direction.y = -1
  end
 
  if getControlState("left") then
    Direction.x = 1
  elseif getControlState("right") then
    Direction.x = -1
  end
  Direction:Normalize()
 
  -- Calculate the sight direction
  local cameraX, cameraY, cameraZ, lookX, lookY, lookZ = getCameraMatrix()
  local SightDirection = Vector3D:new((lookX - cameraX), (lookY - cameraY), (lookZ - cameraZ))
  SightDirection:Normalize()
  if getControlState("look_behind") then
    SightDirection = SightDirection:Mul(-1)
  end
 
  -- Calculate the current max speed and acceleration values
  local maxSpeed = MAX_SPEED
  local acceleration = ACCELERATION
  if getControlState("sprint") then
    maxSpeed = MAX_SPEED * EXTRA_SPEED_FACTOR
    acceleration = acceleration * EXTRA_ACCELERATION_FACTOR
  elseif getControlState("walk") then
    maxSpeed = MAX_SPEED * LOW_SPEED_FACTOR
    acceleration = acceleration * LOW_ACCELERATION_FACTOR
  end
 
  local DirectionModule = Direction:Module()
 
  -- Check if we must change the gravity
  if DirectionModule == 0 and self.currentSpeed ~= 0 then
    setGravity(0)
  else
    setGravity(serverGravity)
  end
 
  -- Calculate the new current speed
  if self.currentSpeed ~= 0 and (DirectionModule == 0 or self.currentSpeed > maxSpeed) then
    -- deccelerate
    self.currentSpeed = self.currentSpeed - acceleration
    if self.currentSpeed < 0 then self.currentSpeed = 0 end
 
  elseif DirectionModule ~= 0 and self.currentSpeed < maxSpeed then
    -- accelerate
    self.currentSpeed = self.currentSpeed + acceleration
    if self.currentSpeed > maxSpeed then self.currentSpeed = maxSpeed end
 
  end
 
  -- Calculate the movement requested direction
  if DirectionModule ~= 0 then
    Direction = Vector3D:new(SightDirection.x * Direction.y - SightDirection.y * Direction.x,
                             SightDirection.x * Direction.x + SightDirection.y * Direction.y,
                             SightDirection.z * Direction.y)
    -- Save the last movement direction for when player releases all direction keys
    self.lastDirection = Direction
  else
    -- Player is not specifying any direction, use last known direction or the current velocity
    if self.lastDirection then
      Direction = self.lastDirection
      if self.currentSpeed == 0 then self.lastDirection = nil end
    else
      Direction = Vector3D:new(getElementVelocity(localPlayer))
    end
  end
  Direction:Normalize()
  Direction = Direction:Mul(self.currentSpeed)
 
  -- Applicate a smooth direction change, if moving
  if self.currentSpeed > 0 then
    local VelocityDirection = Vector3D:new(getElementVelocity(localPlayer))
    VelocityDirection:Normalize()
 
    if math.sqrt(VelocityDirection.x^2 + VelocityDirection.y^2) > 0 then
      local DirectionAngle = getVector2DAngle(Direction)
      local VelocityAngle = getVector2DAngle(VelocityDirection)
 
      local diff = angleDiff(DirectionAngle, VelocityAngle)
      local calculatedAngle
 
      if diff >= 0 then
        if diff > MAX_ANGLE_SPEED then
          calculatedAngle = VelocityAngle + MAX_ANGLE_SPEED
 else
   calculatedAngle = DirectionAngle
 end
      else
        if diff < MAX_ANGLE_SPEED then
          calculatedAngle = VelocityAngle - MAX_ANGLE_SPEED
 else
          calculatedAngle = DirectionAngle
        end
      end
      calculatedAngle = calculatedAngle % 360
 
      local DirectionModule2D = math.sqrt(Direction.x^2 + Direction.y^2)
      Direction.x = -DirectionModule2D*math.cos(math.rad(calculatedAngle))
      Direction.y = DirectionModule2D*math.sin(math.rad(calculatedAngle))
    end
  end
 
  if Direction:Module() == 0 then
 self.extraVelocity = { x = 0, y = 0, z = 0 }
  end
 
  -- Set the new velocity
  setElementVelocity(localPlayer, Direction.x + self.extraVelocity.x,
                                  Direction.y + self.extraVelocity.y,
          Direction.z + self.extraVelocity.z)
 
  if self.extraVelocity.z > 0 then
    self.extraVelocity.z = self.extraVelocity.z - 1
 if self.extraVelocity.z < 0 then self.extraVelocity.z = 0 end
  elseif self.extraVelocity.z < 0 then
 self.extraVelocity.z = self.extraVelocity.z + 1
 if self.extraVelocity.z > 0 then self.extraVelocity.z = 0 end
  end
end
 
 
 
--
-- Players flight processing
--
function Superman.processFlight()
  local self = Superman
 
  for player in iterateFlyingPlayers() do
    local Velocity = Vector3D:new(getElementVelocity(player))
    local distanceToBase = getElementDistanceFromCentreOfMassToBaseOfModel(player)
    local playerPos = Vector3D:new(getElementPosition(player))
    playerPos.z = playerPos.z - distanceToBase
 
    local distanceToGround
    if playerPos.z > 0 then
      local hit, hitX, hitY, hitZ, hitElement = processLineOfSight(playerPos.x, playerPos.y, playerPos.z,
                                                                   playerPos.x, playerPos.y, playerPos.z - LANDING_DISTANCE - 1,
                                                                   true, true, true, true, true, false, false, false)
      if hit then distanceToGround = playerPos.z - hitZ end
    end
 
    if distanceToGround and distanceToGround < GROUND_ZERO_TOLERANCE then
      self:restorePlayer(player)
      if player == localPlayer then
       setGravity(serverGravity)
        triggerServerEvent("superman:stop", getRootElement())
      end
    elseif distanceToGround and distanceToGround < LANDING_DISTANCE then
      self:processLanding(player, Velocity, distanceToGround)
    elseif Velocity:Module() < ZERO_TOLERANCE then
      self:processIdleFlight(player)
    else
      self:processMovingFlight(player, Velocity)
    end
  end
end
 
function Superman:processIdleFlight(player)
  -- Set the proper animation on the player
  local animLib, animName = getPedAnimation(player)
  if animLib ~= IDLE_ANIMLIB or animName ~= IDLE_ANIMATION then
    setPedAnimation(player, IDLE_ANIMLIB, IDLE_ANIMATION, -1, IDLE_ANIM_LOOP, false, false)
  end
 
  setElementCollisionsEnabled(player, false)
 
  -- If this is myself, calculate the ped rotation depending on the camera rotation
  if player == localPlayer then
    local cameraX, cameraY, cameraZ, lookX, lookY, lookZ = getCameraMatrix()
    local Sight = Vector3D:new(lookX - cameraX, lookY - cameraY, lookZ - cameraZ)
    Sight:Normalize()
    if getControlState("look_behind") then
      Sight = Sight:Mul(-1)
    end
 
    Sight.z = math.atan(Sight.x / Sight.y)
    if Sight.y > 0 then
      Sight.z = Sight.z + math.pi
    end
    Sight.z = math.deg(Sight.z) + 180
 
    setPedRotation(localPlayer, Sight.z)
    setElementRotation(localPlayer, 0, 0, Sight.z)
  else
    local Zangle = getPedCameraRotation(player)
    setPedRotation(player, Zangle)
    setElementRotation(player, 0, 0, Zangle)
  end
end
 
function Superman:processMovingFlight(player, Velocity)
  -- Set the proper animation on the player
  local animLib, animName = getPedAnimation(player)
  if animLib ~= FLIGHT_ANIMLIB or animName ~= FLIGHT_ANIMATION then
    setPedAnimation(player, FLIGHT_ANIMLIB, FLIGHT_ANIMATION, -1, FLIGHT_ANIM_LOOP, true, false)
  end
 
  if player == localPlayer then
    setElementCollisionsEnabled(player, true)
  else
    setElementCollisionsEnabled(player, false)
  end
 
  -- Calculate the player rotation depending on their velocity
  local Rotation = Vector3D:new(0, 0, 0)
  if Velocity.x == 0 and Velocity.y == 0 then
    Rotation.z = getPedRotation(player)
  else
    Rotation.z = math.deg(math.atan(Velocity.x / Velocity.y))
    if Velocity.y > 0 then
      Rotation.z = Rotation.z - 180
    end
    Rotation.z = (Rotation.z + 180) % 360
  end
  Rotation.x = -math.deg(Velocity.z / Velocity:Module() * 1.2)
 
  -- Rotation compensation for the self animation rotation
  Rotation.x = Rotation.x - 40
 
  -- Calculate the Y rotation for barrel rotations
  if not self.rotations[player] then self.rotations[player] = 0 end
  if not self.previousVelocity[player] then self.previousVelocity[player] = Vector3D:new(0, 0, 0) end
 
  local previousAngle = getVector2DAngle(self.previousVelocity[player])
  local currentAngle = getVector2DAngle(Velocity)
  local diff = angleDiff(currentAngle, previousAngle)
  if isnan(diff) then
 diff = 0
  end
  local calculatedYRotation = -diff * MAX_Y_ROTATION / MAX_ANGLE_SPEED
 
  if calculatedYRotation > self.rotations[player] then
    if calculatedYRotation - self.rotations[player] > ROTATION_Y_SPEED then
      self.rotations[player] = self.rotations[player] + ROTATION_Y_SPEED
    else
      self.rotations[player] = calculatedYRotation
    end
  else
    if self.rotations[player] - calculatedYRotation > ROTATION_Y_SPEED then
      self.rotations[player] = self.rotations[player] - ROTATION_Y_SPEED
    else
      self.rotations[player] = calculatedYRotation
    end
  end
 
  if self.rotations[player] > MAX_Y_ROTATION then
    self.rotations[player] = MAX_Y_ROTATION
  elseif self.rotations[player] < -MAX_Y_ROTATION then
    self.rotations[player] = -MAX_Y_ROTATION
  elseif math.abs(self.rotations[player]) < ZERO_TOLERANCE then
    self.rotations[player] = 0
  end
  Rotation.y = self.rotations[player]
 
  -- Apply the calculated rotation
  setPedRotation(player, Rotation.z)
  setElementRotation(player, Rotation.x, Rotation.y, Rotation.z)
 
  -- Save the current velocity
  self.previousVelocity[player] = Velocity
 
  -- If the speed is over the given value, create the smoke generators
  if Velocity:Module() > (SMOKING_SPEED - ZERO_TOLERANCE) and not isPedInWater(player) then
    self:createSmokeGenerators(player)
  else
    self:destroySmokeGenerators(player)
  end
end
 
function Superman:processLanding(player, Velocity, distanceToGround)
  -- Set the proper animation on the player
  local animLib, animName = getPedAnimation(player)
  if animLib ~= FLIGHT_ANIMLIB or animName ~= FLIGHT_ANIMATION then
    setPedAnimation(player, FLIGHT_ANIMLIB, FLIGHT_ANIMATION, -1, FLIGHT_ANIM_LOOP, true, false)
  end
 
  if player == localPlayer then
    setElementCollisionsEnabled(player, true)
  else
    setElementCollisionsEnabled(player, false)
  end
 
  -- If the speed is over the given value, create the smoke generators
  if Velocity:Module() > (SMOKING_SPEED - ZERO_TOLERANCE) and not isPedInWater(player) then
    self:createSmokeGenerators(player)
  else
    self:destroySmokeGenerators(player)
  end
 
  -- Calculate the player rotation depending on their velocity and distance to ground
  local Rotation = Vector3D:new(0, 0, 0)
  if Velocity.x == 0 and Velocity.y == 0 then
    Rotation.z = getPedRotation(player)
  else
    Rotation.z = math.deg(math.atan(Velocity.x / Velocity.y))
    if Velocity.y > 0 then
      Rotation.z = Rotation.z - 180
    end
    Rotation.z = (Rotation.z + 180) % 360
  end
  Rotation.x = -(85 - (distanceToGround * 85 / LANDING_DISTANCE))
 
  -- Rotation compensation for the self animation rotation
  Rotation.x = Rotation.x - 40
 
  -- Apply the calculated rotation
  setPedRotation(player, Rotation.z)
  setElementRotation(player, Rotation.x, Rotation.y, Rotation.z)
end
 
 
 
--
-- Vectors
--
Vector3D = {
  new = function(self, _x, _y, _z)
    local newVector = { x = _x or 0.0, y = _y or 0.0, z = _z or 0.0 }
    return setmetatable(newVector, { __index = Vector3D })
  end,
 
  Copy = function(self)
    return Vector3D:new(self.x, self.y, self.z)
  end,
 
  Normalize = function(self)
    local mod = self:Module()
    if mod ~= 0 then
      self.x = self.x / mod
      self.y = self.y / mod
      self.z = self.z / mod
    end
  end,
 
  Dot = function(self, V)
    return self.x * V.x + self.y * V.y + self.z * V.z
  end,
 
  Module = function(self)
    return math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
  end,
 
  AddV = function(self, V)
    return Vector3D:new(self.x + V.x, self.y + V.y, self.z + V.z)
  end,
 
  SubV = function(self, V)
    return Vector3D:new(self.x - V.x, self.y - V.y, self.z - V.z)
  end,
 
  CrossV = function(self, V)
    return Vector3D:new(self.y * V.z - self.z * V.y,
                        self.z * V.x - self.x * V.z,
                        self.x * V.y - self.y * V.z)
  end,
 
  Mul = function(self, n)
    return Vector3D:new(self.x * n, self.y * n, self.z * n)
  end,
 
  Div = function(self, n)
    return Vector3D:new(self.x / n, self.y / n, self.z / n)
  end,
 
  MulV = function(self, V)
    return Vector3D:new(self.x * V.x, self.y * V.y, self.z * V.z)
  end,
 
  DivV = function(self, V)
    return Vector3D:new(self.x / V.x, self.y / V.y, self.z / V.z)
  end,
}
 
esta el server.lua y supongo que ahí entra la edición para poder poner solo para admins
local Superman = {}
 
-- Static global values
local rootElement = getRootElement()
local thisResource = getThisResource()
 
-- Resource events
addEvent("superman:start", true)
addEvent("superman:stop", true)
 
--
-- Start/stop functions
--
function Superman.Start()
  local self = Superman
 
  addEventHandler("superman:start", rootElement, self.clientStart)
  addEventHandler("superman:stop", rootElement, self.clientStop)
end
addEventHandler("onResourceStart", getResourceRootElement(thisResource), Superman.Start, false)
 
function Superman.clientStart()
  setElementData(client, "superman:flying", true)
end
 
function Superman.clientStop()
  setElementData(client, "superman:flying", false)
end
 
y la meta que dice esto

 

<meta>
  <info author="Alberto Alonso (ryden)" version="1.0" type="script" />
  <script src="server.lua" type="server" />
  <script src="client.lua" type="client" />
</meta>

 

que edito?

Link to comment
  1. ----Corregido debes crear un team llamado , Staff o Admin ... Luego al estar en ese team podran usar /superman o saltar 2 veces y listo
  2. local Superman = {}
  3.  
  4. -- Settings
  5. local ZERO_TOLERANCE = 0.00001
  6. local MAX_ANGLE_SPEED = 6 -- In degrees per frame
  7. local MAX_SPEED = 1.3
  8. local EXTRA_SPEED_FACTOR = 2.6
  9. local LOW_SPEED_FACTOR = 0.40
  10. local ACCELERATION = 0.025
  11. local EXTRA_ACCELERATION_FACTOR = 1.8
  12. local LOW_ACCELERATION_FACTOR = 0.85
  13. local TAKEOFF_VELOCITY = 1.75
  14. local TAKEOFF_FLIGHT_DELAY = 750
  15. local SMOKING_SPEED = 1000 -- change back to 1.25 to enable smoke creation, disabled due to FPS lag concerns
  16. local GROUND_ZERO_TOLERANCE = 0.18
  17. local LANDING_DISTANCE = 3.2
  18. local FLIGHT_ANIMLIB = "swim"
  19. local FLIGHT_ANIMATION = "Swim_Dive_Under"
  20. local FLIGHT_ANIM_LOOP = false
  21. local IDLE_ANIMLIB = "cop_ambient"
  22. local IDLE_ANIMATION = "Coplook_loop"
  23. local IDLE_ANIM_LOOP = true
  24. local MAX_Y_ROTATION = 70
  25. local ROTATION_Y_SPEED = 3.8
  26.  
  27. -- Static global variables
  28. local thisResource = getThisResource()
  29. local rootElement = getRootElement()
  30. local localPlayer = getLocalPlayer()
  31. local serverGravity = getGravity()
  32.  
  33.  
  34. --
  35. -- Utility functions
  36. --
  37. local function isPlayerFlying(player)
  38.   local data = getElementData(player, "superman:flying")
  39.   if not data or data == false then return false
  40.   else return true end
  41. end
  42.  
  43. local function setPlayerFlying(player, state)
  44.   if state == true then state = true
  45.   else state = false end
  46.  
  47.   setElementData(player, "superman:flying", state)
  48. end
  49.  
  50. local function iterateFlyingPlayers()
  51.   local current = 1
  52.   local allPlayers = getElementsByType("player")
  53.  
  54.   return function()
  55.     local player
  56.  
  57.     repeat
  58.       player = allPlayers[current]
  59.       current = current + 1
  60.     until not player or (isPlayerFlying(player) and isElementStreamedIn(player))
  61.  
  62.     return player
  63.   end
  64. end
  65.  
  66. function Superman:restorePlayer(player)
  67.   setPlayerFlying(player, false)
  68.   setPedAnimation(player, false)
  69.   setElementVelocity(player, 0, 0, 0)
  70.   setElementRotation(player, 0, 0, 0)
  71.   --setPedRotation(player, getPedRotation(player))
  72.   setElementCollisionsEnabled(player, true)
  73.   self:destroySmokeGenerators(player)
  74.   self.rotations[player] = nil
  75.   self.previousVelocity[player] = nil
  76. end
  77.  
  78. function Superman:createSmokeGenerator(player)
  79.   local generator = createObject(2780, getElementPosition(player))
  80.   setElementCollisionsEnabled(generator, false)
  81.   setObjectScale(generator, 0)
  82.   return generator
  83. end
  84.  
  85. function Superman:createSmokeGenerators(player)
  86.   if not self.smokeGenerators[player] then
  87.     local smokeGenerators = {}
  88.  
  89.     smokeGenerators[1] = self:createSmokeGenerator(player)
  90.     attachElements(smokeGenerators[1], player, 0.75, -0.2, -0.4, -40, 0, 60)
  91.     smokeGenerators[2] = self:createSmokeGenerator(player)
  92.     attachElements(smokeGenerators[2], player, -0.75, -0.2, -0.4, -40, 0, -60)
  93.  
  94.     self.smokeGenerators[player] = smokeGenerators
  95.   end
  96. end
  97.  
  98. function Superman:destroySmokeGenerators(player)
  99.   if self.smokeGenerators[player] then
  100.     for k, v in ipairs(self.smokeGenerators[player]) do
  101.       destroyElement(v)
  102.     end
  103.     self.smokeGenerators[player] = nil
  104.   end
  105. end
  106.  
  107. function angleDiff(angle1, angle2)
  108.   angle1, angle2 = angle1 % 360, angle2 % 360
  109.   local diff = (angle1 - angle2) % 360
  110.   if diff <= 180 then
  111.     return diff
  112.   else
  113.     return -(360 - diff)
  114.   end
  115. end
  116.  
  117. local function isElementInWater(ped)
  118.   local pedPosition = Vector3D:new(getElementPosition(ped))
  119.   if pedPosition.z <= 0 then return true end
  120.  
  121.   local waterLevel = getWaterLevel(pedPosition.x, pedPosition.y, pedPosition.z)
  122.   if not isElementStreamedIn(ped) or not waterLevel or waterLevel < pedPosition.z then
  123.     return false
  124.   else
  125.     return true
  126.   end
  127. end
  128.  
  129. local function isnan(x)
  130.     math.inf = 1/0
  131.     if x == math.inf or x == -math.inf or x ~= x then
  132.         return true
  133.     end
  134.     return false
  135. end
  136.  
  137. local function getVector2DAngle(vec)
  138.   if vec.x == 0 and vec.y == 0 then return 0 end
  139.   local angle = math.deg(math.atan(vec.x / vec.y)) + 90
  140.   if vec.y < 0 then
  141.     angle = angle + 180
  142.   end
  143.   return angle
  144. end
  145.  
  146. --
  147. -- Initialization and shutdown functions
  148. --
  149. function Superman.Start()
  150.   local self = Superman
  151.  
  152.   --Initializate custom events
  153.   addEvent("superman:updateRight",true)
  154.  
  155.   -- Register events
  156.   addEventHandler("onClientResourceStop", getResourceRootElement(thisResource), Superman.Stop, false)
  157.   addEventHandler("onPlayerJoin", rootElement, Superman.onJoin)
  158.   addEventHandler("onPlayerQuit", rootElement, Superman.onQuit)
  159.   addEventHandler("onClientRender", rootElement, Superman.processControls)
  160.   addEventHandler("onClientRender", rootElement, Superman.processFlight)
  161.   addEventHandler("onClientPlayerDamage", localPlayer, Superman.onDamage, false)
  162.   addEventHandler("onClientPlayerVehicleEnter",localPlayer,Superman.onEnter)
  163.   addEventHandler("onClientElementDataChange", rootElement, Superman.onDataChange)
  164.   addEventHandler("onClientElementStreamIn", rootElement, Superman.onStreamIn)
  165.   addEventHandler("onClientElementStreamOut", rootElement, Superman.onStreamOut)
  166.   addEventHandler("superman:updateRight",rootElement,Superman.updateRight)
  167.  
  168.   -- Bind keys
  169.   bindKey("jump", "down", Superman.onJump)
  170.  
  171.   -- Register commands
  172.   addCommandHandler("superman", Superman.cmdSuperman)
  173.  
  174.   -- Initializate attributes
  175.   self.smokeGenerators = {}
  176.   self.rotations = {}
  177.   self.previousVelocity = {}
  178.  
  179.   --Check right
  180.   triggerServerEvent("superman:checkRight",localPlayer)
  181. end
  182. addEventHandler("onClientResourceStart", getResourceRootElement(thisResource), Superman.Start, false)
  183.  
  184. function Superman.Stop()
  185.   local self = Superman
  186.  
  187.   setGravity(serverGravity)
  188.  
  189.   -- Restore all players animations, collisions, etc
  190.   for player in iterateFlyingPlayers() do
  191.     self:restorePlayer(player)
  192.   end
  193. end
  194.  
  195.  
  196.  
  197. --
  198. -- Join/Quit
  199. --
  200. function Superman.onJoin(player)
  201.   local self = Superman
  202.   local player = player or source
  203.  
  204.   setPlayerFlying(player, false)
  205. end
  206.  
  207. function Superman.onQuit(reason, player)
  208.   local self = Superman
  209.   local player = player or source
  210.  
  211.   if isPlayerFlying(player) then
  212.     self:restorePlayer(player)
  213.   end
  214. end
  215.  
  216. --
  217. --onEnter: superman cant enter vehicles
  218. -- Fix (in serverside) for players glitching other players' vehicles by warping into them while superman is active, causing them to flinch into air and get stuck.
  219.  
  220. function showWarning()
  221.  
  222.     local x,y,z = getPedBonePosition(localPlayer,6)
  223.     local sx,sy,dist = getScreenFromWorldPosition(x,y,z+0.3)
  224.    
  225.     if sx and sy and dist and dist < 100 then
  226.         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")
  227.     end
  228.  
  229. end
  230.  
  231. function hideWarning()
  232.  
  233.     removeEventHandler("onClientRender",root,showWarning)
  234.  
  235. end
  236.  
  237. function Superman.onEnter()
  238.  
  239.     if (isPlayerFlying(localPlayer) or getElementData(localPlayer,"superman:takingOff")) and not isTimer(warningTimer) then
  240.         addEventHandler("onClientRender",root,showWarning)
  241.         warningTimer = setTimer(hideWarning,5000,1)
  242.     end
  243.  
  244. end
  245.  
  246. --
  247. --updateRight: Update right state of player
  248. --
  249.  
  250. function Superman.updateRight(state)
  251.  
  252.     IS_ALLOWED = state
  253.  
  254. end
  255.  
  256. --
  257. -- onDamage: superman is invulnerable
  258. --
  259. function Superman.onDamage()
  260.   local self = Superman
  261.  
  262.   if isPlayerFlying(localPlayer) then
  263.     cancelEvent()
  264.   end
  265. end
  266.  
  267.  
  268. --
  269. -- onStreamIn: Reset rotation attribute for player
  270. --
  271. function Superman.onStreamIn()
  272.   local self = Superman
  273. end
  274.  
  275. function Superman.onStreamOut()
  276.   local self = Superman
  277.  
  278.   if source and isElement(source) and getElementType(source) == "player" and isPlayerFlying(source) then
  279.     self.rotations[source] = nil
  280.     self.previousVelocity[source] = nil
  281.   end
  282. end
  283.  
  284. --
  285. -- onDataChange: Check if somebody who is out of stream stops being superman
  286. --
  287. function Superman.onDataChange(dataName, oldValue)
  288.   local self = Superman
  289.  
  290.   if dataName == "superman:flying" and isElement(source) and getElementType(source) == "player" and
  291.      oldValue ~= getElementData(source, dataName) and oldValue == true and getElementData(source, dataName) == false then
  292.     self:restorePlayer(source)
  293.   end
  294. end
  295.  
  296. --
  297. -- onJump: Combo to start flight without any command
  298. --
  299. function Superman.onJump(key, keyState)
  300.   if not getElementData(localPlayer, "class") then return end
  301.   if getElementData(localPlayer, "class") ~= "Staff" and getElementData(localPlayer, "class") ~= "Admin" then return end
  302.   if not getPlayerTeam(localPlayer) then return end
  303.   if getTeamName(getPlayerTeam(localPlayer)) ~= "Admins" then return end
  304.  
  305.   local self = Superman
  306.  
  307.   local task = getPedSimplestTask(localPlayer)
  308.   if not isPlayerFlying(localPlayer) then
  309.     if task == "TASK_SIMPLE_IN_AIR" then
  310.       setElementVelocity(localPlayer, 0, 0, TAKEOFF_VELOCITY)
  311.       setTimer(Superman.startFlight, 100, 1)
  312.     end
  313.   end
  314. end
  315.  
  316. --
  317. -- Commands
  318. --
  319. function Superman.cmdSuperman()
  320.   if not getElementData(localPlayer, "class") then return end
  321.   if getElementData(localPlayer, "class") ~= "Staff" and getElementData(localPlayer, "class") ~= "Admin" then return end
  322.   if not getPlayerTeam(localPlayer) then return end
  323.   if getTeamName(getPlayerTeam(localPlayer)) ~= "Admins" then return end
  324.  
  325.   local self = Superman
  326.  
  327.   if isPedInVehicle(localPlayer) or isPlayerFlying(localPlayer) then return end
  328.   setElementVelocity(localPlayer, 0, 0, TAKEOFF_VELOCITY)
  329.   setTimer(Superman.startFlight, TAKEOFF_FLIGHT_DELAY, 1)
  330.   setElementData(localPlayer,"superman:takingOff",true)
  331. end
  332.  
  333. function Superman.startFlight()
  334.   local self = Superman
  335.  
  336.   setElementData(localPlayer,"superman:takingOff",false)
  337.   if isPlayerFlying(localPlayer) then return end
  338.  
  339.   triggerServerEvent("superman:start", rootElement)
  340.   setPlayerFlying(localPlayer, true)
  341.   setElementVelocity(localPlayer, 0, 0, 0)
  342.   self.currentSpeed = 0
  343.   self.extraVelocity = { x = 0, y = 0, z = 0 }
  344. end
  345.  
  346.  
  347. --
  348. -- Controls processing
  349. --
  350. local jump, oldJump = false, false
  351. function Superman.processControls()
  352.   local self = Superman
  353.  
  354.   if not isPlayerFlying(localPlayer) then
  355.     jump, oldJump = getPedControlState("jump"), jump
  356.     if not oldJump and jump then
  357.       Superman.onJump()
  358.     end
  359.     return
  360.   end
  361.  
  362.   -- Calculate the requested movement direction
  363.   local Direction = Vector3D:new(0, 0, 0)
  364.   if getPedControlState("forwards") then
  365.     Direction.y = 1
  366.   elseif getPedControlState("backwards") then
  367.     Direction.y = -1
  368.   end
  369.  
  370.   if getPedControlState("left") then
  371.     Direction.x = 1
  372.   elseif getPedControlState("right") then
  373.     Direction.x = -1
  374.   end
  375.   Direction:Normalize()
  376.  
  377.   -- Calculate the sight direction
  378.   local cameraX, cameraY, cameraZ, lookX, lookY, lookZ = getCameraMatrix()
  379.   local SightDirection = Vector3D:new((lookX - cameraX), (lookY - cameraY), (lookZ - cameraZ))
  380.   SightDirection:Normalize()
  381.   if getPedControlState("look_behind") then
  382.     SightDirection = SightDirection:Mul(-1)
  383.   end
  384.  
  385.   -- Calculate the current max speed and acceleration values
  386.   local maxSpeed = MAX_SPEED
  387.   local acceleration = ACCELERATION
  388.   if getPedControlState("sprint") then
  389.     maxSpeed = MAX_SPEED * EXTRA_SPEED_FACTOR
  390.     acceleration = acceleration * EXTRA_ACCELERATION_FACTOR
  391.   elseif getPedControlState("walk") then
  392.     maxSpeed = MAX_SPEED * LOW_SPEED_FACTOR
  393.     acceleration = acceleration * LOW_ACCELERATION_FACTOR
  394.   end
  395.  
  396.   local DirectionModule = Direction:Module()
  397.  
  398.   -- Check if we must change the gravity
  399.   if DirectionModule == 0 and self.currentSpeed ~= 0 then
  400.     setGravity(0)
  401.   else
  402.     setGravity(serverGravity)
  403.   end
  404.  
  405.   -- Calculate the new current speed
  406.   if self.currentSpeed ~= 0 and (DirectionModule == 0 or self.currentSpeed > maxSpeed) then
  407.     -- deccelerate
  408.     self.currentSpeed = self.currentSpeed - acceleration
  409.     if self.currentSpeed < 0 then self.currentSpeed = 0 end
  410.  
  411.   elseif DirectionModule ~= 0 and self.currentSpeed < maxSpeed then
  412.     -- accelerate
  413.     self.currentSpeed = self.currentSpeed + acceleration
  414.     if self.currentSpeed > maxSpeed then self.currentSpeed = maxSpeed end
  415.  
  416.   end
  417.  
  418.   -- Calculate the movement requested direction
  419.   if DirectionModule ~= 0 then
  420.     Direction = Vector3D:new(SightDirection.x * Direction.y - SightDirection.y * Direction.x,
  421.                              SightDirection.x * Direction.x + SightDirection.y * Direction.y,
  422.                              SightDirection.z * Direction.y)
  423.     -- Save the last movement direction for when player releases all direction keys
  424.     self.lastDirection = Direction
  425.   else
  426.     -- Player is not specifying any direction, use last known direction or the current velocity
  427.     if self.lastDirection then
  428.       Direction = self.lastDirection
  429.       if self.currentSpeed == 0 then self.lastDirection = nil end
  430.     else
  431.       Direction = Vector3D:new(getElementVelocity(localPlayer))
  432.     end
  433.   end
  434.   Direction:Normalize()
  435.   Direction = Direction:Mul(self.currentSpeed)
  436.  
  437.   -- Applicate a smooth direction change, if moving
  438.   if self.currentSpeed > 0 then
  439.     local VelocityDirection = Vector3D:new(getElementVelocity(localPlayer))
  440.     VelocityDirection:Normalize()
  441.  
  442.     if math.sqrt(VelocityDirection.x^2 + VelocityDirection.y^2) > 0 then
  443.       local DirectionAngle = getVector2DAngle(Direction)
  444.       local VelocityAngle = getVector2DAngle(VelocityDirection)
  445.  
  446.       local diff = angleDiff(DirectionAngle, VelocityAngle)
  447.       local calculatedAngle
  448.  
  449.       if diff >= 0 then
  450.         if diff > MAX_ANGLE_SPEED then
  451.           calculatedAngle = VelocityAngle + MAX_ANGLE_SPEED
  452.     else
  453.       calculatedAngle = DirectionAngle
  454.     end
  455.       else
  456.         if diff < MAX_ANGLE_SPEED then
  457.           calculatedAngle = VelocityAngle - MAX_ANGLE_SPEED
  458.     else
  459.           calculatedAngle = DirectionAngle
  460.         end
  461.       end
  462.       calculatedAngle = calculatedAngle % 360
  463.  
  464.       local DirectionModule2D = math.sqrt(Direction.x^2 + Direction.y^2)
  465.       Direction.x = -DirectionModule2D*math.cos(math.rad(calculatedAngle))
  466.       Direction.y = DirectionModule2D*math.sin(math.rad(calculatedAngle))
  467.     end
  468.   end
  469.  
  470.   if Direction:Module() == 0 then
  471.     self.extraVelocity = { x = 0, y = 0, z = 0 }
  472.   end
  473.  
  474.   -- Set the new velocity
  475.   setElementVelocity(localPlayer, Direction.x + self.extraVelocity.x,
  476.                                   Direction.y + self.extraVelocity.y,
  477.                                   Direction.z + self.extraVelocity.z)
  478.  
  479.   if self.extraVelocity.z > 0 then
  480.     self.extraVelocity.z = self.extraVelocity.z - 1
  481.     if self.extraVelocity.z < 0 then self.extraVelocity.z = 0 end
  482.   elseif self.extraVelocity.z < 0 then
  483.     self.extraVelocity.z = self.extraVelocity.z + 1
  484.     if self.extraVelocity.z > 0 then self.extraVelocity.z = 0 end
  485.   end
  486. end
  487.  
  488.  
  489.  
  490. --
  491. -- Players flight processing
  492. --
  493. function Superman.processFlight()
  494.   local self = Superman
  495.  
  496.   for player in iterateFlyingPlayers() do
  497.     local Velocity = Vector3D:new(getElementVelocity(player))
  498.     local distanceToBase = getElementDistanceFromCentreOfMassToBaseOfModel(player)
  499.     local playerPos = Vector3D:new(getElementPosition(player))
  500.     playerPos.z = playerPos.z - distanceToBase
  501.  
  502.     local distanceToGround
  503.     if playerPos.z > 0 then
  504.       local hit, hitX, hitY, hitZ, hitElement = processLineOfSight(playerPos.x, playerPos.y, playerPos.z,
  505.                                                                    playerPos.x, playerPos.y, playerPos.z - LANDING_DISTANCE - 1,
  506.                                                                    true, true, true, true, true, false, false, false)
  507.       if hit then distanceToGround = playerPos.z - hitZ end
  508.     end
  509.  
  510.     if distanceToGround and distanceToGround < GROUND_ZERO_TOLERANCE then
  511.       self:restorePlayer(player)
  512.       if player == localPlayer then
  513.         setGravity(serverGravity)
  514.         triggerServerEvent("superman:stop", getRootElement())
  515.       end
  516.     elseif distanceToGround and distanceToGround < LANDING_DISTANCE then
  517.       self:processLanding(player, Velocity, distanceToGround)
  518.     elseif Velocity:Module() < ZERO_TOLERANCE then
  519.       self:processIdleFlight(player)
  520.     else
  521.       self:processMovingFlight(player, Velocity)
  522.     end
  523.   end
  524. end
  525.  
  526. function Superman:processIdleFlight(player)
  527.   -- Set the proper animation on the player
  528.   local animLib, animName = getPedAnimation(player)
  529.   if animLib ~= IDLE_ANIMLIB or animName ~= IDLE_ANIMATION then
  530.     setPedAnimation(player, IDLE_ANIMLIB, IDLE_ANIMATION, -1, IDLE_ANIM_LOOP, false, false)
  531.   end
  532.  
  533.   setElementCollisionsEnabled(player, false)
  534.  
  535.   -- If this is myself, calculate the ped rotation depending on the camera rotation
  536.   if player == localPlayer then
  537.     local cameraX, cameraY, cameraZ, lookX, lookY, lookZ = getCameraMatrix()
  538.     local Sight = Vector3D:new(lookX - cameraX, lookY - cameraY, lookZ - cameraZ)
  539.     Sight:Normalize()
  540.     if getPedControlState("look_behind") then
  541.       Sight = Sight:Mul(-1)
  542.     end
  543.  
  544.     Sight.z = math.atan(Sight.x / Sight.y)
  545.     if Sight.y > 0 then
  546.       Sight.z = Sight.z + math.pi
  547.     end
  548.     Sight.z = math.deg(Sight.z) + 180
  549.  
  550.     setPedRotation(localPlayer, Sight.z)
  551.     setElementRotation(localPlayer, 0, 0, Sight.z)
  552.   else
  553.     local Zangle = getPedCameraRotation(player)
  554.     setPedRotation(player, Zangle)
  555.     setElementRotation(player, 0, 0, Zangle)
  556.   end
  557. end
  558.  
  559. function Superman:processMovingFlight(player, Velocity)
  560.   -- Set the proper animation on the player
  561.   local animLib, animName = getPedAnimation(player)
  562.   if animLib ~= FLIGHT_ANIMLIB or animName ~= FLIGHT_ANIMATION then
  563.     setPedAnimation(player, FLIGHT_ANIMLIB, FLIGHT_ANIMATION, -1, FLIGHT_ANIM_LOOP, true, false)
  564.   end
  565.  
  566.   if player == localPlayer then
  567.     setElementCollisionsEnabled(player, true)
  568.   else
  569.     setElementCollisionsEnabled(player, false)
  570.   end
  571.  
  572.   -- Calculate the player rotation depending on their velocity
  573.   local Rotation = Vector3D:new(0, 0, 0)
  574.   if Velocity.x == 0 and Velocity.y == 0 then
  575.     Rotation.z = getPedRotation(player)
  576.   else
  577.     Rotation.z = math.deg(math.atan(Velocity.x / Velocity.y))
  578.     if Velocity.y > 0 then
  579.       Rotation.z = Rotation.z - 180
  580.     end
  581.     Rotation.z = (Rotation.z + 180) % 360
  582.   end
  583.   Rotation.x = -math.deg(Velocity.z / Velocity:Module() * 1.2)
  584.  
  585.   -- Rotation compensation for the self animation rotation
  586.   Rotation.x = Rotation.x - 40
  587.  
  588.   -- Calculate the Y rotation for barrel rotations
  589.   if not self.rotations[player] then self.rotations[player] = 0 end
  590.   if not self.previousVelocity[player] then self.previousVelocity[player] = Vector3D:new(0, 0, 0) end
  591.  
  592.   local previousAngle = getVector2DAngle(self.previousVelocity[player])
  593.   local currentAngle = getVector2DAngle(Velocity)
  594.   local diff = angleDiff(currentAngle, previousAngle)
  595.   if isnan(diff) then
  596.     diff = 0
  597.   end
  598.   local calculatedYRotation = -diff * MAX_Y_ROTATION / MAX_ANGLE_SPEED
  599.  
  600.   if calculatedYRotation > self.rotations[player] then
  601.     if calculatedYRotation - self.rotations[player] > ROTATION_Y_SPEED then
  602.       self.rotations[player] = self.rotations[player] + ROTATION_Y_SPEED
  603.     else
  604.       self.rotations[player] = calculatedYRotation
  605.     end
  606.   else
  607.     if self.rotations[player] - calculatedYRotation > ROTATION_Y_SPEED then
  608.       self.rotations[player] = self.rotations[player] - ROTATION_Y_SPEED
  609.     else
  610.       self.rotations[player] = calculatedYRotation
  611.     end
  612.   end
  613.  
  614.   if self.rotations[player] > MAX_Y_ROTATION then
  615.     self.rotations[player] = MAX_Y_ROTATION
  616.   elseif self.rotations[player] < -MAX_Y_ROTATION then
  617.     self.rotations[player] = -MAX_Y_ROTATION
  618.   elseif math.abs(self.rotations[player]) < ZERO_TOLERANCE then
  619.     self.rotations[player] = 0
  620.   end
  621.   Rotation.y = self.rotations[player]
  622.  
  623.   -- Apply the calculated rotation
  624.   setPedRotation(player, Rotation.z)
  625.   setElementRotation(player, Rotation.x, Rotation.y, Rotation.z)
  626.  
  627.   -- Save the current velocity
  628.   self.previousVelocity[player] = Velocity
  629.  
  630.   -- If the speed is over the given value, create the smoke generators
  631.   if Velocity:Module() > (SMOKING_SPEED - ZERO_TOLERANCE) and not isElementInWater(player) then
  632.     self:createSmokeGenerators(player)
  633.   else
  634.     self:destroySmokeGenerators(player)
  635.   end
  636. end
  637.  
  638. function Superman:processLanding(player, Velocity, distanceToGround)
  639.   -- Set the proper animation on the player
  640.   local animLib, animName = getPedAnimation(player)
  641.   if animLib ~= FLIGHT_ANIMLIB or animName ~= FLIGHT_ANIMATION then
  642.     setPedAnimation(player, FLIGHT_ANIMLIB, FLIGHT_ANIMATION, -1, FLIGHT_ANIM_LOOP, true, false)
  643.   end
  644.  
  645.   if player == localPlayer then
  646.     setElementCollisionsEnabled(player, true)
  647.   else
  648.     setElementCollisionsEnabled(player, false)
  649.   end
  650.  
  651.   -- If the speed is over the given value, create the smoke generators
  652.   if Velocity:Module() > (SMOKING_SPEED - ZERO_TOLERANCE) and not isElementInWater(player) then
  653.     self:createSmokeGenerators(player)
  654.   else
  655.     self:destroySmokeGenerators(player)
  656.   end
  657.  
  658.   -- Calculate the player rotation depending on their velocity and distance to ground
  659.   local Rotation = Vector3D:new(0, 0, 0)
  660.   if Velocity.x == 0 and Velocity.y == 0 then
  661.     Rotation.z = getPedRotation(player)
  662.   else
  663.     Rotation.z = math.deg(math.atan(Velocity.x / Velocity.y))
  664.     if Velocity.y > 0 then
  665.       Rotation.z = Rotation.z - 180
  666.     end
  667.     Rotation.z = (Rotation.z + 180) % 360
  668.   end
  669.   Rotation.x = -(85 - (distanceToGround * 85 / LANDING_DISTANCE))
  670.  
  671.   -- Rotation compensation for the self animation rotation
  672.   Rotation.x = Rotation.x - 40
  673.  
  674.   -- Apply the calculated rotation
  675.   setPedRotation(player, Rotation.z)
  676.   setElementRotation(player, Rotation.x, Rotation.y, Rotation.z)
  677. end
  678.  
  679.  
  680.  
  681. --
  682. -- Vectors
  683. --
  684. Vector3D = {
  685.   new = function(self, _x, _y, _z)
  686.     local newVector = { x = _x or 0.0, y = _y or 0.0, z = _z or 0.0 }
  687.     return setmetatable(newVector, { __index = Vector3D })
  688.   end,
  689.  
  690.   Copy = function(self)
  691.     return Vector3D:new(self.x, self.y, self.z)
  692.   end,
  693.  
  694.   Normalize = function(self)
  695.     local mod = self:Module()
  696.     if mod ~= 0 then
  697.       self.x = self.x / mod
  698.       self.y = self.y / mod
  699.       self.z = self.z / mod
  700.     end
  701.   end,
  702.  
  703.   Dot = function(self, V)
  704.     return self.x * V.x + self.y * V.y + self.z * V.z
  705.   end,
  706.  
  707.   Module = function(self)
  708.     return math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
  709.   end,
  710.  
  711.   AddV = function(self, V)
  712.     return Vector3D:new(self.x + V.x, self.y + V.y, self.z + V.z)
  713.   end,
  714.  
  715.   SubV = function(self, V)
  716.     return Vector3D:new(self.x - V.x, self.y - V.y, self.z - V.z)
  717.   end,
  718.  
  719.   CrossV = function(self, V)
  720.     return Vector3D:new(self.y * V.z - self.z * V.y,
  721.                         self.z * V.x - self.x * V.z,
  722.                         self.x * V.y - self.y * V.z)
  723.   end,
  724.  
  725.   Mul = function(self, n)
  726.     return Vector3D:new(self.x * n, self.y * n, self.z * n)
  727.   end,
  728.  
  729.   Div = function(self, n)
  730.     return Vector3D:new(self.x / n, self.y / n, self.z / n)
  731.   end,
  732.  
  733.   MulV = function(self, V)
  734.     return Vector3D:new(self.x * V.x, self.y * V.y, self.z * V.z)
  735.   end,
  736.  
  737.   DivV = function(self, V)
  738.     return Vector3D:new(self.x / V.x, self.y / V.y, self.z / V.z)
  739.   end,
  740. }
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...