[YARDIM] Ghost Mode

0 Üye ve 1 Ziyaretçi konuyu incelemekte.

Çevrimdışı 4VCI

  • 4VCI#4969(discord)
  • Acemi Üye
  • *
    • İleti: 177
  • Pertinacious Vargant Stars
    • Pertinacious Vargant Stars
: 29 Mayıs 2017, 11:48:16
Beyler bu sadece race maplarda oluyor bunu nasıl dm maplara uyarlayabilirim.  :)



Client
Spoiler for Hiden:
GhostPlayback = {}
GhostPlayback.__index = GhostPlayback

addEvent( "onClientGhostDataReceive", true )
addEvent( "clearMapGhost", true )

function GhostPlayback:create( recording, ped, vehicle )
   local result = {
      ped = ped,
      vehicle = vehicle,
      recording = recording,
      isPlaying = false,
      startTick = nil,
   }
   setElementCollisionsEnabled( result.ped, false )
   setElementCollisionsEnabled( result.vehicle, false )
   setVehicleFrozen( result.vehicle, true )
   setElementAlpha( result.ped, 100 )
   setElementAlpha( result.vehicle, 100 )
   return setmetatable( result, self )
end

function GhostPlayback:destroy( finished )
   self:stopPlayback( finished )
   if self.checkForCountdownEnd_HANDLER then removeEventHandler( "onClientRender", g_Root, self.checkForCountdownEnd_HANDLER ) self.checkForCountdownEnd_HANDLER = nil end
   if self.updateGhostState_HANDLER then removeEventHandler( "onClientRender", g_Root, self.updateGhostState_HANDLER ) self.updateGhostState_HANDLER = nil end
   if isTimer( self.ghostFinishTimer ) then
      killTimer( self.ghostFinishTimer )
      self.ghostFinishTimer = nil
   end
   self = nil
end

function GhostPlayback:preparePlayback()
   self.checkForCountdownEnd_HANDLER = function() self:checkForCountdownEnd() end
   addEventHandler( "onClientRender", g_Root, self.checkForCountdownEnd_HANDLER )
   self:createNametag()
end

function GhostPlayback:createNametag()
   self.nametagInfo = {
      name = "Ghost (" .. globalInfo.racer .. ")",
      time = msToTimeStr( globalInfo.bestTime )
   }
   self.drawGhostNametag_HANDLER = function() self:drawGhostNametag( self.nametagInfo ) end
   addEventHandler( "onClientRender", g_Root, self.drawGhostNametag_HANDLER )
end

function GhostPlayback:destroyNametag()
   if self.drawGhostNametag_HANDLER then removeEventHandler( "onClientRender", g_Root, self.drawGhostNametag_HANDLER ) self.drawGhostNametag_HANDLER = nil end
end

function GhostPlayback:checkForCountdownEnd()
   local vehicle = getPedOccupiedVehicle( getLocalPlayer() )
   if vehicle then
      local frozen = isVehicleFrozen( vehicle )
      if not frozen then
         outputDebug( "Playback started." )
         setVehicleFrozen( self.vehicle, false )
         if self.checkForCountdownEnd_HANDLER then removeEventHandler( "onClientRender", g_Root, self.checkForCountdownEnd_HANDLER ) self.checkForCountdownEnd_HANDLER = nil end
         self:startPlayback()
      end
   end
end

function GhostPlayback:startPlayback()
   self.startTick = getTickCount()
   self.isPlaying = true
   self.updateGhostState_HANDLER = function() self:updateGhostState() end
   addEventHandler( "onClientRender", g_Root, self.updateGhostState_HANDLER )
end

function GhostPlayback:stopPlayback( finished )
   self:destroyNametag()
   self:resetKeyStates()
   self.isPlaying = false
   if self.updateGhostState_HANDLER then removeEventHandler( "onClientRender", g_Root, self.updateGhostState_HANDLER ) self.updateGhostState_HANDLER = nil end
   if finished then
      self.ghostFinishTimer = setTimer(
         function()
            local blip = getBlipAttachedTo( self.ped )
            if blip then
               setBlipColor( blip, 0, 0, 0, 0 )
            end
            setElementPosition( self.vehicle, 0, 0, 0 )
            setVehicleFrozen( self.vehicle, true )
            setElementAlpha( self.vehicle, 0 )
            setElementAlpha( self.ped, 0 )
         end, 5000, 1
      )
   end
