Advertisement
Guest User

Untitled

a guest
Nov 27th, 2023
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.79 KB | None | 0 0
  1. -- kanaRevive - Release 5 - For tes3mp 0.8-alpha
  2. -- Players enter a downed state before dying. Other players can activate them to revive them!
  3.  
  4. --[[ INSTALLATION
  5. = GENERAL =
  6. Save this file as "kanaRevive.lua" in server/custom/scripts
  7.  
  8. = IN CUSTOMSCRIPTS.LUA =
  9. Add this line: kanaRevive = require("custom.kanaRevive")
  10. ]]
  11.  
  12. local scriptConfig = {}
  13.  
  14. scriptConfig.useBleedout = true
  15. scriptConfig.bleedoutTime = 30
  16.  
  17. -- "cell" - Sends the message to anyone who has the cell loaded | "server" - Sends the message to everyone on the server | "none" - Sends the message to nobody else
  18. scriptConfig.playerDownedAnnounceRadius = "server"
  19. scriptConfig.reviveAnnounceRadius = "server"
  20. scriptConfig.playerDiedAnnounceRadius = "server"
  21.  
  22. -- "set" - Set the stat to a fixed number () | "preserve" - keeps the value as it is | "percent" - Set the stat to be a % of its maximum
  23. -- Note for preserve:
  24. scriptConfig.revivedHealthMode = "percent"
  25. scriptConfig.revivedMagickaMode = "preserve"
  26. scriptConfig.revivedFatigueMode = "set"
  27. -- The following are the numbers used if the revive mode is set to "set"
  28. scriptConfig.setModeHealth = 10 -- Obviously, don't use 0 here or they'll be dead...
  29. scriptConfig.setModeMagicka = 0
  30. scriptConfig.setModeFatigue = 0
  31. -- The following are the modifiers used if the revive mode is set to "percent"
  32. -- 0.1 represents 10%. 1 represents 100%
  33. scriptConfig.percentModeHealth = 0.1
  34. scriptConfig.percentModeMagicka = 0.1
  35. scriptConfig.percentModeFatigue = 0.1
  36.  
  37. -- The following are for the custom player markers
  38. -- Currently, if a player is downed in a separate cell, players entering the cell won't see the corpse
  39. -- Using this option, a marker will be created that players can activate instead.
  40. scriptConfig.useMarkers = true
  41. scriptConfig.markerModel = "o/contain_corpse20.nif"
  42. scriptConfig.baseObjectType = "miscellaneous"
  43. scriptConfig.recordRefId = "kanarevivemarker"
  44.  
  45. -- Set the following to true when running a permadeath server to allow players to be downed instead of dying.
  46. scriptConfig.allowReviveWithPermadeath = true
  47.  
  48.  
  49. local lang = {
  50. ["awaitingReviveMessage"] = "You are awaiting revival.",
  51. ["awaitingReviveOtherMessage"] = "%name has been downed! Activate them to revive them.",
  52. ["bleedingOutMessage"] = "You have %seconds seconds before you bleed out.",
  53. ["giveInPrompt"] = "Type /die to give in.",
  54. ["revivedReceiveMessage"] = "You have been revived by %name.",
  55. ["revivedGiveMessage"] = "You have revived %name.",
  56. ["revivedOtherMessage"] = "%receive has been revived by %give.",
  57. ["bleedoutPlayerMessage"] = "You have died.",
  58. ["bleedoutOtherMessage"] = "%name has bled out.",
  59. ["defaultSuicide"] = "%name committed suicide.",
  60. ["defaultKilledByPlayer"] = "%name was killed by player %killer.",
  61. ["defaultKilledByOther"] = "%name was killed by %killer.",
  62. ["defaultPermanentDeath"] = "You have died permanently.",
  63. ["reviveMarkerName"] = "Player corpse - Use to revive!",
  64. }
  65.  
  66. ---------------------------------------------------------------------------------------
  67. local Methods = {}
  68.  
  69. Methods.GetLangText = function(key, data)
  70. local function replacer(wildcard)
  71. if data[wildcard] then
  72. return data[wildcard]
  73. else
  74. return ""
  75. end
  76. end
  77.  
  78. local text = lang[key] or ""
  79. text = text:gsub("%%(%w+)", replacer)
  80.  
  81. return text
  82. end
  83.  
  84. ---------------------------------------------------------------------------------------
  85. local reviveMarkers = {}
  86. local pidMarkerLookup = {}
  87.  
  88. Methods.CreateReviveMarker = function(pid)
  89. local playerName = Players[pid].name
  90. local cellDescription = Players[pid].data.location.cell
  91. local location = {
  92. posX = tes3mp.GetPosX(pid),
  93. posY = tes3mp.GetPosY(pid),
  94. posZ = tes3mp.GetPosZ(pid) + 10,
  95. rotX = 0,
  96. rotY = 0,
  97. rotZ = tes3mp.GetRotZ(pid)
  98. }
  99.  
  100. -- Create the marker
  101. local useTemporaryLoad = false
  102. if LoadedCells[cellDescription] == nil then
  103. logicHandler.LoadCell(cellDescription)
  104. useTemporaryLoad = true
  105. end
  106.  
  107. local objData = { refId = scriptConfig.recordRefId, count = 1, charge = -1, enchantmentCharge = -1, soul = -1}
  108. local uniqueIndex = logicHandler.CreateObjectAtLocation(cellDescription, location, objData, "place")
  109.  
  110. if useTemporaryLoad then
  111. logicHandler.UnloadCell(cellDescription)
  112. end
  113.  
  114. reviveMarkers[uniqueIndex] = {playerName = Players[pid].name, cellDescription = cellDescription, pid = pid}
  115. pidMarkerLookup[pid] = uniqueIndex
  116.  
  117. -- Delete the marker for the downed player, and anyone who was in the cell
  118. for pid, player in pairs(Players) do
  119. if tes3mp.GetCell(pid) == cellDescription then
  120. logicHandler.DeleteObjectForPlayer(pid, cellDescription, uniqueIndex)
  121. end
  122. end
  123.  
  124. -- A little bit extra to maybe ensure that the player whose marker it is doesn't see it
  125. logicHandler.DeleteObjectForPlayer(pid, cellDescription, uniqueIndex)
  126. end
  127.  
  128. Methods.RemoveReviveMarker = function(uniqueIndex, cellDescriptionGiven)
  129. if uniqueIndex then
  130. local useTemporaryLoad = false
  131.  
  132. local cellDescription
  133. -- The OnObjectActivate call for this function provides a cell description in case the revive marker is from an old session
  134. -- Use that if provided, otherwise it's safe to get it from looking up its information
  135. if not cellDescriptionGiven then
  136. cellDescription = reviveMarkers[uniqueIndex].cellDescription
  137. else
  138. cellDescription = cellDescriptionGiven
  139. end
  140.  
  141. if LoadedCells[cellDescription] == nil then
  142. logicHandler.LoadCell(cellDescription)
  143. useTemporaryLoad = true
  144. end
  145.  
  146. logicHandler.DeleteObjectForEveryone(cellDescription, uniqueIndex)
  147. LoadedCells[cellDescription]:DeleteObjectData(uniqueIndex)
  148.  
  149. if useTemporaryLoad then
  150. logicHandler.UnloadCell(cellDescription)
  151. end
  152.  
  153. if reviveMarkers[uniqueIndex] then
  154. pidMarkerLookup[reviveMarkers[uniqueIndex].pid] = nil
  155. end
  156.  
  157. reviveMarkers[uniqueIndex] = nil
  158. end
  159. end
  160.  
  161. Methods.SendMessageToAllWithCellLoaded = function(cellDescription, message, exceptionPids)
  162. for pid, player in pairs(Players) do
  163. if tableHelper.containsValue(player.cellsLoaded, cellDescription) and not tableHelper.containsValue(exceptionPids or {}, pid) then
  164. tes3mp.SendMessage(pid, message .. "\n")
  165. end
  166. end
  167. end
  168.  
  169. Methods.SendMessageToAllOnServer = function(message, exceptionPids)
  170. for pid, player in pairs(Players) do
  171. if not tableHelper.containsValue(exceptionPids or {}, pid) then
  172. tes3mp.SendMessage(pid, message .. "\n")
  173. end
  174. end
  175. end
  176.  
  177. Methods.IsPlayerDowned = function(pid)
  178. if Players[pid] ~= nil then
  179. return Players[pid].data.customVariables.isDowned or false
  180. else
  181. return false
  182. end
  183. end
  184.  
  185. Methods.CanRevivePlayer = function(pid)
  186. if Players[pid] ~= nil then
  187. return not Players[pid].data.customVariables.cannotRevive
  188. else
  189. return false
  190. end
  191. end
  192.  
  193.  
  194. Methods.OnPlayerRevive = function(downedPid, reviverPid)
  195. -- Time to do all the configured stat stuff...
  196. local healthCurrent = tes3mp.GetHealthCurrent(downedPid)
  197. local healthBase = Players[downedPid].data.stats.healthBase --We'll use this value instead so we avoid that setting-to-1 bug
  198. local fatigueCurrent = tes3mp.GetFatigueCurrent(downedPid)
  199. local fatigueBase = tes3mp.GetFatigueBase(downedPid)
  200. local magickaCurrent = tes3mp.GetMagickaCurrent(downedPid)
  201. local magickaBase = tes3mp.GetMagickaBase(downedPid)
  202.  
  203. local newHealth, newMagicka, newFatigue
  204. -- Note: We'll clamp them within bounds when everything is done
  205.  
  206. -- Health
  207. if scriptConfig.revivedHealthMode == "set" then
  208. newHealth = scriptConfig.setModeHealth
  209. elseif scriptConfig.revivedHealthMode == "preserve" then
  210. -- Health can't be preserved, so set it to 1 instead
  211. newHealth = 1
  212. else -- percent
  213. newHealth = math.floor((healthBase * scriptConfig.percentModeHealth) + 0.5 )
  214. end
  215.  
  216. -- Magicka
  217. if scriptConfig.revivedMagickaMode == "set" then
  218. newMagicka = scriptConfig.setModeMagicka
  219. elseif scriptConfig.revivedMagickaMode == "preserve" then
  220. -- Health can't be preserved, so set it to 1 instead
  221. newMagicka = magickaCurrent
  222. else -- percent
  223. newMagicka = math.floor((magickaBase * scriptConfig.percentModeMagicka) + 0.5 )
  224. end
  225.  
  226. -- Fatigue
  227. if scriptConfig.revivedFatigueMode == "set" then
  228. newFatigue = scriptConfig.setModeFatigue
  229. elseif scriptConfig.revivedFatigueMode == "preserve" then
  230. newFatigue = fatigueCurrent
  231. else -- Percent
  232. newFatigue = math.floor((fatigueBase * scriptConfig.percentModeFatigue) + 0.5 )
  233. end
  234.  
  235. -- Now we'll clamp these values before we move on
  236. newHealth = math.max(math.min(newHealth, healthBase), 1)
  237. newMagicka = math.max(math.min(newMagicka, magickaBase), 0)
  238. newFatigue = math.max(math.min(newFatigue, fatigueBase), 0)
  239.  
  240. -- Inform players about the revival
  241. local exemptPids = {downedPid, reviverPid}
  242. local downedPlayerName = Players[downedPid].name
  243. local reviverPlayerName = Players[reviverPid].name
  244. local cell = Players[downedPid].data.location.cell
  245. local broadcastMessage = Methods.GetLangText("revivedOtherMessage", {receive = downedPlayerName, give = reviverPlayerName})
  246.  
  247. -- ...Inform the player being revived
  248. tes3mp.SendMessage(downedPid, Methods.GetLangText("revivedReceiveMessage", {name = reviverPlayerName}) .. "\n")
  249.  
  250. -- ...Inform the reviver
  251. tes3mp.SendMessage(reviverPid, Methods.GetLangText("revivedGiveMessage", {name = downedPlayerName}) .. "\n")
  252.  
  253. -- ...Inform others (if configured)
  254. if scriptConfig.reviveAnnounceRadius == "cell" then
  255. Methods.SendMessageToAllWithCellLoaded(cell, broadcastMessage, exemptPids)
  256. elseif scriptConfig.reviveAnnounceRadius == "server" then
  257. Methods.SendMessageToAllOnServer(broadcastMessage, exemptPids)
  258. end
  259.  
  260. -- Now finally actually revive the player
  261. Players[downedPid].data.customVariables.isDowned = false
  262. contentFixer.UnequipDeadlyItems(downedPid)
  263. tes3mp.Resurrect(downedPid, 0)
  264.  
  265. -- Set the players stats...
  266. tes3mp.SetHealthCurrent(downedPid, newHealth)
  267. tes3mp.SetMagickaCurrent(downedPid, newMagicka)
  268. tes3mp.SetFatigueCurrent(downedPid, newFatigue)
  269.  
  270. tes3mp.SendStatsDynamic(downedPid)
  271.  
  272. -- Cleanup the player's revive marker, if created
  273. if scriptConfig.useMarkers then
  274. Methods.RemoveReviveMarker(pidMarkerLookup[downedPid])
  275. end
  276. end
  277.  
  278. Methods.OnBleedoutExpire = function(pid)
  279. Players[pid].data.customVariables.isDowned = false
  280.  
  281. -- Inform the player
  282. if config.playersRespawn then
  283. tes3mp.SendMessage(pid, Methods.GetLangText("bleedoutPlayerMessage") .. "\n")
  284. else
  285. tes3mp.SendMessage(pid, Methods.GetLangText("defaultPermanentDeath") .. "\n")
  286. end
  287.  
  288. -- Inform others if configured
  289. local exemptPids = {pid}
  290. local pname = Players[pid].name
  291. local message = Methods.GetLangText("bleedoutOtherMessage", {name = pname})
  292. local cell = Players[pid].data.location.cell
  293.  
  294. if scriptConfig.playerDiedAnnounceRadius == "cell" then
  295. Methods.SendMessageToAllWithCellLoaded(cell, message, exemptPids)
  296. elseif scriptConfig.playerDiedAnnounceRadius == "server" then
  297. Methods.SendMessageToAllOnServer(message, exemptPids)
  298. end
  299.  
  300. -- Resurrect the player, if permadeath is disabled
  301. if config.playersRespawn then
  302. -- While we could just jump straight to using Resurrect, we'll faff through the proper channels...
  303. -- Note: Might have to instead start the regular dying timer, just to be safe
  304. OnDeathTimeExpiration(pid, Players[pid].accountName)
  305. else
  306. -- Set a flag permanently preventing the player from being able to be revived
  307. Players[pid].data.customVariables.cannotRevive = true
  308.  
  309. end
  310.  
  311. -- Cleanup the player's revive marker, if created
  312. if scriptConfig.useMarkers then
  313. Methods.RemoveReviveMarker(pidMarkerLookup[pid])
  314. end
  315. end
  316.  
  317. Methods.SetPlayerDowned = function(pid, timeRemaining)
  318. -- Set the variables
  319. Players[pid].data.customVariables.isDowned = true
  320. -- If the player logged out while bleeding out, they will have a non-standard number of seconds left
  321. local secondsLeft
  322. if not timeRemaining then
  323. secondsLeft = scriptConfig.bleedoutTime
  324. Players[pid].data.customVariables.bleedoutTicks = 0
  325. else
  326. secondsLeft = timeRemaining
  327. Players[pid].data.customVariables.bleedoutTicks = scriptConfig.bleedoutTime - secondsLeft
  328. end
  329.  
  330. -- Send the first basic messages
  331. -- ... To the player
  332. tes3mp.SendMessage(pid, Methods.GetLangText("awaitingReviveMessage") .. "\n")
  333.  
  334. -- ... And the others (if configured)
  335. local downedPlayerName = Players[pid].name
  336. local exemptPids = {pid}
  337. local cell = Players[pid].data.location.cell
  338.  
  339. local downBroadcastMessage = Methods.GetLangText("awaitingReviveOtherMessage", {name = downedPlayerName})
  340.  
  341. if scriptConfig.playerDownedAnnounceRadius == "cell" then
  342. Methods.SendMessageToAllWithCellLoaded(cell, downBroadcastMessage, exemptPids)
  343. elseif scriptConfig.playerDownedAnnounceRadius == "server" then
  344. Methods.SendMessageToAllOnServer(downBroadcastMessage, exemptPids)
  345. end
  346.  
  347. -- Do all the bleedout-related things, provided we're configured to do that
  348. if scriptConfig.useBleedout then
  349. -- Tell the player that they're bleeding out, and how many seconds they have left
  350. tes3mp.SendMessage(pid, Methods.GetLangText("bleedingOutMessage", {seconds = secondsLeft}) .. "\n")
  351.  
  352. -- Start their bleedout timer
  353. local timerId = tes3mp.CreateTimerEx("BleedoutTick", time.seconds(1), "i", pid)
  354. Players[pid].data.customVariables["bleedoutTimerId"] = timerId
  355. tes3mp.StartTimer(timerId)
  356. end
  357.  
  358. -- Create a marker, if configured
  359. if scriptConfig.useMarkers then
  360. Methods.CreateReviveMarker(pid)
  361. end
  362.  
  363. -- Tell the player the command prompt to die
  364. tes3mp.SendMessage(pid, Methods.GetLangText("giveInPrompt") .. "\n")
  365. end
  366.  
  367. -- We use this to set a player to the downed state when they die, with a special case for if the player has logged back in after being downed (using a flag set during in Methods.OnPlayerLogin to know)
  368. -- And also obviously we only want to set the player downed if they aren't already
  369. Methods.TrySetPlayerDowned = function(pid)
  370. if Players[pid].data.customVariables.cannotRevive == true then
  371. -- Do nothing
  372. elseif Players[pid].data.customVariables.loggedOutDowned == true then
  373. local remaining = scriptConfig.bleedoutTime - Players[pid].data.customVariables.bleedoutTicks
  374. -- Clear the logout flag
  375. Players[pid].data.customVariables.loggedOutDowned = nil
  376.  
  377. Methods.SetPlayerDowned(pid, remaining)
  378. elseif not Methods.IsPlayerDowned(pid) then
  379. Methods.SetPlayerDowned(pid)
  380. end
  381. end
  382.  
  383. customEventHooks.registerValidator("OnPlayerDeath", function(eventStatus, pid)
  384. -- Here we replicate some of the tesmp default logic that we're blocking
  385. local message
  386. if tes3mp.DoesPlayerHavePlayerKiller(pid) and tes3mp.GetPlayerKillerPid(pid) ~= pid then
  387. local killerPid = tes3mp.GetPlayerKillerPid(pid)
  388. message = Methods.GetLangText("defaultKilledByPlayer", {name = logicHandler.GetChatName(pid), killer = logicHandler.GetChatName(killerPid)})
  389. elseif tes3mp.GetPlayerKillerName(pid) ~= "" then
  390. message = Methods.GetLangText("defaultKilledByOther", {name = logicHandler.GetChatName(pid), killer = tes3mp.GetPlayerKillerName(pid)})
  391. else
  392. message = Methods.GetLangText("defaultSuicide", {name = logicHandler.GetChatName(pid)})
  393. end
  394.  
  395. tes3mp.SendMessage(pid, message .. "\n", true)
  396.  
  397. if config.playersRespawn or scriptConfig.allowReviveWithPermadeath then
  398. Methods.TrySetPlayerDowned(pid)
  399. else
  400. tes3mp.SendMessage(pid, Methods.GetLangText("defaultPermanentDeath") .. "\n", false)
  401. return customEventHooks.makeEventStatus(false, true)
  402. end
  403.  
  404. return customEventHooks.makeEventStatus(false, false)
  405. end)
  406.  
  407. -------------
  408. Methods.OnDieCommand = function(pid)
  409. -- Only do anything if the player is actually downed
  410. if Methods.IsPlayerDowned(pid) then
  411. return Methods.OnBleedoutExpire(pid)
  412. end
  413. end
  414.  
  415. customCommandHooks.registerCommand("die", Methods.OnDieCommand)
  416.  
  417. Methods.OnPlayerLogin = function(pid)
  418. -- Check if a player logged out while downed
  419. -- If they did, set the flags up for them to resume bleeding out when their death event triggers
  420. if Players[pid].data.customVariables.isDowned then
  421. Players[pid]:SetHealthCurrent(0) -- Just to ensure they're always dead
  422. Players[pid].data.customVariables.loggedOutDowned = true
  423. -- The rest of setting up / resuming is left to the death event
  424. end
  425. end
  426.  
  427. customEventHooks.registerHandler("OnPlayerFinishLogin", function (eventStatus, pid)
  428. Methods.OnPlayerLogin(pid)
  429. end)
  430.  
  431. Methods.OnObjectActivate = function(pid, cellDescription)
  432. -- A lot of this code is copied from eventHandler.OnObjectActivate
  433. if Players[pid] ~= nil and Players[pid]:IsLoggedIn() then
  434. if LoadedCells[cellDescription] ~= nil then
  435. tes3mp.ReadReceivedObjectList()
  436.  
  437. for index = 0, tes3mp.GetObjectListSize() - 1 do
  438. local objectPid
  439. local activatorPid
  440. local objectUniqueIndex
  441. local objectRefId
  442.  
  443. -- Detect if the object being activated is a player
  444. if tes3mp.IsObjectPlayer(index) then
  445. objectPid = tes3mp.GetObjectPid(index)
  446. else
  447. objectUniqueIndex = tes3mp.GetObjectRefNum(index) .. "-" .. tes3mp.GetObjectMpNum(index)
  448. objectRefId = tes3mp.GetObjectRefId(index)
  449. end
  450.  
  451. -- Detect if the object was activated by a player
  452. if tes3mp.DoesObjectHavePlayerActivating(index) then
  453. activatorPid = tes3mp.GetObjectActivatingPid(index)
  454. end
  455.  
  456. -- If a player was activating a player...
  457. if objectPid and activatorPid then
  458. -- Check if the target player is currently downed
  459. if Methods.IsPlayerDowned(objectPid) then
  460. -- Revive them!
  461. Methods.OnPlayerRevive(objectPid, activatorPid)
  462. end
  463. elseif objectRefId == scriptConfig.recordRefId then
  464. -- The player activated a revive marker!
  465. if reviveMarkers[objectUniqueIndex] and Methods.IsPlayerDowned(reviveMarkers[objectUniqueIndex].pid) then
  466. Methods.OnPlayerRevive(reviveMarkers[objectUniqueIndex].pid, activatorPid)
  467. end
  468.  
  469. -- It's possible that markers might be left over from previous sessions, so we'll always make sure to delete one that's activated
  470. Methods.RemoveReviveMarker(objectUniqueIndex, cellDescription)
  471. end
  472. end
  473. end
  474. end
  475. end
  476.  
  477. customEventHooks.registerHandler("OnObjectActivate", function(eventStatus, pid, cellDescription, objects, players)
  478. Methods.OnObjectActivate(pid, cellDescription)
  479. end)
  480.  
  481. Methods.OnServerPostInit = function()
  482. -- Detect if this script's permanent record has been created on this server yet
  483. -- If it hasn't, create it
  484. if RecordStores[scriptConfig.baseObjectType].data.permanentRecords[scriptConfig.recordRefId] == nil then
  485. local data = {model = scriptConfig.markerModel, name = Methods.GetLangText("reviveMarkerName"), script = "nopickup"}
  486.  
  487. RecordStores[scriptConfig.baseObjectType].data.permanentRecords[scriptConfig.recordRefId] = data
  488.  
  489. RecordStores[scriptConfig.baseObjectType]:Save()
  490. end
  491. end
  492.  
  493. customEventHooks.registerHandler("OnServerPostInit", function(eventStatus)
  494. Methods.OnServerPostInit()
  495. end)
  496.  
  497. Methods.OnPlayerDisconnect = function(pid)
  498. -- Remove the revive markers of players who disconnect
  499. if Methods.IsPlayerDowned(pid) and scriptConfig.useMarkers then
  500. Methods.RemoveReviveMarker(pidMarkerLookup[pid])
  501. end
  502. end
  503.  
  504. customEventHooks.registerValidator("OnPlayerDisconnect", function(eventStatus, pid)
  505. Methods.OnPlayerDisconnect(pid)
  506. end)
  507.  
  508. -------------
  509. function BleedoutTick(pid)
  510. if Players[pid] ~= nil and Players[pid]:IsLoggedIn() then
  511. local cvars = Players[pid].data.customVariables
  512.  
  513. -- Check if the player is still supposed to be bleeding out
  514. if cvars.isDowned ~= nil and cvars.isDowned == true then
  515. -- Increment timer
  516. cvars.bleedoutTicks = (cvars.bleedoutTicks or 0) + 1
  517.  
  518. if scriptConfig.useBleedout and cvars.bleedoutTicks >= scriptConfig.bleedoutTime then
  519. -- Player has exceeded bleedout time!
  520. return Methods.OnBleedoutExpire(pid)
  521. else
  522. -- Queue up another tick countdown
  523. local timerId = cvars.bleedoutTimerId
  524. return tes3mp.RestartTimer(timerId, time.seconds(1))
  525. end
  526. else
  527. -- The player is no longer bleeding out, so we don't need to do anything
  528. return
  529. end
  530. end
  531. end
  532. -------------
  533. return Methods
  534.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement