units.lua 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. Units = extend(Manager)
  2. Units.manages = 'unit'
  3. function Units:init()
  4. Manager.init(self)
  5. self.config = ctx.mode == 'campaign' and config.enemies[ctx.biome] or config.enemies.survival
  6. self.level = 0
  7. self.nextEnemy = 5
  8. self.enemyCount = 0
  9. self.nextSpike = 10 * 60 / ls.tickrate
  10. table.merge(self.config, self)
  11. end
  12. function Units:createEnemy()
  13. local conf = config.biomes[ctx.biome]
  14. if self.enemyCount < 2 + math.floor(self.level * self.maxEnemiesCoefficient) then
  15. local choices = {}
  16. table.each(self.types, function(time, code)
  17. if ctx.timer * ls.tickrate >= time then table.insert(choices, code) end
  18. end)
  19. local enemyType = choices[love.math.random(1, #choices)]
  20. local x = love.math.random() < .5 and Unit.width / 2 or ctx.map.width - Unit.width / 2
  21. local eliteChance = config.elites.baseModifier + (config.elites.levelModifier * self.level)
  22. local eliteCount = table.count(self:filter(function(u) return u.elite end))
  23. local isElite = love.math.random() < eliteChance
  24. isElite = isElite and self.level > self.eliteLevelThreshold
  25. isElite = isElite and eliteCount < self.maxElites
  26. local unit = self:add(enemyType, {x = x, elite = isElite})
  27. if isElite then
  28. local buffs = table.keys(config.elites.buffs)
  29. for i = 1, math.min(self.maxEliteBuffCount, math.max(1, math.floor(ctx.timer * ls.tickrate / 60 / 5))) do
  30. local index = love.math.random(1, #buffs)
  31. local buff = buffs[index]
  32. table.remove(buffs, index)
  33. unit.buffs:add(buff, config.elites.buffs[buff])
  34. end
  35. end
  36. self.minEnemyRate = math.max(self.minEnemyRate - self.minEnemyRateDecay * math.clamp((0.2 + self.minEnemyRate) / 5, .2, 1), 0.2)
  37. self.maxEnemyRate = math.max(self.maxEnemyRate - self.maxEnemyRateDecay * math.clamp((0.2 + self.maxEnemyRate) / 5, .4, 1), 0.2)
  38. if self.maxEnemyRate < self.minEnemyRate then self.maxEnemyRate = self.minEnemyRate end
  39. else
  40. return .5
  41. end
  42. return math.max(love.math.randomNormal(self.maxEnemyRate - self.minEnemyRate, (self.minEnemyRate + self.maxEnemyRate) / 2), ls.tickrate)
  43. end
  44. function Units:update()
  45. if not ctx.tutorial.active then
  46. self.enemyCount = table.count(self:filter(function(u) return u.team == 0 end))
  47. self.nextEnemy = timer.rot(self.nextEnemy, f.cur(self.createEnemy, self))
  48. self.level = self.level + (ls.tickrate / 15) * self.levelScale
  49. if tick > self.nextSpike then
  50. self.levelScale = self.levelScale * 1.8
  51. self.nextSpike = self.nextSpike + (5 * 60 / ls.tickrate)
  52. end
  53. end
  54. return Manager.update(self)
  55. end
  56. function Units:add(class, vars)
  57. local unit = Unit()
  58. table.merge(vars, unit, true)
  59. unit.class = data.unit[class]
  60. f.exe(unit.activate, unit)
  61. self.objects[unit] = unit
  62. return unit
  63. end
  64. function Units:remove(unit)
  65. f.exe(unit.deactivate, unit)
  66. self.objects[unit] = nil
  67. unit = nil
  68. end
  69. function Units:clear()
  70. table.each(self.objects, function(unit)
  71. self:remove(unit)
  72. end)
  73. self:init()
  74. end