end

function GhostPlayback:updateGhostState()
   self.currentIndex = self.currentIndex or 1
   local ticks = getTickCount() - self.startTick
   setElementHealth( self.ped, 100 ) -- we don't want the ped to die
   while (self.recording[self.currentIndex] and self.recording[self.currentIndex].t < ticks) do
      local theType = self.recording[self.currentIndex].ty
      if theType == "st" then
         -- Skip
      elseif theType == "po" then
         local x, y, z = self.recording[self.currentIndex].x, self.recording[self.currentIndex].y, self.recording[self.currentIndex].z
         local rX, rY, rZ = self.recording[self.currentIndex].rX, self.recording[self.currentIndex].rY, self.recording[self.currentIndex].rZ
         local vX, vY, vZ = self.recording[self.currentIndex].vX, self.recording[self.currentIndex].vY, self.recording[self.currentIndex].vZ
         local lg = self.recording[self.currentIndex].lg
         local health = self.recording[self.currentIndex].h or 1000
         setElementPosition( self.vehicle, x, y, z )
         setElementRotation( self.vehicle, rX, rY, rZ )
         setElementVelocity( self.vehicle, vX, vY, vZ )
         setElementHealth( self.vehicle, health )
         if lg then setVehicleLandingGearDown( self.vehicle, lg ) end
      elseif theType == "k" then
         local control = self.recording[self.currentIndex].k
         local state = self.recording[self.currentIndex].s
         setPedControlState( self.ped, control, state )
      elseif theType == "pi" then
         local item = self.recording[self.currentIndex].i
         if item == "n" then
            addVehicleUpgrade( self.vehicle, 1010 )
         elseif item == "r" then
            fixVehicle( self.vehicle )
         end
      elseif theType == "sp" then
         fixVehicle( self.vehicle )
      elseif theType == "v" then
         local vehicleType = self.recording[self.currentIndex].m
         setElementModel( self.vehicle, vehicleType )
      end
      self.currentIndex = self.currentIndex + 1
      
      if not self.recording[self.currentIndex] then
         self:stopPlayback( true )
      end
   end
end

function GhostPlayback:resetKeyStates()
   if isElement( self.ped ) then
      for _, v in ipairs( keyNames ) do
         setPedControlState( self.ped, v, false )
      end
   end
end

addEventHandler( "onClientGhostDataReceive", g_Root,
   function( recording, bestTime, racer, ped, vehicle )
      if playback then
         playback:destroy()
      end
      
      globalInfo.bestTime = bestTime
      globalInfo.racer = racer
      
      playback = GhostPlayback:create( recording, ped, vehicle )
      playback:preparePlayback()
   end
)

addEventHandler( "clearMapGhost", g_Root,
   function()
      if playback then
         playback:destroy()
         globalInfo.bestTime = math.huge
         globalInfo.racer = ""
      end
   end
)

function getBlipAttachedTo( elem )
   local elements = getAttachedElements( elem )
   for _, element in ipairs( elements ) do
      if getElementType( element ) == "blip" then
         return element
      end
   end
   return false
end

Server
Spoiler for Hiden:
g_Root = getRootElement()

addEvent"onMapStarting"

GhostPlayback = {}
GhostPlayback.__index = GhostPlayback

function GhostPlayback:create( map )
   local result = {
      map = map,
      bestTime = math.huge,
      racer = "",
      recording = {},
      hasGhost = false,
      ped = nil,
      vehicle = nil,
      blip = nil
   }
   return setmetatable( result, self )
end

function GhostPlayback:destroy()
   if self.hasGhost then
      triggerClientEvent( "clearMapGhost", g_Root )
   end
   if isElement( self.ped ) then
      destroyElement( self.ped )
      outputDebug( "Destroyed ped." )
   end
   if isElement( self.vehicle ) then
      destroyElement( self.vehicle )
      outputDebug( "Destroyed vehicle." )
   end
   if isElement( self.blip ) then
      destroyElement( self.blip )
      outputDebug( "Destroyed blip." )
   end
   self = nil
end

