| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- Game = class()
- function Game:load(user, options, info)
- self.options = options
- if self.options.textureSmoothing then
- data.media.graphics.juju:setMipmapFilter('linear', 1)
- data.media.graphics.map.forest:setMipmapFilter('linear', 1)
- data.media.graphics.map.forestSpirit:setMipmapFilter('linear', 1)
- data.media.graphics.atlas.hud:setMipmapFilter('linear', 1)
- data.media.graphics.hud.clockBlue:setMipmapFilter('linear', 1)
- data.media.graphics.hud.clockBronze:setMipmapFilter('linear', 1)
- data.media.graphics.hud.clockSilver:setMipmapFilter('linear', 1)
- data.media.graphics.hud.clockGold:setMipmapFilter('linear', 1)
- end
- self.user = user
- self.id = 1
- self.mode = info.mode
- self.biome = info.biome
- self.paused = false
- self.ded = false
- self.timer = 0
- self.event = Event()
- self.view = View()
- self.map = Map()
- self.players = Players()
- self.player = ctx.players:add(1)
- self.shrujus = Shrujus()
- self.hud = Hud()
- self.upgrades = Upgrades
- self.shrines = Manager()
- self.shrine = self.shrines:add(Shrine, {x = ctx.map.width / 2, team = 1})
- self.units = Units()
- self.spells = Spells()
- self.particles = Particles()
- self.target = Target()
- self.sound = Sound(self.options)
- self.effects = Effects()
- self.jujus = Jujus()
- self.achievements = Achievements(self.user)
- self.tutorial = Tutorial(info.tutorial, info.destination)
- Upgrades.clear()
- self.event:on('shrine.dead', function(data)
- self.youlose = ctx.sound:play('youlose')
- ctx.sound:play('death')
- self.ded = true
- self:distribute()
- end)
- self.backgroundSound = self.sound:loop(self.biome)
- love.keyboard.setKeyRepeat(false)
- if self.options.mute then self.sound:mute() end
- end
- function Game:update()
- if self.hud.upgrades.active or self.paused or self.ded then
- self.hud:update()
- if self.ded and self.effects:get('deathblur') then self.effects:get('deathblur'):update() end
- self.players:paused()
- self.units:paused()
- self.spells:paused()
- self.particles:update()
- self.tutorial:update()
- return
- end
- self.timer = self.timer + 1
- ls.framerate = self.options.powersave and (love.system.getPowerInfo() == 'battery' and 30 or 60) or -1
- self.players:update()
- self.units:update()
- self.shrines:update()
- self.jujus:update()
- self.spells:update()
- self.map:update()
- self.view:update()
- self.hud:update()
- self.effects:update()
- self.shrujus:update()
- self.tutorial:update()
- end
- function Game:unload()
- self.backgroundSound:stop()
- if self.youlose then self.youlose:stop() end
- end
- function Game:draw()
- self.view:draw()
- end
- function Game:resize()
- self.hud:resize()
- self.view:resize()
- self.effects:resize()
- end
- function Game:keypressed(key)
- if not self.ded then
- if key == 'p' or (key == 'escape' and not self.hud:menuActive()) then self.paused = not self.paused
- elseif key == 'm' then
- -- self.options.mute = not self.options.mute
- self.sound:mute()
- end
- end
- self.hud:keypressed(key)
- self.players:keypressed(key)
- self.tutorial:keypressed(key)
- end
- function Game:keyreleased(...)
- self.hud:keyreleased(...)
- end
- function Game:mousepressed(...)
- self.hud:mousepressed(...)
- end
- function Game:mousereleased(...)
- self.hud:mousereleased(...)
- end
- function Game:mousemoved(...)
- self.hud:mousemoved(...)
- end
- function Game:gamepadpressed(gamepad, button)
- print('Game:gamepadpressed', gamepad, button)
- if button == 'start' or button == 'guide' then self.paused = not self.paused end
- self.hud:gamepadpressed(gamepad, button)
- self.players:gamepadpressed(gamepad, button)
- end
- function Game:gamepadaxis(...)
- self.players:gamepadaxis(...)
- end
- function Game:distribute()
- local function tableRandom(t)
- return t[love.math.random(1, #t)]
- end
- -- So the hud can draw them
- self.rewards = {runes = {}, medals = {}, minions = {}, hats = {}, highscore = false}
- local time = math.floor(self.timer * ls.tickrate)
- if self.mode == 'campaign' then
- local bronze = time >= config.medals.bronze
- local silver = time >= config.medals.silver
- local gold = time >= config.medals.gold
- -- Distribute medals
- if bronze and not ctx.user.campaign.medals[self.biome].bronze then
- table.insert(self.rewards.medals, 'bronze')
- self.user.campaign.medals[self.biome].bronze = true
- end
- if silver and not ctx.user.campaign.medals[self.biome].silver then
- local nextMinions = {forest = 'xuju', cavern = 'kuju', tundra = 'thuju'}
- if nextMinions[self.biome] then
- table.insert(self.rewards.minions, nextMinions[self.biome])
- end
- table.insert(self.rewards.medals, 'silver')
- self.user.campaign.medals[self.biome].silver = true
- end
- if gold and not ctx.user.campaign.medals[self.biome].gold then
- table.insert(self.rewards.medals, 'gold')
- self.user.campaign.medals[self.biome].gold = true
- local hatPool = table.copy(config.hats)
- for i = 1, #config.hats do
- local index = love.math.random(1, #hatPool)
- if table.has(self.user.hats, hatPool[index]) then
- table.remove(hatPool, i)
- else
- local hat = hatPool[index]
- table.insert(self.rewards.hats, hat)
- table.insert(self.user.hats, hat)
- self.user.campaign.hatHistory[self.biome] = hat
- break
- end
- if #hatPool == 0 then break end
- end
- end
- -- Distribute runes
- local runeCount = 0
- if bronze then runeCount = runeCount + 1 end
- if silver and love.math.random() < .3 then runeCount = runeCount + 1 end
- if gold and love.math.random() < .2 then runeCount = runeCount + 1 end
- for i = 1, runeCount do
- -- Basics
- local rune = {}
- local maxLevel = config.runes.maxLevels[self.biome]
- local mu = 0
- if gold then mu = maxLevel
- elseif silver then mu = maxLevel * .8
- elseif bronze then mu = maxLevel * .5 end
- local runeLevel = math.clamp(love.math.randomNormal(10, mu), 1, 100)
- -- Generate prefix
- local prefixes = config.runes.prefixes
- local prefixLevel = math.clamp(runeLevel + love.math.random(-4, 4), 0, 100)
- local prefix = prefixes[1 + lume.round((prefixLevel / 100) * (#prefixes - 1))]
- rune.name = prefix .. ' Rune'
- -- Generate bonuses
- local r = love.math.random()
- if r < .33 then
- -- Attributes
- rune.attributes = {}
- local attribute = tableRandom(config.attributes.list)
- local attributeLevels = math.max(lume.round((runeLevel / 100) * 8), 1)
- local attributeLevelsDistributed = 0
- local attributesDistributed = {attribute}
- while attributeLevelsDistributed < attributeLevels do
- local amount = love.math.random(1, attributeLevels - attributeLevelsDistributed)
- rune.attributes[attribute] = (rune.attributes[attribute] or 0) + amount
- attributeLevelsDistributed = attributeLevelsDistributed + amount
- if #attributesDistributed < 2 and love.math.random() < .4 then
- attribute = tableRandom(config.attributes.list)
- if not table.has(attributesDistributed, attribute) then
- table.insert(attributesDistributed, attribute)
- end
- end
- end
- table.sort(attributesDistributed)
- rune.name = rune.name .. ' of ' .. tableRandom(config.runes.suffixes.attributes[table.concat(attributesDistributed)])
- elseif r < .67 then
- -- Stat bonuses
- local stats = config.runes.stats
- local stat = stats[love.math.random(1, #stats)]
- local min, max = unpack(config.runes.statRanges[stat])
- local mu, sigma = lume.lerp(min, max, runeLevel / 100), (max - min) / 10
- local amount = math.clamp(love.math.randomNormal(sigma, mu), min, max)
- rune.stats = {[stat] = amount}
- rune.name = rune.name .. ' of ' .. tableRandom(config.runes.suffixes.stats[stat])
- else
- -- Ability bonuses
- local unit = tableRandom(table.keys(config.runes.abilities))
- if self.mode == 'campaign' and love.math.random() < .5 then unit = config.biomes[ctx.biome].minion end
- local ability = tableRandom(table.keys(config.runes.abilities[unit]))
- local stat = tableRandom(table.keys(config.runes.abilities[unit][ability]))
- local min, max = unpack(config.runes.abilities[unit][ability][stat])
- local mu, sigma = lume.lerp(min, max, runeLevel / 100), (max - min) / 10
- local amount = math.clamp(love.math.randomNormal(sigma, mu), min, max)
- rune.unit = unit
- rune.abilities = {[ability] = {[stat] = amount}}
- rune.name = rune.name .. ' of ' .. tableRandom(config.runes.suffixes.abilities[ability])
- end
- -- Generate appearance
- rune.color = tableRandom(table.keys(config.runes.colors))
- rune.image = love.math.random(1, config.runes.imageCount)
- rune.background = runeLevel < 30 and 'broken' or 'normal'
- -- Add to account
- if table.count(ctx.user.runes.stash) < 32 then
- for i = 1, 32 do
- if not self.user.runes.stash[i] then
- self.user.runes.stash[i] = rune
- table.insert(self.rewards.runes, rune)
- break
- end
- end
- end
- end
- end
- -- Calculate highscores
- if self.mode == 'survival' and time > self.user.survival.bestTime then
- self.user.survival.bestTime = time
- self.rewards.highscore = true
- end
- saveUser(self.user)
- end
|