Advertisement
Guest User

player/base.lua

a guest
Aug 15th, 2018
375
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 32.97 KB | None | 0 0
  1. require("config")
  2. require("actionTypes")
  3. require("patterns")
  4. stateHelper = require("stateHelper")
  5. tableHelper = require("tableHelper")
  6. local BasePlayer = class("BasePlayer")
  7.  
  8. function BasePlayer:__init(pid, playerName)
  9. self.dbPid = nil
  10.  
  11. self.data =
  12. {
  13. login = {
  14. name = "",
  15. password = ""
  16. },
  17. settings = {
  18. admin = 0,
  19. difficulty = "default",
  20. consoleAllowed = "default",
  21. bedRestAllowed = "default",
  22. wildernessRestAllowed = "default",
  23. waitAllowed = "default"
  24. },
  25. character = {
  26. race = "",
  27. head = "",
  28. hair = "",
  29. gender = 1,
  30. class = "",
  31. birthsign = ""
  32. },
  33. location = {
  34. cell = "",
  35. posX = 0,
  36. posY = 0,
  37. posZ = 0,
  38. rotX = 0,
  39. rotZ = 0
  40. },
  41. stats = {
  42. level = 1,
  43. levelProgress = 0,
  44. healthBase = 1,
  45. healthCurrent = 1,
  46. magickaBase = 1,
  47. magickaCurrent = 1,
  48. fatigueBase = 1,
  49. fatigueCurrent = 1,
  50. bounty = 0
  51. },
  52. customClass = {},
  53. attributes = {},
  54. attributeSkillIncreases = {},
  55. skills = {},
  56. skillProgress = {},
  57. equipment = {},
  58. inventory = {},
  59. spellbook = {},
  60. quickKeys = {},
  61. shapeshift = {},
  62. journal = {},
  63. factionRanks = {},
  64. factionExpulsion = {},
  65. factionReputation = {},
  66. topics = {},
  67. books = {},
  68. mapExplored = {},
  69. ipAddresses = {},
  70. customVariables= {}
  71. };
  72.  
  73. for i = 0, (tes3mp.GetAttributeCount() - 1) do
  74. local attributeName = tes3mp.GetAttributeName(i)
  75. self.data.attributes[attributeName] = 1
  76. self.data.attributeSkillIncreases[attributeName] = 0
  77. end
  78.  
  79. for i = 0, (tes3mp.GetSkillCount() - 1) do
  80. local skillName = tes3mp.GetSkillName(i)
  81. self.data.skills[skillName] = 1
  82. self.data.skillProgress[skillName] = 0
  83. end
  84.  
  85. self.initTimestamp = os.time()
  86.  
  87. if playerName == nil then
  88. self.accountName = tes3mp.GetName(pid)
  89. else
  90. self.accountName = playerName
  91. end
  92.  
  93. self.pid = pid
  94. self.loggedIn = false
  95. self.tid_login = nil
  96. self.admin = 0
  97. self.hasAccount = nil -- TODO Check whether account file exists
  98.  
  99. self.cellsLoaded = {}
  100. end
  101.  
  102. function BasePlayer:Destroy()
  103. if self.tid_login ~= nil then
  104. tes3mp.StopTimer(self.tid_login)
  105. self.tid_login = nil
  106. end
  107.  
  108. self.loggedIn = false
  109. self.hasAccount = nil
  110. end
  111.  
  112. function BasePlayer:Kick()
  113. self:Destroy()
  114. tes3mp.Kick(self.pid)
  115. end
  116.  
  117. function BasePlayer:Registered(passw)
  118. self.loggedIn = true
  119. self.data.login.password = passw
  120. self.data.settings.consoleAllowed = "default"
  121. if self.hasAccount == false then -- create account
  122. tes3mp.SetCharGenStage(self.pid, 1, 4)
  123. end
  124. end
  125.  
  126. function BasePlayer:FinishLogin()
  127. self.loggedIn = true
  128. if self.hasAccount ~= false then -- load account
  129. self:SaveIpAddress()
  130. self:LoadCharacter()
  131. self:LoadClass()
  132. self:LoadLevel()
  133. self:LoadAttributes()
  134. self:LoadSkills()
  135. self:LoadStatsDynamic()
  136. self:LoadBounty()
  137. self:LoadCell()
  138. self:LoadInventory()
  139. self:LoadEquipment()
  140. self:LoadSpellbook()
  141. self:LoadQuickKeys()
  142. self:LoadBooks()
  143. --self:LoadMap()
  144. self:LoadShapeshift()
  145. self:LoadSettings()
  146.  
  147. if config.shareJournal == true then
  148. WorldInstance:LoadJournal(self.pid)
  149. else
  150. self:LoadJournal()
  151. end
  152.  
  153. if config.shareFactionRanks == true then
  154. WorldInstance:LoadFactionRanks(self.pid)
  155. else
  156. self:LoadFactionRanks()
  157. end
  158.  
  159. if config.shareFactionExpulsion == true then
  160. WorldInstance:LoadFactionExpulsion(self.pid)
  161. else
  162. self:LoadFactionExpulsion()
  163. end
  164.  
  165. if config.shareFactionReputation == true then
  166. WorldInstance:LoadFactionReputation(self.pid)
  167. else
  168. self:LoadFactionReputation()
  169. end
  170.  
  171. if config.shareTopics == true then
  172. WorldInstance:LoadTopics(self.pid)
  173. else
  174. self:LoadTopics()
  175. end
  176.  
  177. WorldInstance:LoadKills(self.pid)
  178.  
  179. self:LoadSpecialStates()
  180. end
  181. end
  182.  
  183. function BasePlayer:EndCharGen()
  184. self:SaveLogin()
  185. self:SaveCharacter()
  186. self:SaveClass()
  187. self:SaveStatsDynamic()
  188. self:SaveEquipment()
  189. self:SaveIpAddress()
  190. self:CreateAccount()
  191.  
  192. if config.shareJournal == true then
  193. WorldInstance:LoadJournal(self.pid)
  194. end
  195.  
  196. if config.shareFactionRanks == true then
  197. WorldInstance:LoadFactionRanks(self.pid)
  198. end
  199.  
  200. if config.shareFactionExpulsion == true then
  201. WorldInstance:LoadFactionExpulsion(self.pid)
  202. end
  203.  
  204. if config.shareFactionReputation == true then
  205. WorldInstance:LoadFactionReputation(self.pid)
  206. end
  207.  
  208. if config.shareTopics == true then
  209. WorldInstance:LoadTopics(self.pid)
  210. end
  211.  
  212. WorldInstance:LoadKills(self.pid)
  213.  
  214. if config.defaultSpawnCell ~= nil then
  215.  
  216. tes3mp.SetCell(self.pid, config.defaultSpawnCell)
  217. tes3mp.SendCell(self.pid)
  218.  
  219. if config.defaultSpawnPos ~= nil and config.defaultSpawnRot ~= nil then
  220. tes3mp.SetPos(self.pid, config.defaultSpawnPos[1], config.defaultSpawnPos[2], config.defaultSpawnPos[3])
  221. tes3mp.SetRot(self.pid, config.defaultSpawnRot[1], config.defaultSpawnRot[2])
  222. tes3mp.SendPos(self.pid)
  223. end
  224. end
  225.  
  226. if config.shareJournal == true and WorldInstance.data.customVariables ~= nil then
  227. if WorldInstance.data.customVariables.deliveredCaiusPackage ~= true then
  228. local item = { refId = "bk_a1_1_caiuspackage", count = 1, charge = -1 }
  229. table.insert(self.data.inventory, item)
  230. self:LoadInventory()
  231. self:LoadEquipment()
  232. tes3mp.MessageBox(self.pid, -1, "Multiplayer skips over the original character generation.\n\nAs a result, you start out with Caius Cosades' package.")
  233. end
  234. end
  235. end
  236.  
  237. function BasePlayer:IsLoggedIn()
  238. return self.loggedIn
  239. end
  240.  
  241. function BasePlayer:IsAdmin()
  242. return self.data.settings.admin == 2
  243. end
  244.  
  245. function BasePlayer:IsModerator()
  246. return self.data.settings.admin >= 1
  247. end
  248.  
  249. function BasePlayer:PromoteModerator(other)
  250. if self.IsAdmin() then
  251. other.data.settings.admin = 1
  252. return true
  253. end
  254. return false
  255. end
  256.  
  257. function BasePlayer:GetHealthCurrent()
  258. self.data.stats.healthCurrent = tes3mp.GetHealthCurrent(self.pid)
  259. return self.data.stats.healthCurrent
  260. end
  261.  
  262. function BasePlayer:SetHealthCurrent(health)
  263. self.data.stats.healthCurrent = health
  264. tes3mp.SetHealthCurrent(self.pid, health)
  265. end
  266.  
  267. function BasePlayer:GetHealthBase()
  268. self.data.stats.healthBase = tes3mp.GetHealthBase(self.pid)
  269. return self.data.stats.healthBase
  270. end
  271.  
  272. function BasePlayer:SetHealthBase(health)
  273. self.data.stats.healthBase = health
  274. tes3mp.SetHealthBase(self.pid, health)
  275. end
  276.  
  277. function BasePlayer:HasAccount()
  278. return self.hasAccount
  279. end
  280.  
  281. function BasePlayer:Message(message)
  282. tes3mp.SendMessage(self.pid, message, false)
  283. end
  284.  
  285. function BasePlayer:CreateAccount()
  286. error("Not implemented")
  287. end
  288.  
  289. function BasePlayer:Save()
  290. error("Not implemented")
  291. end
  292.  
  293. function BasePlayer:Load()
  294. error("Not implemented")
  295. end
  296.  
  297. function BasePlayer:SaveLogin()
  298. self.data.login.name = tes3mp.GetName(self.pid)
  299. end
  300.  
  301. function BasePlayer:SaveIpAddress()
  302. if self.data.ipAddresses == nil then
  303. self.data.ipAddresses = {}
  304. end
  305.  
  306. local ipAddress = tes3mp.GetIP(self.pid)
  307.  
  308. if tableHelper.containsValue(self.data.ipAddresses, ipAddress) == false then
  309. table.insert(self.data.ipAddresses, ipAddress)
  310. end
  311. end
  312.  
  313. function BasePlayer:ProcessDeath()
  314.  
  315. local deathReason = tes3mp.GetDeathReason(self.pid)
  316.  
  317. tes3mp.LogMessage(1, "Original death reason was " .. deathReason)
  318.  
  319. if deathReason == "suicide" then
  320. deathReason = "committed suicide"
  321. else
  322. if deathReason == "" then
  323. deathReason = "unknown forces"
  324. end
  325.  
  326. deathReason = "was killed by " .. deathReason
  327. end
  328.  
  329. local message = ("%s (%d) %s"):format(self.data.login.name, self.pid, deathReason)
  330.  
  331. message = message .. ".\n"
  332. tes3mp.SendMessage(self.pid, message, true)
  333.  
  334. self.tid_resurrect = tes3mp.CreateTimerEx("OnDeathTimeExpiration", time.seconds(config.deathTime), "i", self.pid)
  335. tes3mp.StartTimer(self.tid_resurrect)
  336. end
  337.  
  338. function BasePlayer:Resurrect()
  339.  
  340. local currentResurrectType
  341.  
  342. if config.respawnAtImperialShrine == true then
  343. if config.respawnAtTribunalTemple == true then
  344. if math.random() > 0.5 then
  345. currentResurrectType = actionTypes.resurrect.IMPERIAL_SHRINE
  346. else
  347. currentResurrectType = actionTypes.resurrect.TRIBUNAL_TEMPLE
  348. end
  349. else
  350. currentResurrectType = actionTypes.resurrect.IMPERIAL_SHRINE
  351. end
  352.  
  353. elseif config.respawnAtTribunalTemple == true then
  354. currentResurrectType = actionTypes.resurrect.TRIBUNAL_TEMPLE
  355.  
  356. elseif config.defaultRespawnCell ~= nil then
  357. currentResurrectType = actionTypes.resurrect.REGULAR
  358.  
  359. tes3mp.SetCell(self.pid, config.defaultRespawnCell)
  360. tes3mp.SendCell(self.pid)
  361.  
  362. if config.defaultRespawnPos ~= nil and config.defaultRespawnRot ~= nil then
  363. tes3mp.SetPos(self.pid, config.defaultRespawnPos[1], config.defaultRespawnPos[2], config.defaultRespawnPos[3])
  364. tes3mp.SetRot(self.pid, config.defaultRespawnRot[1], config.defaultRespawnRot[2])
  365. tes3mp.SendPos(self.pid)
  366. end
  367. end
  368.  
  369. local message = "You have been revived"
  370.  
  371. if currentResurrectType == actionTypes.resurrect.IMPERIAL_SHRINE then
  372. message = message .. " at the nearest Imperial shrine"
  373. elseif currentResurrectType == actionTypes.resurrect.TRIBUNAL_TEMPLE then
  374. message = message .. " at the nearest Tribunal temple"
  375. end
  376.  
  377. message = message .. ".\n"
  378.  
  379. -- Ensure that dying as a werewolf turns you back into your normal form
  380. if self.data.shapeshift.isWerewolf == true then
  381. self:SetWerewolfState(false)
  382. end
  383.  
  384. -- Ensure that we unequip deadly items when applicable, to prevent an
  385. -- infinite death loop
  386. questFixer.UnequipDeadlyItems(self.pid)
  387.  
  388. tes3mp.Resurrect(self.pid, currentResurrectType)
  389.  
  390. if config.deathPenaltyJailDays > 0 then
  391. tes3mp.Jail(self.pid, config.deathPenaltyJailDays, true, true, "Recovering", "You've been revived and brought back here, but your skills have been affected by your time spent incapacitated.")
  392. end
  393.  
  394. tes3mp.SendMessage(self.pid, message, false)
  395. end
  396.  
  397. function BasePlayer:LoadCharacter()
  398. tes3mp.SetRace(self.pid, self.data.character.race)
  399. tes3mp.SetHead(self.pid, self.data.character.head)
  400. tes3mp.SetHair(self.pid, self.data.character.hair)
  401. tes3mp.SetIsMale(self.pid, self.data.character.gender)
  402. tes3mp.SetBirthsign(self.pid, self.data.character.birthsign)
  403.  
  404. tes3mp.SendBaseInfo(self.pid)
  405. end
  406.  
  407. function BasePlayer:SaveCharacter()
  408. self.data.character.race = tes3mp.GetRace(self.pid)
  409. self.data.character.head = tes3mp.GetHead(self.pid)
  410. self.data.character.hair = tes3mp.GetHair(self.pid)
  411. self.data.character.gender = tes3mp.GetIsMale(self.pid)
  412. self.data.character.birthsign = tes3mp.GetBirthsign(self.pid)
  413. end
  414.  
  415. function BasePlayer:LoadClass()
  416. if self.data.character.class ~= "custom" then
  417. tes3mp.SetDefaultClass(self.pid, self.data.character.class)
  418. elseif self.data.customClass ~= nil then
  419. tes3mp.SetClassName(self.pid, self.data.customClass.name)
  420. tes3mp.SetClassSpecialization(self.pid, self.data.customClass.specialization)
  421.  
  422. if self.data.customClass.description ~= nil then
  423. tes3mp.SetClassDesc(self.pid, self.data.customClass.description)
  424. end
  425.  
  426. local i = 0
  427. for value in string.gmatch(self.data.customClass.majorAttributes, patterns.commaSplit) do
  428. tes3mp.SetClassMajorAttribute(self.pid, i, tes3mp.GetAttributeId(value))
  429. i = i + 1
  430. end
  431.  
  432. i = 0
  433. for value in string.gmatch(self.data.customClass.majorSkills, patterns.commaSplit) do
  434. tes3mp.SetClassMajorSkill(self.pid, i, tes3mp.GetSkillId(value))
  435. i = i + 1
  436. end
  437.  
  438. i = 0
  439. for value in string.gmatch(self.data.customClass.minorSkills, patterns.commaSplit) do
  440. tes3mp.SetClassMinorSkill(self.pid, i, tes3mp.GetSkillId(value))
  441. i = i + 1
  442. end
  443. end
  444.  
  445. tes3mp.SendClass(self.pid)
  446. end
  447.  
  448. function BasePlayer:SaveClass()
  449. if tes3mp.IsClassDefault(self.pid) == 1 then
  450. self.data.character.class = tes3mp.GetDefaultClass(self.pid)
  451. else
  452. self.data.character.class = "custom"
  453. self.data.customClass.name = tes3mp.GetClassName(self.pid)
  454. self.data.customClass.description = tes3mp.GetClassDesc(self.pid):gsub("\n", "\\n")
  455. self.data.customClass.specialization = tes3mp.GetClassSpecialization(self.pid)
  456. local majorAttributes = {}
  457. local majorSkills = {}
  458. local minorSkills = {}
  459.  
  460. for i = 0, 1, 1 do
  461. majorAttributes[i + 1] = tes3mp.GetAttributeName(tonumber(tes3mp.GetClassMajorAttribute(self.pid, i)))
  462. end
  463.  
  464. for i = 0, 4, 1 do
  465. majorSkills[i + 1] = tes3mp.GetSkillName(tonumber(tes3mp.GetClassMajorSkill(self.pid, i)))
  466. minorSkills[i + 1] = tes3mp.GetSkillName(tonumber(tes3mp.GetClassMinorSkill(self.pid, i)))
  467. end
  468.  
  469. self.data.customClass.majorAttributes = table.concat(majorAttributes, ", ")
  470. self.data.customClass.majorSkills = table.concat(majorSkills, ", ")
  471. self.data.customClass.minorSkills = table.concat(minorSkills, ", ")
  472. end
  473. end
  474.  
  475. function BasePlayer:LoadStatsDynamic()
  476. tes3mp.SetHealthBase(self.pid, self.data.stats.healthBase)
  477. tes3mp.SetMagickaBase(self.pid, self.data.stats.magickaBase)
  478. tes3mp.SetFatigueBase(self.pid, self.data.stats.fatigueBase)
  479. tes3mp.SetHealthCurrent(self.pid, self.data.stats.healthCurrent)
  480. tes3mp.SetMagickaCurrent(self.pid, self.data.stats.magickaCurrent)
  481. tes3mp.SetFatigueCurrent(self.pid, self.data.stats.fatigueCurrent)
  482.  
  483. tes3mp.SendStatsDynamic(self.pid)
  484. end
  485.  
  486. function BasePlayer:SaveStatsDynamic()
  487. self.data.stats.healthBase = tes3mp.GetHealthBase(self.pid)
  488. self.data.stats.magickaBase = tes3mp.GetMagickaBase(self.pid)
  489. self.data.stats.fatigueBase = tes3mp.GetFatigueBase(self.pid)
  490. self.data.stats.healthCurrent = tes3mp.GetHealthCurrent(self.pid)
  491. self.data.stats.magickaCurrent = tes3mp.GetMagickaCurrent(self.pid)
  492. self.data.stats.fatigueCurrent = tes3mp.GetFatigueCurrent(self.pid)
  493. end
  494.  
  495. function BasePlayer:LoadAttributes()
  496. for name, value in pairs(self.data.attributes) do
  497. tes3mp.SetAttributeBase(self.pid, tes3mp.GetAttributeId(name), value)
  498. end
  499.  
  500. tes3mp.SendAttributes(self.pid)
  501. end
  502.  
  503. function BasePlayer:SaveAttributes()
  504. for name in pairs(self.data.attributes) do
  505.  
  506. local attributeId = tes3mp.GetAttributeId(name)
  507.  
  508. local baseValue = tes3mp.GetAttributeBase(self.pid, attributeId)
  509. local modifierValue = tes3mp.GetAttributeModifier(self.pid, attributeId)
  510. local maxAttributeValue = config.maxAttributeValue
  511.  
  512. if name == "Speed" then
  513. maxAttributeValue = config.maxSpeedValue
  514. end
  515.  
  516. if baseValue > maxAttributeValue then
  517. self:LoadAttributes()
  518.  
  519. local message = "Your base " .. name .. " has exceeded the maximum allowed value and been reset to its last recorded one.\n"
  520. tes3mp.SendMessage(self.pid, message)
  521. elseif (baseValue + modifierValue) > maxAttributeValue then
  522. tes3mp.ClearAttributeModifier(self.pid, attributeId)
  523. tes3mp.SendAttributes(self.pid)
  524.  
  525. local message = "Your " .. name .. " fortification has exceeded the maximum allowed value and been removed.\n"
  526. tes3mp.SendMessage(self.pid, message)
  527. else
  528. self.data.attributes[name] = baseValue
  529. end
  530. end
  531. end
  532.  
  533. function BasePlayer:LoadSkills()
  534. for name, value in pairs(self.data.skills) do
  535. tes3mp.SetSkillBase(self.pid, tes3mp.GetSkillId(name), value)
  536. end
  537.  
  538. for name, value in pairs(self.data.skillProgress) do
  539. tes3mp.SetSkillProgress(self.pid, tes3mp.GetSkillId(name), value)
  540. end
  541.  
  542. for name, value in pairs(self.data.attributeSkillIncreases) do
  543. tes3mp.SetSkillIncrease(self.pid, tes3mp.GetAttributeId(name), value)
  544. end
  545.  
  546. tes3mp.SetLevelProgress(self.pid, self.data.stats.levelProgress)
  547. tes3mp.SendSkills(self.pid)
  548. end
  549.  
  550. function BasePlayer:SaveSkills()
  551. for name in pairs(self.data.skills) do
  552.  
  553. local skillId = tes3mp.GetSkillId(name)
  554.  
  555. local baseValue = tes3mp.GetSkillBase(self.pid, skillId)
  556. if baseValue ~= self.data.skills[name] then
  557. skilledone = name
  558. skilledtwice = 1
  559. end
  560. local modifierValue = tes3mp.GetSkillModifier(self.pid, skillId)
  561. local maxSkillValue = config.maxSkillValue
  562.  
  563. if name == "Acrobatics" then
  564. maxSkillValue = config.maxAcrobaticsValue
  565. end
  566.  
  567. if baseValue > maxSkillValue then
  568. self:LoadSkills()
  569.  
  570. local message = "Your base " .. name .. " has exceeded the maximum allowed value and been reset to its last recorded one.\n"
  571. tes3mp.SendMessage(self.pid, message)
  572. elseif (baseValue + modifierValue) > maxSkillValue then
  573. tes3mp.ClearSkillModifier(self.pid, skillId)
  574. tes3mp.SendSkills(self.pid)
  575.  
  576. local message = "Your " .. name .. " fortification has exceeded the maximum allowed value and been removed.\n"
  577. tes3mp.SendMessage(self.pid, message)
  578. else
  579. self.data.skills[name] = baseValue
  580. self.data.skillProgress[name] = tes3mp.GetSkillProgress(self.pid, skillId)
  581. end
  582. end
  583.  
  584. for name in pairs(self.data.attributeSkillIncreases) do
  585. local attributeId = tes3mp.GetAttributeId(name)
  586. self.data.attributeSkillIncreases[name] = tes3mp.GetSkillIncrease(self.pid, attributeId)
  587. end
  588.  
  589. self.data.stats.levelProgress = tes3mp.GetLevelProgress(self.pid)
  590. end
  591.  
  592. function BasePlayer:LoadLevel()
  593. tes3mp.SetLevel(self.pid, self.data.stats.level)
  594. tes3mp.SendLevel(self.pid)
  595. end
  596.  
  597. function BasePlayer:SaveLevel()
  598. self.data.stats.level = tes3mp.GetLevel(self.pid)
  599. end
  600.  
  601. function BasePlayer:LoadBounty()
  602. tes3mp.SetBounty(self.pid, self.data.stats.bounty)
  603. tes3mp.SendBounty(self.pid)
  604. end
  605.  
  606. function BasePlayer:SaveBounty()
  607. self.data.stats.bounty = tes3mp.GetBounty(self.pid)
  608. end
  609.  
  610. function BasePlayer:LoadShapeshift()
  611.  
  612. if self.data.shapeshift == nil then
  613. self.data.shapeshift = {}
  614. end
  615.  
  616. if self.data.shapeshift.isWerewolf == true then
  617. tes3mp.SetWerewolfState(self.pid, true)
  618. tes3mp.SendShapeshift(self.pid)
  619. end
  620. end
  621.  
  622. function BasePlayer:SaveShapeshift()
  623.  
  624. if self.data.shapeshift == nil then
  625. self.data.shapeshift = {}
  626. end
  627.  
  628. self.data.shapeshift.isWerewolf = tes3mp.IsWerewolf(self.pid)
  629. end
  630.  
  631. function BasePlayer:LoadCell()
  632. local newCell = self.data.location.cell
  633.  
  634. if newCell ~= nil then
  635.  
  636. tes3mp.SetCell(self.pid, newCell)
  637.  
  638. local pos = {0, 0, 0}
  639. local rot = {0, 0}
  640. pos[0] = self.data.location.posX
  641. pos[1] = self.data.location.posY
  642. pos[2] = self.data.location.posZ
  643. rot[0] = self.data.location.rotX
  644. rot[1] = self.data.location.rotZ
  645.  
  646. tes3mp.SetPos(self.pid, pos[0], pos[1], pos[2])
  647. tes3mp.SetRot(self.pid, rot[0], rot[1])
  648.  
  649. tes3mp.SendCell(self.pid)
  650. tes3mp.SendPos(self.pid)
  651. end
  652. end
  653.  
  654. function BasePlayer:SaveCell()
  655.  
  656. -- Keep this around to update old player files
  657. if self.data.mapExplored == nil then
  658. self.data.mapExplored = {}
  659. end
  660.  
  661. local cell = tes3mp.GetCell(self.pid)
  662.  
  663. self.data.location.cell = cell
  664. self.data.location.posX = tes3mp.GetPosX(self.pid)
  665. self.data.location.posY = tes3mp.GetPosY(self.pid)
  666. self.data.location.posZ = tes3mp.GetPosZ(self.pid)
  667. self.data.location.rotX = tes3mp.GetRotX(self.pid)
  668. self.data.location.rotZ = tes3mp.GetRotZ(self.pid)
  669.  
  670. if tes3mp.IsInExterior(self.pid) == true then
  671.  
  672. if tableHelper.containsValue(self.data.mapExplored, cell) == false then
  673. table.insert(self.data.mapExplored, cell)
  674. end
  675. end
  676. end
  677.  
  678. function BasePlayer:LoadEquipment()
  679.  
  680. for i = 0, tes3mp.GetEquipmentSize() - 1 do
  681.  
  682. local currentItem = self.data.equipment[i]
  683.  
  684. if currentItem ~= nil then
  685. if currentItem.enchantmentCharge == nil then
  686. currentItem.enchantmentCharge = -1
  687. end
  688.  
  689. tes3mp.EquipItem(self.pid, i, currentItem.refId, currentItem.count, currentItem.charge, currentItem.enchantmentCharge)
  690. else
  691. tes3mp.UnequipItem(self.pid, i)
  692. end
  693. end
  694.  
  695. tes3mp.SendEquipment(self.pid)
  696. end
  697.  
  698. function BasePlayer:SaveEquipment()
  699.  
  700. local reloadAtEnd = false
  701.  
  702. self.data.equipment = {}
  703.  
  704. for i = 0, tes3mp.GetEquipmentSize() - 1 do
  705. local itemRefId = tes3mp.GetEquipmentItemRefId(self.pid, i)
  706.  
  707. if itemRefId ~= "" then
  708. if tableHelper.containsValue(config.bannedEquipmentItems, itemRefId) then
  709. self:Message("You have tried wearing an item that isn't allowed!\n")
  710. reloadAtEnd = true
  711. else
  712. self.data.equipment[i] = {
  713. refId = itemRefId,
  714. count = tes3mp.GetEquipmentItemCount(self.pid, i),
  715. charge = tes3mp.GetEquipmentItemCharge(self.pid, i),
  716. enchantmentCharge = tes3mp.GetEquipmentItemEnchantmentCharge(self.pid, i)
  717. }
  718. end
  719. end
  720. end
  721.  
  722. if reloadAtEnd then
  723. -- Disable and enable the player's menus to avoid an inventory view that hasn't
  724. -- been properly updated (to be fixed for 0.6.3)
  725. myMod.RunConsoleCommandOnPlayer(self.pid, "tm")
  726. myMod.RunConsoleCommandOnPlayer(self.pid, "tm")
  727. self:LoadEquipment()
  728. end
  729. end
  730.  
  731. function BasePlayer:LoadInventory()
  732.  
  733. if self.data.inventory == nil then
  734. self.data.inventory = {}
  735. end
  736.  
  737. -- Send an empty initialized inventory to clear the player's existing items
  738. tes3mp.InitializeInventoryChanges(self.pid)
  739. tes3mp.SendInventoryChanges(self.pid)
  740.  
  741. for index, currentItem in pairs(self.data.inventory) do
  742.  
  743. if currentItem ~= nil then
  744. if currentItem.count < 1 then
  745. self.data.inventory[index] = nil
  746. else
  747. if currentItem.charge == nil or currentItem.charge < -1 then
  748. currentItem.charge = -1
  749. end
  750.  
  751. if currentItem.enchantmentCharge == nil or currentItem.enchantmentCharge < -1 then
  752. currentItem.enchantmentCharge = -1
  753. end
  754.  
  755. tes3mp.AddItem(self.pid, currentItem.refId, currentItem.count, currentItem.charge, currentItem.enchantmentCharge)
  756. end
  757. end
  758. end
  759.  
  760. tes3mp.SendInventoryChanges(self.pid)
  761. end
  762.  
  763. function BasePlayer:SaveInventory()
  764.  
  765. self.data.inventory = {}
  766.  
  767. for i = 0, tes3mp.GetInventoryChangesSize(self.pid) - 1 do
  768. local itemRefId = tes3mp.GetInventoryItemRefId(self.pid, i)
  769.  
  770. if itemRefId ~= "" then
  771. self.data.inventory[i] = {
  772. refId = itemRefId,
  773. count = tes3mp.GetInventoryItemCount(self.pid, i),
  774. charge = tes3mp.GetInventoryItemCharge(self.pid, i),
  775. enchantmentCharge = tes3mp.GetInventoryItemEnchantmentCharge(self.pid, i)
  776. }
  777. end
  778. end
  779. end
  780.  
  781. function BasePlayer:LoadSpellbook()
  782.  
  783. if self.data.spellbook == nil then
  784. self.data.spellbook = {}
  785. end
  786.  
  787. tes3mp.InitializeSpellbookChanges(self.pid)
  788. tes3mp.SetSpellbookChangesAction(self.pid, actionTypes.spellbook.SET)
  789.  
  790. for index, currentSpell in pairs(self.data.spellbook) do
  791.  
  792. if currentSpell ~= nil then
  793. tes3mp.AddSpell(self.pid, currentSpell.spellId)
  794. end
  795. end
  796.  
  797. tes3mp.SendSpellbookChanges(self.pid)
  798. end
  799.  
  800. function BasePlayer:AddSpells()
  801.  
  802. for i = 0, tes3mp.GetSpellbookChangesSize(self.pid) - 1 do
  803. local spellId = tes3mp.GetSpellId(self.pid, i)
  804.  
  805. -- Only add new spell if we don't already have it
  806. if tableHelper.containsKeyValue(self.data.spellbook, "spellId", spellId, true) == false then
  807. tes3mp.LogMessage(1, "Adding spell " .. spellId .. " to " .. tes3mp.GetName(self.pid))
  808. local newSpell = {}
  809. newSpell.spellId = spellId
  810. table.insert(self.data.spellbook, newSpell)
  811. end
  812. end
  813. end
  814.  
  815. function BasePlayer:RemoveSpells()
  816.  
  817. for i = 0, tes3mp.GetSpellbookChangesSize(self.pid) - 1 do
  818. local spellId = tes3mp.GetSpellId(self.pid, i)
  819.  
  820. -- Only print spell removal if the spell actually exists
  821. if tableHelper.containsKeyValue(self.data.spellbook, "spellId", spellId, true) == true then
  822. tes3mp.LogMessage(1, "Removing spell " .. spellId .. " from " .. tes3mp.GetName(self.pid))
  823. local foundIndex = tableHelper.getIndexByNestedKeyValue(self.data.spellbook, "spellId", spellId)
  824. self.data.spellbook[foundIndex] = nil
  825. end
  826. end
  827.  
  828. tableHelper.cleanNils(self.data.spellbook)
  829. end
  830.  
  831. function BasePlayer:SetSpells()
  832.  
  833. self.data.spellbook = {}
  834. self:AddSpells()
  835. end
  836.  
  837. function BasePlayer:LoadQuickKeys()
  838.  
  839. if self.data.quickKeys == nil then
  840. self.data.quickKeys = {}
  841. end
  842.  
  843. tes3mp.InitializeQuickKeyChanges(self.pid)
  844.  
  845. for slot, currentQuickKey in pairs(self.data.quickKeys) do
  846.  
  847. if currentQuickKey ~= nil then
  848. tes3mp.AddQuickKey(self.pid, slot, currentQuickKey.keyType, currentQuickKey.itemId)
  849. end
  850. end
  851.  
  852. tes3mp.SendQuickKeyChanges(self.pid)
  853. end
  854.  
  855. function BasePlayer:SaveQuickKeys()
  856.  
  857. for i = 0, tes3mp.GetQuickKeyChangesSize(self.pid) - 1 do
  858.  
  859. local slot = tes3mp.GetQuickKeySlot(self.pid, i)
  860.  
  861. self.data.quickKeys[slot] = {
  862. keyType = tes3mp.GetQuickKeyType(self.pid, i),
  863. itemId = tes3mp.GetQuickKeyItemId(self.pid, i)
  864. }
  865. end
  866. end
  867.  
  868. function BasePlayer:LoadJournal()
  869. stateHelper:LoadJournal(self.pid, self)
  870. end
  871.  
  872. function BasePlayer:SaveJournal()
  873. stateHelper:SaveJournal(self.pid, self)
  874. end
  875.  
  876. function BasePlayer:LoadFactionRanks()
  877. stateHelper:LoadFactionRanks(self.pid, self)
  878. end
  879.  
  880. function BasePlayer:SaveFactionRanks()
  881. stateHelper:SaveFactionRanks(self.pid, self)
  882. end
  883.  
  884. function BasePlayer:LoadFactionExpulsion()
  885. stateHelper:LoadFactionExpulsion(self.pid, self)
  886. end
  887.  
  888. function BasePlayer:SaveFactionExpulsion()
  889. stateHelper:SaveFactionExpulsion(self.pid, self)
  890. end
  891.  
  892. function BasePlayer:LoadFactionReputation()
  893. stateHelper:LoadFactionReputation(self.pid, self)
  894. end
  895.  
  896. function BasePlayer:SaveFactionReputation()
  897. stateHelper:SaveFactionReputation(self.pid, self)
  898. end
  899.  
  900. function BasePlayer:LoadTopics()
  901. stateHelper:LoadTopics(self.pid, self)
  902. end
  903.  
  904. function BasePlayer:SaveTopics()
  905. stateHelper:SaveTopics(self.pid, self)
  906. end
  907.  
  908. function BasePlayer:LoadBooks()
  909.  
  910. if self.data.books == nil then
  911. self.data.books = {}
  912. end
  913.  
  914. tes3mp.InitializeBookChanges(self.pid)
  915.  
  916. for index, bookId in pairs(self.data.books) do
  917.  
  918. tes3mp.AddBook(self.pid, bookId)
  919. end
  920.  
  921. tes3mp.SendBookChanges(self.pid)
  922. end
  923.  
  924. function BasePlayer:AddBooks()
  925.  
  926. for i = 0, tes3mp.GetBookChangesSize(self.pid) - 1 do
  927. local bookId = tes3mp.GetBookId(self.pid, i)
  928.  
  929. -- Only add new book if we don't already have it
  930. if tableHelper.containsValue(self.data.books, bookId, false) == false then
  931. tes3mp.LogMessage(1, "Adding book " .. bookId .. " to " .. tes3mp.GetName(self.pid))
  932. table.insert(self.data.books, bookId)
  933. end
  934. end
  935. end
  936.  
  937. function BasePlayer:LoadMap()
  938.  
  939. if self.data.mapExplored == nil then
  940. self.data.mapExplored = {}
  941. end
  942.  
  943. tes3mp.InitializeMapChanges(self.pid)
  944.  
  945. for index, cellDescription in pairs(self.data.mapExplored) do
  946.  
  947. tes3mp.AddCellExplored(self.pid, cellDescription)
  948. end
  949.  
  950. tes3mp.SendMapChanges(self.pid)
  951. end
  952.  
  953. function BasePlayer:GetDifficulty(state)
  954. return self.data.settings.difficulty
  955. end
  956.  
  957. function BasePlayer:GetConsoleAllowed(state)
  958. return self.data.settings.consoleAllowed
  959. end
  960.  
  961. function BasePlayer:GetBedRestAllowed(state)
  962. return self.data.settings.bedRestAllowed
  963. end
  964.  
  965. function BasePlayer:GetWildernessRestAllowed(state)
  966. return self.data.settings.wildernessRestAllowed
  967. end
  968.  
  969. function BasePlayer:GetWaitAllowed(state)
  970. return self.data.settings.waitAllowed
  971. end
  972.  
  973. function BasePlayer:SetDifficulty(difficulty)
  974. if difficulty == nil or difficulty == "default" then
  975. difficulty = config.difficulty
  976. self.data.settings.difficulty = "default"
  977. else
  978. self.data.settings.difficulty = difficulty
  979. end
  980.  
  981. tes3mp.SetDifficulty(self.pid, difficulty)
  982. tes3mp.LogMessage(3, "Set difficulty to " .. tostring(difficulty) .. " for " .. self.pid)
  983. end
  984.  
  985. function BasePlayer:SetConsoleAllowed(state)
  986. if state == nil or state == "default" then
  987. state = config.allowConsole
  988. self.data.settings.consoleAllowed = "default"
  989. else
  990. self.data.settings.consoleAllowed = state
  991. end
  992.  
  993. tes3mp.SetConsoleAllowed(self.pid, state)
  994. end
  995.  
  996. function BasePlayer:SetBedRestAllowed(state)
  997. if state == nil or state == "default" then
  998. state = config.allowBedRest
  999. self.data.settings.bedRestAllowed = "default"
  1000. else
  1001. self.data.settings.bedRestAllowed = state
  1002. end
  1003.  
  1004. tes3mp.SetBedRestAllowed(self.pid, state)
  1005. end
  1006.  
  1007. function BasePlayer:SetWildernessRestAllowed(state)
  1008. if state == nil or state == "default" then
  1009. state = config.allowWildernessRest
  1010. self.data.settings.wildernessRestAllowed = "default"
  1011. else
  1012. self.data.settings.wildernessRestAllowed = state
  1013. end
  1014.  
  1015. tes3mp.SetWildernessRestAllowed(self.pid, state)
  1016. end
  1017.  
  1018. function BasePlayer:SetWaitAllowed(state)
  1019. if state == nil or state == "default" then
  1020. state = config.allowWait
  1021. self.data.settings.waitAllowed = "default"
  1022. else
  1023. self.data.settings.waitAllowed = state
  1024. end
  1025.  
  1026. tes3mp.SetWaitAllowed(self.pid, state)
  1027. end
  1028.  
  1029. function BasePlayer:SetWerewolfState(state)
  1030. self.data.shapeshift.isWerewolf = state
  1031.  
  1032. tes3mp.SetWerewolfState(self.pid, state)
  1033. tes3mp.SendShapeshift(self.pid)
  1034. end
  1035.  
  1036. function BasePlayer:SetConfiscationState(state)
  1037.  
  1038. self.data.customVariables.isConfiscationTarget = state
  1039.  
  1040. if self:IsLoggedIn() then
  1041.  
  1042. if state == true then
  1043. myMod.RunConsoleCommandOnPlayer(self.pid, "tm")
  1044. myMod.RunConsoleCommandOnPlayer(self.pid, "disableplayercontrols")
  1045. tes3mp.MessageBox(self.pid, -1, "You are immobilized while an item is being confiscated from you")
  1046. elseif state == false then
  1047. self.data.customVariables.isConfiscationTarget = nil
  1048. myMod.RunConsoleCommandOnPlayer(self.pid, "tm")
  1049. myMod.RunConsoleCommandOnPlayer(self.pid, "enableplayercontrols")
  1050. tes3mp.MessageBox(self.pid, -1, "You are free to move again")
  1051. end
  1052. end
  1053. end
  1054.  
  1055. function BasePlayer:LoadSettings()
  1056.  
  1057. self:SetDifficulty(self.data.settings.difficulty)
  1058. self:SetConsoleAllowed(self.data.settings.consoleAllowed)
  1059. self:SetBedRestAllowed(self.data.settings.bedRestAllowed)
  1060. self:SetWildernessRestAllowed(self.data.settings.wildernessRestAllowed)
  1061. self:SetWaitAllowed(self.data.settings.waitAllowed)
  1062.  
  1063. tes3mp.SendSettings(self.pid)
  1064. end
  1065.  
  1066. function BasePlayer:LoadSpecialStates()
  1067.  
  1068. if self.data.customVariables.isConfiscationTarget ~= nil then
  1069. self:SetConfiscationState(self.data.customVariables.isConfiscationTarget)
  1070. end
  1071. end
  1072.  
  1073. function BasePlayer:AddCellLoaded(cellDescription)
  1074.  
  1075. -- Only add new loaded cell if we don't already have it
  1076. if tableHelper.containsValue(self.cellsLoaded, cellDescription) == false then
  1077. table.insert(self.cellsLoaded, cellDescription)
  1078. end
  1079. end
  1080.  
  1081. function BasePlayer:RemoveCellLoaded(cellDescription)
  1082.  
  1083. tableHelper.removeValue(self.cellsLoaded, cellDescription)
  1084. end
  1085.  
  1086. return BasePlayer
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement