123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506 |
- Hud = class()
- Hud.bonuses = {
- wreckingBall = {
- name = 'Wrecking Ball',
- description = 'Kill all buildings',
- score = 100000,
- color = 'silver',
- check = function()
- local aliveBuilding = false
- table.each(ctx.buildings.objects, function(building)
- if not building.destroyed then
- aliveBuilding = true
- end
- end)
- return not aliveBuilding
- end
- },
- bigBadPigeon = {
- name = 'Big Bad Pigeon',
- description = 'Kill no buildings',
- score = 50000,
- color = 'bronze',
- check = function()
- return ctx.stats.buildingsDestroyed == 0
- end
- },
- genocide = {
- name = 'Genocide',
- description = 'Kill all people',
- score = 250000,
- color = 'gold',
- check = function()
- local aliveBuilding = false
- table.each(ctx.buildings.objects, function(building)
- if not building.destroyed then
- aliveBuilding = true
- end
- end)
- local alivePerson = false
- table.each(ctx.enemies.objects, function(person)
- if person.state ~= 'dead' then
- alivePerson = true
- end
- end)
- return not aliveBuilding and not alivePerson
- end
- },
- hopper = {
- name = 'Hopper',
- description = 'Don\'t stop jumping',
- score = 100000,
- color = 'silver',
- check = function()
- return ctx.pigeon.stepsTaken == 0
- end
- },
- woodpecker = {
- name = 'Woodpecker',
- description = 'Kill everything by pecking',
- score = 250000,
- color = 'gold',
- check = function()
- return ctx.nonPeckKill == false and ctx.pigeon.pecks > 0
- end
- },
- verticallyChallenged = {
- name = 'Vertically Challenged',
- description = 'Don\'t jump',
- score = 25000,
- color = 'bronze',
- check = function()
- return ctx.pigeon.jumps == 0
- end
- },
- stiff = {
- name = 'Stiff Neck',
- description = 'Don\'t peck',
- score = 25000,
- color = 'bronze',
- check = function()
- return ctx.pigeon.pecks == 0
- end
- },
- pacifist = {
- name = 'Pacifist',
- description = 'Don\'t kill anything',
- score = 500000,
- color = 'gold',
- check = function()
- return ctx.stats.buildingsDestroyed == 0 and ctx.stats.peopleKilled == 0
- end
- },
- scrub = {
- name = 'Scrub',
- description = 'Get a max combo of 25 or less',
- score = 50000,
- color = 'bronze',
- check = function()
- return ctx.stats.maxCombo <= 25
- end
- },
- badass = {
- name = 'Badass',
- description = 'Get a max combo of 100 or higher',
- score = 100000,
- color = 'silver',
- check = function()
- return ctx.stats.maxCombo >= 100
- end
- },
- korean = {
- name = 'Korean',
- description = 'Get the highest possible max combo',
- score = 500000,
- color = 'gold',
- check = function()
- return ctx.stats.maxCombo >= ctx.stats.maxMaxCombo
- end
- },
- fabulous = {
- name = 'Fabulous',
- description = 'End the game in turbo mode',
- score = 100000,
- color = 'silver',
- check = function()
- return ctx.pigeon.rainbowShitTimer > 0
- end
- },
- youTried = {
- name = 'You Tried',
- description = 'Get no medals',
- score = 250000,
- color = 'silver',
- postCheck = function()
- return #ctx.hud.win.bonuses == 0
- end
- }
- }
- function Hud:init()
- ctx.event:emit('view.register', {object = self, mode = 'gui'})
- self.score = 0
- self.scoreDisplay = self.score
- self.startTimer = 3
- self.goTimer = 1.5
- self.bubble = {}
- self:resetBubble()
- self.rainbowShitCounter = 0
- self.rainbowShitDisplay = 0
- self.prevRainbowShitDisplay = 0
- self.win = {}
- self.win.active = false
- self.win.width = 800
- self.win.height = 500
- self.win.x = -400
- self.win.prevx = self.win.x
- self.deathBulge = 0
- end
- function Hud:update()
- self.prevRainbowShitDisplay = self.rainbowShitDisplay
- self.bubble.prevy = self.bubble.y
- self.bubble.prevScale = self.bubble.scale
- self.bubble.prevTimer = self.bubble.timer
- self.startTimer = timer.rot(self.startTimer, function()
- ctx.pigeon:changeState('walk')
- ctx.startTick = ls.tick
- end)
- if self.startTimer == 0 then
- self.goTimer = timer.rot(self.goTimer)
- end
- if self.bubble.active then
- self.bubble.y = math.lerp(self.bubble.y, self.bubble.targetY, 12 * ls.tickrate)
- self.bubble.scale = math.lerp(self.bubble.scale, self.bubble.targetScale, 12 * ls.tickrate)
- self.bubble.amountDisplay = math.lerp(self.bubble.amountDisplay, self.bubble.amount, 12 * ls.tickrate)
- self.bubble.timer = timer.rot(self.bubble.timer, function()
- self.score = self.score + self.bubble.amount * self.bubble.multiplier
- ctx.stats.maxCombo = math.max(ctx.stats.maxCombo, self.bubble.multiplier)
- self:resetBubble()
- end)
- end
- if self.win.active then
- self.win.prevx = self.win.x
- self.win.x = math.lerp(self.win.x, love.graphics.getWidth() / 2, 8 * ls.tickrate)
- end
- self.rainbowShitDisplay = math.lerp(self.rainbowShitDisplay, self.rainbowShitCounter, 8 * ls.tickrate)
- self.scoreDisplay = math.lerp(self.scoreDisplay, self.score, 5 * ls.tickrate)
- self.deathBulge = math.lerp(self.deathBulge, 0, 8 * ls.tickrate)
- end
- function Hud:gui()
- local g = love.graphics
- local gw, gh = g.getDimensions()
- if ctx.debug then
- local x, y = ctx.view:worldPoint(love.mouse.getPosition())
- g.setFont('media/fonts/handDrawnShapes.ttf', 24)
- g.setColor(0, 0, 0)
- g.print(x .. ', ' .. y, 9, 9)
- g.setColor(255, 255, 255)
- g.print(x .. ', ' .. y, 8, 8)
- x, y = love.mouse.getPosition()
- g.line(x, 0, x, gh)
- g.line(0, y, gw, y)
- end
- if not self.win.active then
- g.setFont('media/fonts/handDrawnShapes.ttf', 24)
- g.setColor(0, 0, 0, 150)
- local str = math.round(self.scoreDisplay)
- local w = math.max(g.getFont():getWidth(str), 80)
- local h = g.getFont():getHeight()
- g.rectangle('fill', 0, 0, w + 16, h + 16)
- g.setColor(255, 255, 255)
- g.print(str, 8, 8)
- end
- if self.bubble.active then
- local y, scale = math.lerp(self.bubble.prevy, self.bubble.y, ls.accum / ls.tickrate), math.lerp(self.bubble.prevScale, self.bubble.scale, ls.accum / ls.tickrate)
- g.setFont('media/fonts/BebasNeueBold.otf', math.max(math.round(scale / .01) * .01 * 24, 1))
- local alpha = math.clamp(math.lerp(self.bubble.prevTimer, self.bubble.timer, ls.accum / ls.tickrate), 0, 1)
- g.setColor(0, 0, 0, 128 * alpha)
- local amount = math.round(self.bubble.amountDisplay)
- local str = amount .. (self.bubble.multiplier > 1 and (' X ' .. self.bubble.multiplier) or '')
- local textWidth = g.getFont():getWidth(str)
- g.print(str, gw / 2 - textWidth / 2 + 1, y + 1)
- g.setColor(255, 255, 255, 255 * alpha)
- g.print(str, gw / 2 - textWidth / 2, y)
- end
- local baseWidth = 20
- local baseHeight = 100
- if ctx.pigeon.rainbowShitTimer > 0 then
- love.math.setRandomSeed(math.max(love.timer.getTime() * ctx.pigeon.rainbowShitTimer - self.scoreDisplay, 1))
- local prc = math.min(ctx.pigeon.rainbowShitTimer / 5, 1)
- g.setColor(128 + love.math.random() * 127, 128 + love.math.random() * 127, 128 + love.math.random() * 127)
- g.rectangle('fill', 2, 50 + baseHeight * (1 - prc), baseWidth, baseHeight * prc)
- else
- g.setColor(255, 0, 0)
- end
- local baseWidth = 20
- local baseHeight = 100
- g.rectangle('line', 2, 50, baseWidth, baseHeight)
- local prc = math.clamp(math.lerp(self.prevRainbowShitDisplay, self.rainbowShitDisplay, ls.accum / ls.tickrate) / Pigeon.rainbowShitThreshold, 0, 1)
- g.setColor(255, 0, 0)
- g.rectangle('fill', 2, 50 + baseHeight * (1 - prc), baseWidth, baseHeight * prc)
- if self.startTimer > 0 then
- local str = math.ceil(self.startTimer)
- g.setFont('media/fonts/handDrawnShapes.ttf', 80)
- g.setColor(0, 0, 0)
- g.print(str, gw / 2 - g.getFont():getWidth(str) / 2 + 2, 200 - g.getFont():getHeight() / 2 + 2)
- g.setColor(255, 255, 255)
- g.print(str, gw / 2 - g.getFont():getWidth(str) / 2, 200 - g.getFont():getHeight() / 2)
- elseif self.goTimer > 0 then
- local str = 'GO!'
- local alpha = 255 * math.clamp(self.goTimer, 0, 1)
- g.setFont('media/fonts/handDrawnShapes.ttf', 80)
- g.setColor(0, 0, 0, alpha)
- g.print(str, gw / 2 - g.getFont():getWidth(str) / 2 + 2, 200 - g.getFont():getHeight() / 2 + 2)
- g.setColor(255, 255, 255, alpha)
- g.print(str, gw / 2 - g.getFont():getWidth(str) / 2, 200 - g.getFont():getHeight() / 2)
- end
- if self.win.active then
- g.setColor(0, 0, 0, 100)
- local x = math.lerp(self.win.prevx, self.win.x, ls.accum / ls.tickrate)
- local w, h = self.win.width, self.win.height
- w = gw
- g.rectangle('fill', 0, 0, gw, gh)
- g.setFont('media/fonts/handDrawnShapes.ttf', 40)
- local str = 'Congration you done it!'
- local yy = 64
- g.setColor(0, 0, 0)
- g.print(str, x - g.getFont():getWidth(str) / 2 + 2, yy + 2)
- g.setColor(255, 255, 255)
- g.print(str, x - g.getFont():getWidth(str) / 2, yy)
- yy = yy + g.getFont():getHeight() + 10
- local str = math.round(self.scoreDisplay)
- g.setColor(0, 0, 0)
- g.print('Your score:', x - g.getFont():getWidth('Your score:') / 2 + 2, yy + 2)
- g.setColor(255, 255, 255)
- g.print('Your score:', x - g.getFont():getWidth('Your score:') / 2, yy)
- yy = yy + g.getFont():getHeight() + 15
- g.setFont('media/fonts/handDrawnShapes.ttf', 48)
- g.setColor(0, 0, 0)
- g.print(str, x - g.getFont():getWidth(str) / 2 + 2, yy + 2)
- g.setColor(255, 255, 255)
- g.print(str, x - g.getFont():getWidth(str) / 2, yy)
- yy = yy + g.getFont():getHeight() + 32
- g.setFont('media/fonts/runescape.ttf', 16)
- local xx = gw / 4 - 100
- local d = (gw / 2) - x
- local yy = gh * .7
- local function printShadow(str, x, y, off)
- off = off or 1
- g.setColor(0, 0, 0)
- g.print(str, x - d + off, y + off)
- g.setColor(255, 255, 255)
- g.print(str, x - d, y)
- end
- printShadow('Time:', xx, yy)
- local t = math.floor(ctx.stats.time)
- local seconds = math.floor(t % 60)
- local minutes = math.floor(t / 60)
- if minutes < 10 then minutes = '0' .. minutes end
- if seconds < 10 then seconds = '0' .. seconds end
- printShadow(minutes .. ':' .. seconds, xx + 150, yy)
- yy = yy + g.getFont():getHeight() + 6
- printShadow('Max Combo:', xx, yy)
- printShadow(ctx.stats.maxCombo, xx + 150, yy)
- yy = yy + g.getFont():getHeight() + 6
- printShadow('People Killed:', xx, yy)
- printShadow(ctx.stats.peopleKilled .. ' (' .. (ctx.stats.peoplePercentage * 100) .. '%)', xx + 150, yy)
- yy = yy + g.getFont():getHeight() + 6
- xx = gw * .75 - 100
- yy = gh * .7
- printShadow('Buildings Destroyed:', xx, yy)
- printShadow(ctx.stats.buildingsDestroyed .. ' (' .. (ctx.stats.buildingPercentage * 100) .. '%)', xx + 150, yy)
- yy = yy + g.getFont():getHeight() + 6
- printShadow('Pecks:', xx, yy)
- printShadow(ctx.pigeon.pecks, xx + 150, yy)
- yy = yy + g.getFont():getHeight() + 6
- printShadow('Jumps:', xx, yy)
- printShadow(ctx.pigeon.jumps, xx + 150, yy)
- yy = yy + g.getFont():getHeight() + 6
- --
- local ct = #self.win.bonuses
- local inc = 200
- local xx = x - (inc * (ct - 1) / 2)
- while inc * ct > gw do
- inc = inc - 10
- end
- local mx, my = love.mouse.getPosition()
- local flyoutService = nil
- g.setFont('media/fonts/handDrawnShapes.ttf', 24)
- for i = 1, ct do
- local name = self.win.bonuses[i]
- local bonus = self.bonuses[name]
- local image = data.media.graphics.ui[bonus.color]
- local scale = 80 / image:getHeight()
- g.setColor(255, 255, 255)
- g.draw(image, xx, gh / 2 - 20, 0, scale, scale, image:getWidth() / 2, image:getHeight() / 2)
- local str = bonus.name
- g.setColor(0, 0, 0)
- g.print(str, xx - g.getFont():getWidth(str) / 2 + 2, gh / 2 - 20 + 60 + 2)
- g.setColor(255, 255, 255)
- g.print(str, xx - g.getFont():getWidth(str) / 2, gh / 2 - 20 + 60)
- if math.inside(mx, my, xx - image:getWidth() * scale / 2, gh / 2 - 20 - image:getHeight() * scale / 2, image:getWidth() * scale, image:getHeight() * scale) then
- flyoutService = bonus.description .. '\n' .. '+' .. bonus.score
- end
- xx = xx + inc
- end
- g.setFont('media/fonts/runescape.ttf', 16)
- if flyoutService then
- g.setColor(0, 0, 0, 200)
- local w = g.getFont():getWidth(flyoutService) + 8
- local h = g.getFont():getHeight() * 2 + 8
- g.rectangle('fill', mx + 8, my + 8, w, h)
- g.setColor(255, 255, 255)
- g.print(flyoutService, mx + 12, my + 12)
- end
- local alpha = math.abs(math.sin((ls.tick + ls.accum / ls.tickrate) / 25))
- local str = 'Press ' .. (joystick and 'A' or 'space') .. ' to continue'
- g.setFont('media/fonts/handDrawnShapes.ttf', 30)
- g.setColor(0, 0, 0, alpha * 255)
- g.print(str, x - g.getFont():getWidth(str) / 2 + 2, gh - 55 + 2)
- g.setColor(255, 255, 255, alpha * 255)
- g.print(str, x - g.getFont():getWidth(str) / 2, gh - 55)
- g.setFont('media/fonts/runescape.ttf', 16)
- local str = 'Press T to tweet your score!'
- g.setColor(0, 0, 0)
- g.print(str, x - g.getFont():getWidth(str) / 2 + 1, gh - 24 + 1)
- g.setColor(255, 255, 255)
- g.print(str, x - g.getFont():getWidth(str) / 2, gh - 24)
- end
- if ctx.map.name == 'dinoland' and ctx.map.index == 1 then
- local x, y = ctx.view:screenPoint(1067 / 2, ctx.map.height - 40)
- local str = 'Up = Jump, Space = Peck'
- g.setFont('media/fonts/handDrawnShapes.ttf', 30)
- g.setColor(0, 0, 0)
- g.print(str, x - g.getFont():getWidth(str) / 2 + 1, y - g.getFont():getHeight() / 2 + 1)
- g.setColor(255, 255, 255)
- g.print(str, x - g.getFont():getWidth(str) / 2, y - g.getFont():getHeight() / 2)
- end
- end
- function Hud:paused()
- self.prevRainbowShitDisplay = self.rainbowShitDisplay
- self.bubble.prevy = self.bubble.y
- self.bubble.prevScale = self.bubble.scale
- self.bubble.prevTimer = self.bubble.timer
- if self.win.active then
- self.win.prevx = self.win.x
- end
- end
- function Hud:resetBubble()
- self.bubble.active = false
- self.bubble.amount = 0
- self.bubble.amountDisplay = self.bubble.amount
- self.bubble.timer = 0
- self.bubble.multiplier = 0
- self.bubble.targetY = 200
- self.bubble.y = self.bubble.targetY
- self.bubble.prevy = self.bubble.y
- self.bubble.targetScale = 1
- self.bubble.scale = self.bubble.targetScale
- self.bubble.prevScale = self.bubble.scale
- self.rainbowShitCounter = 0
- end
- function Hud:addScore(amount, kind, cause)
- if cause == 'peck' then
- amount = amount * 2
- end
- self.bubble.active = true
- self.bubble.timer = 3
- self.bubble.amount = self.bubble.amount + amount
- self.bubble.multiplier = self.bubble.multiplier + 1
- self.bubble.scale = self.bubble.scale + .2
- self.bubble.targetScale = self.bubble.targetScale + .1
- self.bubble.targetY = math.lerp(self.bubble.targetY, 50, .15)
- self.bubble.prevTimer = self.bubble.timer
- if kind == 'person' then
- self.rainbowShitCounter = self.bubble.multiplier --self.rainbowShitCounter + 1
- if self.rainbowShitCounter % 50 == 0 then
- --self.rainbowShitCounter = 0
- ctx.pigeon:activateRainbowShit()
- end
- end
- end
- function Hud:activateWin()
- self.score = self.score + self.bubble.amount * self.bubble.multiplier
- ctx.stats.maxCombo = math.max(ctx.stats.maxCombo, self.bubble.multiplier)
- self:resetBubble()
- ctx.stats.peoplePercentage = lume.round(ctx.stats.peopleKilled / ctx.stats.originalPeople, .01)
- ctx.stats.buildingPercentage = lume.round(ctx.stats.buildingsDestroyed / ctx.stats.originalBuildings, .01)
- ctx.stats.time = (ls.tick - ctx.startTick) * ls.tickrate
- self.win.active = true
- self.win.bonuses = {}
- collectgarbage()
- table.each(self.bonuses, function(bonus, name)
- if bonus.check and bonus.check() then
- table.insert(self.win.bonuses, name)
- self.score = self.score + bonus.score
- end
- end)
- table.each(self.bonuses, function(bonus, name)
- if bonus.postCheck and bonus.postCheck() then
- table.insert(self.win.bonuses, name)
- self.score = self.score + bonus.score
- end
- end)
- self.scoreDisplay = 0
- end
- function Hud:share()
- local level = ctx.map.name == 'dinoland' and 1 or 2
- level = tostring(level) .. '-' .. tostring(ctx.map.index)
- local url = 'http://twitter.com/intent/tweet?text=I%20got%20a%20new%20highscore%20of%20' .. math.round(self.scoreDisplay) .. '%20points%20on%20level%20' .. level .. '%20of%20%23FowlPlay!%20%23RobotPigeon'
- love.system.openURL(url)
- end
|