function GhostPlayback:loadGhost()
   -- Load the old ghost if there is one
   local mapName = getResourceName( self.map )
   local ghost = xmlLoadFile( "ghosts/" .. mapName .. ".ghost" )
   
   -- Replace with backup if original doesn't exist
   if not ghost then
      local backup = xmlLoadFile( "ghosts/" .. mapName .. ".backup" )
      if backup then
         xmlUnloadFile( backup )
         copyFile( "ghosts/" .. mapName .. ".backup", "ghosts/" .. mapName .. ".ghost" )
         ghost = xmlLoadFile( "ghosts/" .. mapName .. ".ghost" )
         fileDelete( "ghosts/" .. mapName .. ".backup" )
      end
   end
   
   if ghost then
      -- Retrieve info about the ghost maker
      local info = xmlFindChild( ghost, "i", 0 )
      if info then
         self.racer = xmlNodeGetAttribute( info, "r" ) or "unknown"
         self.bestTime = tonumber( xmlNodeGetAttribute( info, "t" ) ) or math.huge
      end
      
      -- Construct a table
      local index = 0
      local node = xmlFindChild( ghost, "n", index )
      while (node) do
         if type( node ) ~= "userdata" then
            outputDebugString( "race_ghost - playback_server.lua: Invalid node data while loading ghost: " .. type( node ) .. ":" .. tostring( node ), 1 )
            break
         end
         
         local attributes = xmlNodeGetAttributes( node )
         local row = {}
         for k, v in pairs( attributes ) do
            row[k] = convert( v )
         end
         table.insert( self.recording, row )
         index = index + 1
         node = xmlFindChild( ghost, "n", index )
      end
      xmlUnloadFile( ghost )
         
      -- Create the ped & vehicle
      for _, v in ipairs( self.recording ) do
         if v.ty == "st" then
            self.ped = createPed( v.p, v.x, v.y, v.z )
            self.vehicle = createVehicle( v.m, v.x, v.y, v.z, v.rX, v.rY, v.rZ )
            self.blip = createBlipAttachedTo( self.ped, 0, 1, 150, 150, 150, 50 )
            setElementParent( self.blip, self.ped )
            warpPedIntoVehicle( self.ped, self.vehicle )
            
            outputDebugString( "Found a valid ghost file for " .. mapName )
            self.hasGhost = true
            return true
         end
      end
      return true
   end
   return false
end

function GhostPlayback:sendGhostData( target )
   if self.hasGhost then
      triggerClientEvent( target or g_Root, "onClientGhostDataReceive", g_Root, self.recording, self.bestTime, self.racer, self.ped, self.vehicle )
   end
end

addEventHandler( "onMapStarting", g_Root,
   function()
      if playback then
         playback:destroy()
      end
      
      playback = GhostPlayback:create( exports.mapmanager:getRunningGamemodeMap() )
      playback:loadGhost()
      playback:sendGhostData()
   end
)

addEventHandler( "onPlayerJoin", g_Root,
   function()
      if playback then
         playback:sendGhostData( source )
      end
   end
)

function convert( value )
   if tonumber( value ) ~= nil then
      return tonumber( value )
   else
      if tostring( value ) == "true" then
         return true
      elseif tostring( value ) == "false" then
         return false
      else
         return tostring( value )
      end
   end
end
« Son Düzenleme: 30 Mayıs 2017, 19:25:26 Gönderen: 4VCI »
[DD/DM] Player
 


MTASATURK

[YARDIM] Ghost Mode
« : 29 Mayıs 2017, 11:48:16 »

Çevrimdışı Paradox

  • Kurucu
  • *
    • İleti: 684
  • SH Gaming
Yanıtla #1 : 02 Haziran 2017, 11:31:06
DM map açınca hata felen veriyormu?
 


Çevrimdışı 4VCI

  • 4VCI#4969(discord)
  • Acemi Üye
  • *
    • İleti: 177
  • Pertinacious Vargant Stars
    • Pertinacious Vargant Stars
Yanıtla #2 : 19 Haziran 2017, 10:45:59
Linki görebilmek için Kayıt olun yada Giriş yapın. Race maplarda oluyor ama dm maplarda olmuyor malesef ne yapabiliriz.

Linki görebilmek için Kayıt olun yada Giriş yapın.
« Son Düzenleme: 19 Haziran 2017, 21:34:13 Gönderen: Narkoz »
[DD/DM] Player