huddeadcampaign.lua 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. HudDeadCampaign = class()
  2. local g = love.graphics
  3. function HudDeadCampaign:init(hud)
  4. self.geometry = setmetatable({}, {__index = function(t, k)
  5. return rawset(t, k, self.geometryFunctions[k]())[k]
  6. end})
  7. self.geometryFunctions = {
  8. deadOk = function()
  9. local u, v = hud.u, hud.v
  10. local w = u * .25
  11. local h = v * .1
  12. local x = u / 2 - w / 2
  13. local y = v - .15 * v - h
  14. return {x, y, w, h}
  15. end
  16. }
  17. self.deadOk = hud.gooey:add(Button, 'hud.dead.ok')
  18. self.deadOk.geometry = function() return self.geometry.deadOk end
  19. self.deadOk:on('click', function() self:endGame() end)
  20. self.deadOk.text = 'Finished'
  21. self.delay = 1
  22. self.timeFactor = 0
  23. self.prevTimeFactor = self.timeFactor
  24. self.soundTimer = 0
  25. self.soundRate = 2 / ls.tickrate
  26. self.alpha = 0
  27. self.prevAlpha = self.alpha
  28. self.bgAlpha = 0
  29. self.prevBgAlpha = self.bgAlpha
  30. self.medalFactors = {bronze = 0, silver = 0, gold = 0}
  31. self.prevMedalFactors = {bronze = 0, silver = 0, gold = 0}
  32. self.canvas = g.newCanvas(400, 400)
  33. local function getMousePosition()
  34. return ctx.view:frameMouseX(), ctx.view:frameMouseY()
  35. end
  36. self.deadOk.getMousePosition = getMousePosition
  37. end
  38. function HudDeadCampaign:update()
  39. if not ctx.ded then return end
  40. local u, v = ctx.hud.u, ctx.hud.v
  41. if not self.rewards then
  42. self.rewards = {}
  43. for i = 1, #ctx.rewards.runes do
  44. table.insert(self.rewards, {
  45. kind = 'rune',
  46. rune = ctx.rewards.runes[i],
  47. x = u * .5,
  48. prevx = u * .5
  49. })
  50. end
  51. for i = 1, #ctx.rewards.minions do
  52. local minion = ctx.rewards.minions[i]
  53. local reward = {
  54. kind = 'minion',
  55. minion = minion,
  56. x = u * .5,
  57. prevx = u * .5
  58. }
  59. local animationScales = {
  60. thuju = .55,
  61. bruju = 1.3,
  62. xuju = .55,
  63. kuju = .6
  64. }
  65. local animation = data.animation[minion]({scale = animationScales[minion]})
  66. animation:on('complete', function() animation:set('idle', {force = true}) end)
  67. reward.animation = animation
  68. table.insert(self.rewards, reward)
  69. end
  70. for i = 1, #ctx.rewards.hats do
  71. table.insert(self.rewards, {
  72. kind = 'hat',
  73. hat = ctx.rewards.hats[i],
  74. x = u * .5,
  75. prevx = u * .5
  76. })
  77. end
  78. end
  79. self.prevBgAlpha = self.bgAlpha
  80. self.bgAlpha = math.lerp(self.bgAlpha, 1, math.min(6 * ls.tickrate, 1))
  81. if ctx.backgroundSound:isPlaying() then
  82. ctx.backgroundSound:setVolume(math.max(ctx.backgroundSound:getVolume() - 2 * ls.tickrate, 0))
  83. if ctx.backgroundSound:getVolume() == 0 then
  84. ctx.backgroundSound:stop()
  85. end
  86. end
  87. self.delay = timer.rot(self.delay)
  88. if self.delay == 0 then
  89. self.prevAlpha = self.alpha
  90. self.alpha = math.lerp(self.alpha, 1, math.min(6 * ls.tickrate, 1))
  91. self.prevTimeFactor = self.timeFactor
  92. self.timeFactor = math.lerp(self.timeFactor, 1, 1 * ls.tickrate)
  93. local inc = .2 * u
  94. local medalX = .5 * u - (inc * (3 - 1) / 2)
  95. local rewardSize = .1 * v
  96. local rewardInc = rewardSize + .05 * v
  97. local countSoFar = 0
  98. for _, medal in pairs({'bronze', 'silver', 'gold'}) do
  99. if math.floor(ctx.timer * self.prevTimeFactor * ls.tickrate) >= config.medals[medal] then
  100. local kinds = {bronze = 'rune', silver = 'minion', gold = 'hat'}
  101. if self.rewards then
  102. for i = 1, #self.rewards do
  103. local reward = self.rewards[i]
  104. if reward.kind == kinds[medal] then
  105. countSoFar = countSoFar + 1
  106. end
  107. end
  108. end
  109. end
  110. end
  111. local rewardX = .5 * u - (rewardInc * (countSoFar - 1) / 2)
  112. for _, medal in pairs({'bronze', 'silver', 'gold'}) do
  113. if math.floor(ctx.timer * self.prevTimeFactor * ls.tickrate) >= config.medals[medal] then
  114. if self.medalFactors[medal] == 0 then
  115. ctx.particles:emit('upgrade', medalX, .37 * v, 20)
  116. ctx.sound:play('upgrade')
  117. end
  118. self.prevMedalFactors[medal] = self.medalFactors[medal]
  119. self.medalFactors[medal] = math.lerp(self.medalFactors[medal], 1, math.min(10 * ls.tickrate, 1))
  120. local kinds = {bronze = 'rune', silver = 'minion', gold = 'hat'}
  121. if self.rewards then
  122. for i = 1, #self.rewards do
  123. local reward = self.rewards[i]
  124. if reward.kind == kinds[medal] then
  125. reward.prevx = reward.x
  126. reward.x = math.lerp(reward.x, rewardX, 12 * ls.tickrate)
  127. rewardX = rewardX + rewardInc
  128. end
  129. end
  130. end
  131. end
  132. medalX = medalX + inc
  133. end
  134. self.soundTimer = timer.rot(self.soundTimer)
  135. if self.soundTimer == 0 and math.floor(ctx.timer * self.prevTimeFactor * ls.tickrate) ~= math.floor(ctx.timer * self.timeFactor * ls.tickrate) then
  136. ctx.sound:play('juju1', function(sound)
  137. sound:setPitch(.5 + self.timeFactor)
  138. sound:setVolume(.5 + self.timeFactor * .25)
  139. end)
  140. self.soundTimer = 1 / self.soundRate
  141. end
  142. end
  143. end
  144. function HudDeadCampaign:draw()
  145. if not ctx.ded then return end
  146. local u, v = ctx.hud.u, ctx.hud.v
  147. local bigFont = .09 * v
  148. local smallFont = .05 * v
  149. local alpha = math.lerp(self.prevAlpha, self.alpha, ls.accum / ls.tickrate)
  150. local bgAlpha = math.lerp(self.prevBgAlpha, self.bgAlpha, ls.accum / ls.tickrate)
  151. local timeFactor = math.lerp(self.prevTimeFactor, self.timeFactor, ls.accum / ls.tickrate)
  152. if self.timeFactor ~= 1 and math.round(ctx.timer * ls.tickrate) == math.round(ctx.timer * ls.tickrate * timeFactor) then
  153. self.timeFactor = 1
  154. timeFactor = 1
  155. ctx.sound:play('juju1', function(sound) sound:setPitch(2) end)
  156. end
  157. local x, y = .1 * u, .1 * v
  158. local padding = .05 * v
  159. g.setColor(0, 0, 0, 120 * bgAlpha)
  160. g.rectangle('fill', x, y, .8 * u, .8 * v)
  161. g.setColor(180, 255, 50)
  162. g.setFont('mesmerize', bigFont)
  163. local str = 'Game Over!'
  164. g.printShadow(str, x + padding, y + padding)
  165. if timeFactor > 0 then
  166. g.setColor(255, 255, 255)
  167. str = tostring(toTime(ctx.timer * ls.tickrate * timeFactor, true))
  168. g.printShadow(str, x + .8 * u - g.getFont():getWidth(str) - padding, y + padding)
  169. end
  170. local inc = .2 * u
  171. local medalX = .5 * u - (inc * (3 - 1) / 2)
  172. for _, medal in ipairs({'bronze', 'silver', 'gold'}) do
  173. local factor = math.lerp(self.prevMedalFactors[medal], self.medalFactors[medal], ls.accum / ls.tickrate)
  174. local size = .15 * v * (.8 + .2 * factor)
  175. local image = data.media.graphics.menu[medal]
  176. local scale = size / image:getHeight()
  177. local alpha = alpha * (.4 + .6 * factor)
  178. g.setColor(255 * alpha, 255 * alpha, 255 * alpha, 255 * alpha)
  179. g.draw(image, medalX, .4 * v, 0, scale, scale, image:getWidth() / 2, image:getHeight() / 2)
  180. medalX = medalX + inc
  181. end
  182. if self.rewards then
  183. local rewardSize = .1 * v
  184. for i = 1, #self.rewards do
  185. local reward = self.rewards[i]
  186. local medal = ({rune = 'bronze', minion = 'silver', hat = 'gold'})[reward.kind]
  187. local factor = math.lerp(self.prevMedalFactors[medal], self.medalFactors[medal], ls.accum / ls.tickrate)
  188. local x = math.lerp(reward.prevx, reward.x, ls.accum / ls.tickrate)
  189. g.setColor(255, 255, 255, 255 * factor)
  190. if reward.kind == 'rune' then
  191. g.drawRune(reward.rune, reward.x, .63 * v, rewardSize, rewardSize * .5)
  192. elseif reward.kind == 'minion' then
  193. local canvas = self.canvas
  194. local cw, ch = canvas:getDimensions()
  195. canvas:clear(0, 0, 0, 0)
  196. canvas:renderTo(function()
  197. local animation = reward.animation
  198. animation.spine.skeleton.a = factor
  199. animation:draw(cw / 2, ch / 2)
  200. end)
  201. local scale = (rewardSize / cw) * 3
  202. g.setColor(255, 255, 255)
  203. g.draw(self.canvas, reward.x, .63 * v, 0, scale, scale, cw / 2, ch / 2)
  204. elseif reward.kind == 'hat' then
  205. local image = data.media.graphics.hats[reward.hat]
  206. if image then
  207. local scale = rewardSize / math.max(image:getWidth(), image:getHeight())
  208. g.setColor(255, 255, 255, 255 * factor)
  209. g.draw(image, reward.x, .63 * v, 0, scale, scale, image:getWidth() / 2, image:getHeight() / 2)
  210. end
  211. end
  212. end
  213. end
  214. self.deadOk:draw()
  215. end
  216. function HudDeadCampaign:keypressed(key)
  217. if not ctx.ded then return end
  218. if key == 'return' then self:endGame() end
  219. end
  220. function HudDeadCampaign:mousemoved(mx, my)
  221. local u, v = ctx.hud.u, ctx.hud.v
  222. local rewardSize = .1 * v
  223. if self.rewards then
  224. for _, medal in pairs({'bronze', 'silver', 'gold'}) do
  225. if math.floor(ctx.timer * self.prevTimeFactor * ls.tickrate) >= config.medals[medal] then
  226. local kinds = {bronze = 'rune', silver = 'minion', gold = 'hat'}
  227. for i = 1, #self.rewards do
  228. local reward = self.rewards[i]
  229. if math.insideCircle(mx, my, reward.x, .63 * v, rewardSize / 2) and reward.kind == kinds[medal] then
  230. if reward.kind == 'rune' then
  231. ctx.hud.tooltip:setRuneTooltip(reward.rune)
  232. elseif reward.kind == 'minion' then
  233. ctx.hud.tooltip:setUnitTooltip(reward.minion, true)
  234. elseif reward.kind == 'hat' then
  235. ctx.hud.tooltip:setHatTooltip(reward.hat)
  236. end
  237. end
  238. end
  239. end
  240. end
  241. end
  242. end
  243. function HudDeadCampaign:endGame()
  244. Context:add(Menu, ctx.user, ctx.options, {page = ctx.mode, biome = ctx.biome, user = ctx.user, rewards = ctx.rewards})
  245. Context:remove(ctx)
  246. end