Advertisement
Guest User

Untitled

a guest
Sep 22nd, 2017
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.41 KB | None | 0 0
  1. --[[function onCreatureAppear(self, creature)
  2. if self == creature then
  3. if self:getType():isRewardBoss() then
  4. self:setReward(true)
  5. end
  6. end
  7. end--]]
  8.  
  9.  
  10. local function pushSeparated(buffer, sep, ...)
  11. local argv = {...}
  12. local argc = #argv
  13. for k, v in ipairs(argv) do
  14. table.insert(buffer, v)
  15. if k < argc and sep then
  16. table.insert(buffer, sep)
  17. end
  18. end
  19. end
  20.  
  21. local function insertItems(buffer, info, parent, items)
  22. local start = info.running
  23. for _, item in ipairs(items) do
  24. if _ ~= 1 or parent > 100 then
  25. table.insert(buffer, ",")
  26. end
  27. info.running = info.running + 1
  28. table.insert(buffer, "(")
  29. pushSeparated(buffer, ",", info.playerGuid, parent, info.running, item:getId(), item:getSubType(), db.escapeBlob(item:serializeAttributes()))
  30. table.insert(buffer, ")")
  31.  
  32. if item:isContainer() then
  33. local size = item:getSize()
  34. if size > 0 then
  35. local subItems = {}
  36. for i = 1, size do
  37. table.insert(subItems, item:getItem(i - 1))
  38. end
  39.  
  40. insertItems(buffer, info, info.running, subItems)
  41. end
  42. end
  43. end
  44. return info.running - start
  45. end
  46.  
  47. local function insertRewardItems(playerGuid, timestamp, itemList)
  48. db.asyncStoreQuery('SELECT `pid`, `sid` FROM `player_rewards` WHERE player_id = ' .. playerGuid .. ' ORDER BY `sid` ASC;',
  49. function(query)
  50. local lastReward = 0
  51. local lastStoreId
  52. if(query) then
  53. repeat
  54. local sid = result.getDataInt(query, 'sid')
  55. local pid = result.getDataInt(query, 'pid')
  56.  
  57. if pid < 100 then
  58. lastReward = pid
  59. end
  60. lastStoreId = sid
  61. until not result.next(query)
  62. end
  63.  
  64. local buffer = {'INSERT INTO `player_rewards` (`player_id`, `pid`, `sid`, `itemtype`, `count`, `attributes`) VALUES'}
  65.  
  66. --reward bag
  67. local info = {
  68. playerGuid = playerGuid,
  69. running = lastStoreId or 100
  70. }
  71.  
  72. local bag = Game.createItem(ITEM_REWARD_CONTAINER)
  73. bag:setAttribute(ITEM_ATTRIBUTE_DATE, timestamp)
  74. if itemList then
  75. for _, p in ipairs(itemList) do
  76. bag:addItem(p[1], p[2])
  77. end
  78. end
  79.  
  80. local total = insertItems(buffer, info, lastReward + 1, {bag})
  81. table.insert(buffer, ";")
  82.  
  83. if total ~= 0 then
  84. db.query(table.concat(buffer))
  85. end
  86. end
  87. )
  88. end
  89.  
  90. local function getPlayerStats(bossId, playerGuid, autocreate)
  91. local ret = globalBosses[bossId][playerGuid]
  92. if not ret and autocreate then
  93. ret = {
  94. bossId = bossId,
  95. damageIn = 0, -- damage taken from the boss
  96. healing = 0, -- healing (other players) done
  97. }
  98. globalBosses[bossId][playerGuid] = ret
  99. return ret
  100. end
  101. return ret
  102. end
  103.  
  104. function onDeath(creature, corpse, killer, mostDamageKiller, lastHitUnjustified, mostDamageUnjustified)
  105. local monsterType = creature:getType()
  106. if monsterType:isRewardBoss() then -- Make sure it is a boss
  107. local bossId = creature:getId()
  108. local timestamp = os.time()
  109.  
  110. local totalDamageOut, totalDamageIn, totalHealing = 0.1, 0.1, 0.1 -- avoid dividing by zero
  111.  
  112. local scores = {}
  113. local uniques = {}
  114. local info = globalBosses[bossId]
  115. local damageMap = creature:getDamageMap()
  116.  
  117. for guid, stats in pairs(info) do
  118. local player = Player(stats.playerId)
  119. local part = damageMap[stats.playerId]
  120. local damageOut, damageIn, healing = (stats.damageOut or 0) + (part and part.total or 0), stats.damageIn or 0, stats.healing or 0
  121.  
  122. totalDamageOut = totalDamageOut + damageOut
  123. totalDamageIn = totalDamageIn + damageIn
  124. totalHealing = totalHealing + healing
  125.  
  126. table.insert(scores, {
  127. player = player,
  128. guid = guid,
  129. damageOut = damageOut,
  130. damageIn = damageIn,
  131. healing = healing,
  132. })
  133. end
  134.  
  135. local participants = 0
  136. for _, con in ipairs(scores) do
  137. local score = (con.damageOut / totalDamageOut) + (con.damageIn / totalDamageIn) + (con.healing / totalHealing)
  138. con.score = score / 3 -- normalize to 0-1
  139. if score ~= 0 then
  140. participants = participants + 1
  141. end
  142. end
  143. table.sort(scores, function(a, b) return a.score > b.score end)
  144.  
  145. local expectedScore = 1 / participants
  146.  
  147. for _, con in ipairs(scores) do
  148. local reward, stamina -- ignoring stamina for now because I heard you receive rewards even when it's depleted
  149. if con.player then
  150. reward = con.player:getReward(timestamp, true)
  151. stamina = con.player:getStamina()
  152. else
  153. stamina = con.stamina or 0
  154. end
  155.  
  156. local playerLoot
  157. if --[[stamina > 840 and]] con.score ~= 0 then
  158. local lootFactor = 1
  159. lootFactor = lootFactor / participants ^ (1 / 3) -- tone down the loot a notch if there are many participants
  160. lootFactor = lootFactor * (1 + lootFactor) ^ (con.score / expectedScore) -- increase the loot multiplicatively by how many times the player surpassed the expected score
  161. if(_==1)then
  162. print(getCreatureName(con.player).." is the top player for the boss. ")
  163. lootFactor = lootFactor+5
  164. else
  165. --con.score=con.score/5
  166. end
  167. playerLoot = monsterType:getBossReward(lootFactor, _)
  168.  
  169. print(getCreatureName(con.player).." is next. loot factor is ".. lootFactor)
  170.  
  171. if con.player then
  172. for _, p in ipairs(playerLoot) do
  173. reward:addItem(p[1], p[2])
  174. end
  175. end
  176. end
  177.  
  178. if con.player then
  179. local lootMessage = {"The following items are available in your reward chest: "}
  180.  
  181. if --[[stamina > 840]]true then
  182. reward:getContentDescription(lootMessage)
  183. else
  184. table.insert(lootMessage, 'nothing (due to low stamina)')
  185. end
  186. table.insert(lootMessage, ".")
  187. con.player:sendTextMessage(MESSAGE_EVENT_ADVANCE, table.concat(lootMessage))
  188. else
  189. insertRewardItems(con.guid, timestamp, playerLoot)
  190. end
  191. end
  192.  
  193. globalBosses[bossId] = nil
  194. end
  195. return true
  196. end
  197.  
  198. function onThink(creature, interval)
  199. local bossId = creature:getId()
  200. local info = globalBosses[bossId]
  201. -- Reset all players' status
  202. for _, player in pairs(info) do
  203. player.active = false
  204. end
  205. -- Set all players in boss' target list as active in the fight
  206. local targets = creature:getTargetList()
  207. for _, target in ipairs(targets) do
  208. if target:isPlayer() then
  209. local stats = getPlayerStats(bossId, target:getGuid(), true)
  210. stats.playerId = target:getId() -- Update player id
  211. stats.active = true
  212. end
  213. end
  214. end
  215.  
  216. function onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
  217. if not next(globalBosses) then
  218. return primaryDamage, primaryType, secondaryDamage, secondaryType
  219. end
  220.  
  221. if not creature or not attacker then
  222. return primaryDamage, primaryType, secondaryDamage, secondaryType
  223. end
  224.  
  225. local stats = creature:inBossFight()
  226. if not stats then
  227. return primaryDamage, primaryType, secondaryDamage, secondaryType
  228. end
  229.  
  230. local creatureId, attackerId = creature:getId(), attacker:getId()
  231. stats.playerId = creatureId -- Update player id
  232.  
  233. -- Account for healing of others active in the boss fight
  234. if primaryType == COMBAT_HEALING and attacker:isPlayer() and attackerId ~= creatureId then
  235. local healerStats = getPlayerStats(stats.bossId, attacker:getGuid(), true)
  236. healerStats.active = true
  237. healerStats.playerId = attackerId -- Update player id
  238. healerStats.healing = healerStats.healing + primaryDamage
  239. elseif stats.bossId == attackerId then
  240. -- Account for damage taken from the boss
  241. stats.damageIn = stats.damageIn + primaryDamage
  242. end
  243. return primaryDamage, primaryType, secondaryDamage, secondaryType
  244. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement