diff --git a/arena.lua b/arena.lua index 154cf71..8c89e5a 100644 --- a/arena.lua +++ b/arena.lua @@ -777,6 +777,7 @@ end function Arena:die() if not self.died_text and not self.won then self.died = true + system.save_run(0, gold, {}, passives, run_passive_pool_by_tiers) self.t:tween(2, self, {main_slow_amount = 0}, math.linear, function() self.main_slow_amount = 0 end) self.died_text = Text2{group = self.ui, x = gw/2, y = gh/2 - 32, lines = { {text = '[wavy_mid, cbyc]you died...', font = fat_font, alignment = 'center', height_multiplier = 1.25}, diff --git a/buy_screen.lua b/buy_screen.lua index 4280276..7aaee4a 100644 --- a/buy_screen.lua +++ b/buy_screen.lua @@ -20,6 +20,7 @@ function BuyScreen:on_exit() self.sets_text = nil self.items_text = nil self.ng_text = nil + self.level_text = nil self.characters = nil self.sets = nil self.cards = nil @@ -31,6 +32,8 @@ function BuyScreen:on_exit() self.springs = nil self.flashes = nil self.hfx = nil + self.tutorial_button = nil + self.restart_button = nil end @@ -54,7 +57,10 @@ function BuyScreen:on_enter(from, level, units, passives) self.ui = Group() self.tutorial = Group() - self:set_cards() + self.locked = locked_state and locked_state.locked + LockButton{group = self.main, x = 210, y = 18, parent = self} + + self:set_cards(nil, nil, true) self:set_party_and_sets() self:set_items() @@ -63,10 +69,11 @@ function BuyScreen:on_enter(from, level, units, passives) self.sets_text = Text({{text = '[wavy_mid, fg]classes', font = pixul_font, alignment = 'center'}}, global_text_tags) self.items_text = Text({{text = '[wavy_mid, fg]items', font = pixul_font, alignment = 'center'}}, global_text_tags) self.ng_text = Text({{text = '[fg]NG+' .. new_game_plus, font = pixul_font, alignment = 'center'}}, global_text_tags) + self.level_text = Text({{text = '[fg]Lv.' .. tostring(level == 0 and 1 or self.level+1) .. tostring((self.level+1) % 3 == 0 and ' (elite)' or ''), font = pixul_font, alignment = 'center'}}, global_text_tags) if not self.first_screen then RerollButton{group = self.main, x = 150, y = 18, parent = self} end GoButton{group = self.main, x = gw - 90, y = gh - 20, parent = self} - self.tutorial_button = Button{group = self.main, x = gw/2 + 142, y = 18, button_text = '?', fg_color = 'yellowm5', bg_color = 'yellow', action = function() + self.tutorial_button = Button{group = self.main, x = gw/2 + 136, y = 18, button_text = '?', fg_color = 'bg10', bg_color = 'bg', action = function() self.in_tutorial = true self.title_text = Text2{group = self.tutorial, x = gw/2, y = 35, lines = {{text = '[fg]WELCOME TO SNKRX!', font = fat_font, alignment = 'center'}}} self.tutorial_text = Text2{group = self.tutorial, x = 228, y = 160, lines = { @@ -103,6 +110,30 @@ function BuyScreen:on_enter(from, level, units, passives) end} end} + self.restart_button = Button{group = self.ui, x = gw/2 + 154, y = 18, force_update = true, button_text = 'R', fg_color = 'bg10', bg_color = 'bg', action = function(b) + self.transitioning = true + ui_transition2:play{pitch = random:float(0.95, 1.05), volume = 0.5} + ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5} + ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5} + TransitionEffect{group = main.transitions, x = gw/2, y = gh/2, color = fg[0], transition_action = function() + slow_amount = 1 + gold = 2 + passives = {} + main_song_instance:stop() + run_passive_pool_by_tiers = { + [1] = {'wall_echo', 'wall_rider', 'centipede', 'temporal_chains', 'amplify', 'amplify_x', 'ballista', 'ballista_x', 'blunt_arrow', 'berserking', 'unwavering_stance', 'assassination', 'unleash', 'blessing', + 'hex_master', 'force_push', 'spawning_pool'}, + [2] = {'ouroboros_technique_r', 'ouroboros_technique_l', 'intimidation', 'vulnerability', 'resonance', 'point_blank', 'longshot', 'explosive_arrow', 'chronomancy', 'awakening', 'ultimatum', 'echo_barrage', + 'reinforce', 'payback', 'whispers_of_doom', 'heavy_impact', 'immolation', 'call_of_the_void'}, + [3] = {'divine_machine_arrow', 'divine_punishment', 'flying_daggers', 'crucio', 'hive', 'void_rift'}, + } + max_units = 7 + new_game_plus + main:add(BuyScreen'buy_screen') + system.save_run(0, gold, {}, passives, run_passive_pool_by_tiers) + main:go_to('buy_screen', 0, {}, passives) + end, text = Text({{text = '[wavy, bg]restarting...', font = pixul_font, alignment = 'center'}}, global_text_tags)} + end} + trigger:tween(1, main_song_instance, {volume = 0.2}, math.linear) if self.level == 1 then @@ -130,6 +161,7 @@ function BuyScreen:update(dt) if self.party_text then self.party_text:update(dt) end if self.items_text then self.items_text:update(dt) end if self.ng_text then self.ng_text:update(dt) end + if self.level_text then self.level_text:update(dt) end else self.tutorial:update(dt*slow_amount) end @@ -162,6 +194,7 @@ function BuyScreen:draw() self.main:draw() self.effects:draw() if self.items_text then self.items_text:draw(32, 145) end + if self.level_text then self.level_text:draw(260, gh - 20) end self.ui:draw() if self.unit_grabbed then @@ -179,9 +212,7 @@ function BuyScreen:draw() if self.shop_text then self.shop_text:draw(64, 20) end if self.sets_text then self.sets_text:draw(328, 20) end if self.party_text then self.party_text:draw(440, 20) end - if new_game_plus > 0 then - self.ng_text:draw(240, 20) - end + if new_game_plus > 0 then self.ng_text:draw(240, 20) end if self.in_tutorial then graphics.rectangle(gw/2, gh/2, 2*gw, 2*gh, nil, nil, modal_transparent_2) @@ -264,7 +295,7 @@ function BuyScreen:gain_gold(amount) end -function BuyScreen:set_cards(level, dont_spawn_effect) +function BuyScreen:set_cards(level, dont_spawn_effect, first_call) if self.cards then for i = 1, 3 do if self.cards[i] then self.cards[i]:die(dont_spawn_effect) end end end self.cards = {} local all_units = {} @@ -277,9 +308,15 @@ function BuyScreen:set_cards(level, dont_spawn_effect) unit_3 = random:table(tier_to_characters[random:weighted_pick(unpack(level_to_tier_weights[level or self.level]))]) all_units = {unit_1, unit_2, unit_3} until not table.all(all_units, function(v) return table.any(non_attacking_characters, function(u) return v == u end) end) - self.cards[1] = ShopCard{group = self.main, x = 60, y = 75, w = 80, h = 90, unit = unit_1, parent = self, i = 1} - self.cards[2] = ShopCard{group = self.main, x = 140, y = 75, w = 80, h = 90, unit = unit_2, parent = self, i = 2} - self.cards[3] = ShopCard{group = self.main, x = 220, y = 75, w = 80, h = 90, unit = unit_3, parent = self, i = 3} + if first_call and self.locked then + if locked_state.cards[1] then self.cards[1] = ShopCard{group = self.main, x = 60, y = 75, w = 80, h = 90, unit = locked_state.cards[1], parent = self, i = 1} end + if locked_state.cards[2] then self.cards[2] = ShopCard{group = self.main, x = 140, y = 75, w = 80, h = 90, unit = locked_state.cards[2], parent = self, i = 2} end + if locked_state.cards[3] then self.cards[3] = ShopCard{group = self.main, x = 220, y = 75, w = 80, h = 90, unit = locked_state.cards[3], parent = self, i = 3} end + else + self.cards[1] = ShopCard{group = self.main, x = 60, y = 75, w = 80, h = 90, unit = unit_1, parent = self, i = 1} + self.cards[2] = ShopCard{group = self.main, x = 140, y = 75, w = 80, h = 90, unit = unit_2, parent = self, i = 2} + self.cards[3] = ShopCard{group = self.main, x = 220, y = 75, w = 80, h = 90, unit = unit_3, parent = self, i = 3} + end end @@ -467,7 +504,7 @@ function RestartButton:update(dt) max_units = 7 + new_game_plus system.save_state() main:add(BuyScreen'buy_screen') - system.save_run(0, gold, {}, passives, run_passive_pool_by_tiers) + system.save_run(0, gold, {}, passives, run_passive_pool_by_tiers, locked_state) main:go_to('buy_screen', 0, {}, passives) end, text = Text({{text = '[wavy, bg]restarting...', font = pixul_font, alignment = 'center'}}, global_text_tags)} end @@ -546,6 +583,13 @@ function Button:on_mouse_exit() end +function Button:set_text(text) + self.button_text = text + self.text:set_text{{text = '[' .. self.fg_color .. ']' .. self.button_text, font = pixul_font, alignment = 'center'}} + self.spring:pull(0.2, 200, 10) +end + + GoButton = Object:extend() @@ -574,6 +618,7 @@ function GoButton:update(dt) self.t:after(2, function() self.info_text:deactivate(); self.info_text.dead = true; self.info_text = nil end, 'info_text') else + if self.parent.locked then locked_state = {locked = true, cards = {self.parent.cards[1] and self.parent.cards[1].unit, self.parent.cards[2] and self.parent.cards[2].unit, self.parent.cards[3] and self.parent.cards[3].unit}} end ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5} self.spring:pull(0.2, 200, 10) self.selected = true @@ -612,6 +657,58 @@ function GoButton:on_mouse_exit() end +LockButton = Object:extend() +LockButton:implement(GameObject) +function LockButton:init(args) + self:init_game_object(args) + self.shape = Rectangle(self.x, self.y, 32, 16) + self.interact_with_mouse = true + if self.parent.locked then self.shape.w = 44 + else self.shape.w = 32 end + if self.parent.locked then self.text = Text({{text = '[fgm5]' .. tostring(self.parent.locked and 'unlock' or 'lock'), font = pixul_font, alignment = 'center'}}, global_text_tags) + else self.text = Text({{text = '[bg10]' .. tostring(self.parent.locked and 'unlock' or 'lock'), font = pixul_font, alignment = 'center'}}, global_text_tags) end +end + + +function LockButton:update(dt) + self:update_game_object(dt) + + if self.selected and input.m1.pressed then + self.parent.locked = not self.parent.locked + if not self.parent.locked then locked_state = nil end + ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5} + self.selected = true + self.spring:pull(0.2, 200, 10) + self.text:set_text{{text = '[fgm5]' .. tostring(self.parent.locked and 'unlock' or 'lock'), font = pixul_font, alignment = 'center'}} + if self.parent.locked then self.shape.w = 44 + else self.shape.w = 32 end + end +end + + +function LockButton:draw() + graphics.push(self.x, self.y, 0, self.spring.x, self.spring.y) + graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 4, 4, (self.selected or self.parent.locked) and fg[0] or bg[1]) + self.text:draw(self.x, self.y + 1) + graphics.pop() +end + + +function LockButton:on_mouse_enter() + ui_hover1:play{pitch = random:float(1.3, 1.5), volume = 0.5} + pop2:play{pitch = random:float(0.95, 1.05), volume = 0.5} + self.selected = true + self.text:set_text{{text = '[fgm5]' .. tostring(self.parent.locked and 'unlock' or 'lock'), font = pixul_font, alignment = 'center'}} + self.spring:pull(0.2, 200, 10) +end + + +function LockButton:on_mouse_exit() + if not self.parent.locked then self.text:set_text{{text = '[bg10]' .. tostring(self.parent.locked and 'unlock' or 'lock'), font = pixul_font, alignment = 'center'}} end + self.selected = false +end + + RerollButton = Object:extend() RerollButton:implement(GameObject) diff --git a/enemies.lua b/enemies.lua index 872f0ab..602792c 100644 --- a/enemies.lua +++ b/enemies.lua @@ -265,7 +265,6 @@ function Seeker:update(dt) self:calculate_stats() self.stun_dmg_m = (self.barbarian_stunned and 2 or 1) - self.bane_dmg_m = (self.baned and 1.5 or 1) if self.shooter then self.t:set_every_multiplier('shooter', (1 - self.level*0.02)) @@ -392,7 +391,7 @@ function Seeker:hit(damage, projectile) if self.push_invulnerable then return end self:show_hp() - local actual_damage = math.max(self:calculate_damage(damage)*(self.stun_dmg_m or 1)*(self.bane_dmg_m or 1), 0) + local actual_damage = math.max(self:calculate_damage(damage)*(self.stun_dmg_m or 1), 0) if self.vulnerable then actual_damage = actual_damage*1.2 end self.hp = self.hp - actual_damage if self.hp > self.max_hp then self.hp = self.max_hp end @@ -473,6 +472,27 @@ function Seeker:hit(damage, projectile) end end) end + + if self.jester_cursed then + trigger:after(0.01, function() + _G[random:table{'scout1', 'scout2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.35} + HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6} + local r = random:float(0, 2*math.pi) + for i = 1, 3 do + local t = {group = main.current.main, x = self.x + 8*math.cos(r), y = self.y + 8*math.sin(r), v = 250, r = r, color = red[0], dmg = self.jester_ref.dmg, + pierce = self.jester_lvl3 and 2 or 0, homing = self.jester_lvl3, character = self.jester_ref.character, parent = self.jester_ref} + Projectile(table.merge(t, mods or {})) + r = r + math.pi/1.5 + end + end) + end + + if self.bane_cursed then + trigger:after(0.01, function() + DotArea{group = main.current.effects, x = self.x, y = self.y, rs = (self.bane_ref.level == 3 and 2 or 1)*self.bane_ref.area_size_m*18, color = purple[0], + dmg = self.bane_ref.area_dmg_m*self.bane_ref.dmg*(self.bane_ref.dot_dmg_m or 1), void_rift = true, duration = 1} + end) + end end end @@ -528,11 +548,16 @@ function Seeker:curse(curse, duration, arg1, arg2, arg3) self.launcher = arg2 self:push(random:float(50, 75)*self.launcher.knockback_m, random:table{0, math.pi, math.pi/2, -math.pi/2}) end, 'launcher_curse') - elseif curse == 'bard' then - self.bard_cursed = true + elseif curse == 'jester' then + self.jester_cursed = true + self.jester_lvl3 = arg1 + self.jester_ref = arg2 + self.t:after(duration*curse_m, function() self.jester_cursed = false end, 'jester_curse') elseif curse == 'bane' then - self.baned = true - self.t:after(duration*curse_m, function() self.baned = false end, 'bane_curse') + self.bane_cursed = true + self.bane_lvl3 = arg1 + self.bane_ref = arg2 + self.t:after(duration*curse_m, function() self.bane_cursed = false end, 'bane_curse') elseif curse == 'infestor' then self.infested = arg1 self.infested_dmg = arg2 @@ -703,11 +728,16 @@ function EnemyCritter:curse(curse, duration, arg1, arg2, arg3) self.launcher = arg2 self:push(random:float(50, 75)*self.launcher.knockback_m, random:table{0, math.pi, math.pi/2, -math.pi/2}) end, 'launcher_curse') - elseif curse == 'bard' then - self.bard_cursed = true + elseif curse == 'jester' then + self.jester_cursed = true + self.jester_lvl3 = arg1 + self.jester_ref = arg2 + self.t:after(duration*curse_m, function() self.jester_cursed = false end, 'jester_curse') elseif curse == 'bane' then - self.baned = true - self.t:after(duration*curse_m, function() self.baned = false end, 'bane_curse') + self.bane_cursed = true + self.bane_lvl3 = arg1 + self.bane_ref = arg2 + self.t:after(duration*curse_m, function() self.bane_cursed = false end, 'bane_curse') elseif curse == 'infestor' then self.infested = arg1 self.infested_dmg = arg2 diff --git a/engine/system.lua b/engine/system.lua index 9f59e64..93e5718 100644 --- a/engine/system.lua +++ b/engine/system.lua @@ -137,8 +137,8 @@ function system.load_state() end -function system.save_run(level, gold, units, passives, run_passive_pool_by_tiers) - local run = {level = level, gold = gold, units = units, passives = passives, run_passive_pool_by_tiers = run_passive_pool_by_tiers} +function system.save_run(level, gold, units, passives, run_passive_pool_by_tiers, locked_state) + local run = {level = level, gold = gold, units = units, passives = passives, run_passive_pool_by_tiers = run_passive_pool_by_tiers, locked_state = locked_state} local str = "return " .. table.tostring(run) love.filesystem.write("run.txt", str) end diff --git a/main.lua b/main.lua index 614013c..8605127 100644 --- a/main.lua +++ b/main.lua @@ -232,7 +232,7 @@ function init() ['corruptor'] = 'Corruptor', ['beastmaster'] = 'Beastmaster', ['launcher'] = 'Launcher', - ['bard'] = 'Bard', + ['jester'] = 'Jester', ['assassin'] = 'Assassin', ['host'] = 'Host', ['carver'] = 'Carver', @@ -276,7 +276,7 @@ function init() ['corruptor'] = orange[0], ['beastmaster'] = red[0], ['launcher'] = yellow[0], - ['bard'] = red[0], + ['jester'] = red[0], ['assassin'] = purple[0], ['host'] = orange[0], ['carver'] = green[0], @@ -320,7 +320,7 @@ function init() ['corruptor'] = 'orange', ['beastmaster'] = 'red', ['launcher'] = 'yellow', - ['bard'] = 'red', + ['jester'] = 'red', ['assassin'] = 'purple', ['host'] = 'orange', ['carver'] = 'green', @@ -364,7 +364,7 @@ function init() ['corruptor'] = {'ranger', 'swarmer'}, ['beastmaster'] = {'rogue', 'swarmer'}, ['launcher'] = {'curser', 'forcer'}, - ['bard'] = {'curser', 'rogue'}, + ['jester'] = {'curser', 'rogue'}, ['assassin'] = {'rogue', 'voider'}, ['host'] = {'swarmer'}, ['carver'] = {'conjurer', 'healer'}, @@ -408,7 +408,7 @@ function init() ['corruptor'] = '[green]Ranger, [orange]Swarmer', ['beastmaster'] = '[red]Rogue, [orange]Swarmer', ['launcher'] = '[yellow]Forcer, [purple]Curser', - ['bard'] = '[purple]Curser, [red]Rogue', + ['jester'] = '[purple]Curser, [red]Rogue', ['assassin'] = '[red]Rogue, [purple]Voider', ['host'] = '[orange]Swarmer', ['carver'] = '[orange]Conjurer, [green]Healer', @@ -467,19 +467,19 @@ function init() ['pyromancer'] = function(lvl) return '[fg]nearby enemies take [yellow]' .. get_character_stat('pyromancer', lvl, 'dmg') .. '[fg] damage per second' end, ['corruptor'] = function(lvl) return '[fg]spawn [yellow]3[fg] small critters if the corruptor kills an enemy' end, ['beastmaster'] = function(lvl) return '[fg]spawn [yellow]2[fg] small critters if the beastmaster crits' end, - ['launcher'] = function(lvl) return '[fg]nearby enemies are pushed after [yellow]4[fg] seconds, taking [yellow]' .. 2*get_character_stat('launcher', lvl, 'dmg') .. '[fg] damage on wall hit' end, - ['bard'] = function(lvl) return "[fg]throws a knife that deals [yellow]" .. get_character_stat('bard', lvl, 'dmg') .. "[fg] damage and inflicts enemies hit with the bard's curse" end, + ['launcher'] = function(lvl) return '[fg]all nearby enemies are pushed after [yellow]4[fg] seconds, taking [yellow]' .. 2*get_character_stat('launcher', lvl, 'dmg') .. '[fg] damage on wall hit' end, + ['jester'] = function(lvl) return "[fg]curses [yellow]5[fg] nearby enemies for [yellow]6[fg] seconds, they will explode into [yellow]3[fg] knives on death" end, ['assassin'] = function(lvl) return '[fg]throws a piercing knife that deals [yellow]' .. get_character_stat('assassin', lvl, 'dmg') .. '[fg] damage + [yellow]' .. get_character_stat('assassin', lvl, 'dmg')/2 .. '[fg] damage per second for [yellow]3[fg] seconds' end, ['host'] = function(lvl) return '[fg]periodically spawn [yellow]1[fg] small critter' end, ['carver'] = function(lvl) return '[fg]carves a statue that periodically heals [yellow]1[fg] unit for [yellow]20%[fg] max HP if in range' end, - ['bane'] = function(lvl) return '[fg]creates a large area that curses enemies to take [yellow]+50%[fg] damage' end, + ['bane'] = function(lvl) return '[fg]curser [yellow]5[fg] nearby enemies for [yellow]6[fg] seconds, they will create small void rifts on death' end, ['psykino'] = function(lvl) return '[fg]pulls enemies together for [yellow]2[fg] seconds' end, ['barrager'] = function(lvl) return '[fg]shoots a barrage of [yellow]3[fg] arrows, each dealing [yellow]' .. get_character_stat('barrager', lvl, 'dmg') .. '[fg] damage and pushing enemies' end, ['highlander'] = function(lvl) return '[fg]deals [yellow]' .. 5*get_character_stat('highlander', lvl, 'dmg') .. '[fg] AoE damage' end, ['fairy'] = function(lvl) return '[fg]periodically heals [yellow]1[fg] unit at random and grants it [yellow]+100%[fg] attack speed for [yellow]6[fg] seconds' end, ['priest'] = function(lvl) return '[fg]heals all allies for [yellow]20%[fg] their max HP' end, - ['infestor'] = function(lvl) return '[fg]curses nearby enemies for [yellow]6[fg] seconds, they will release [yellow]2[fg] critters on death' end, + ['infestor'] = function(lvl) return '[fg]curses all nearby enemies for [yellow]6[fg] seconds, they will release [yellow]2[fg] critters on death' end, ['flagellant'] = function(lvl) return '[fg]deals [yellow]' .. 2*get_character_stat('flagellant', lvl, 'dmg') .. '[fg] damage to self and grants [yellow]+4%[fg] damage to all allies per cast' end, } @@ -503,7 +503,7 @@ function init() ['chronomancer'] = '[blue]Quicken', ['spellblade'] = '[blue]Spiralism', ['psykeeper'] = '[fg]Crucio', - ['engineer'] = '[orange]Upgrade', + ['engineer'] = '[orange]Upgrade!!!', ['plague_doctor'] = '[purple]Black Death Steam', ['barbarian'] = '[yellow]Seism', ['juggernaut'] = '[yellow]Brutal Impact', @@ -513,7 +513,7 @@ function init() ['corruptor'] = '[orange]Corruption', ['beastmaster'] = '[red]Call of the Wild', ['launcher'] = '[orange]Kineticism', - ['bard'] = "[red]The Bard's Song", + ['jester'] = "[red]Pandemonium", ['assassin'] = '[purple]Toxic Delivery', ['host'] = '[orange]Invasion', ['carver'] = '[green]World Tree', @@ -547,7 +547,7 @@ function init() ['chronomancer'] = '[light_bg]Quicken', ['spellblade'] = '[light_bg]Spiralism', ['psykeeper'] = '[light_bg]Crucio', - ['engineer'] = '[light_bg]Upgrade', + ['engineer'] = '[light_bg]Upgrade!!!', ['plague_doctor'] = '[light_bg]Black Death Steam', ['barbarian'] = '[light_bg]Seism', ['juggernaut'] = '[light_bg]Brutal Impact', @@ -557,7 +557,7 @@ function init() ['corruptor'] = '[light_bg]Corruption', ['beastmaster'] = '[light_bg]Call of the Wild', ['launcher'] = '[light_bg]Kineticism', - ['bard'] = "[light_bg]The Bard's Song", + ['jester'] = "[light_bg]Pandemonium", ['assassin'] = '[light_bg]Toxic Delivery', ['host'] = '[light_bg]Invasion', ['carver'] = '[light_bg]World Tree', @@ -572,7 +572,7 @@ function init() } character_effect_descriptions = { - ['vagrant'] = function() return '[yellow]+10%[fg] damage and [yellow]+5%[fg] attack speed per active set' end, + ['vagrant'] = function() return '[yellow]+10%[fg] damage and [yellow]+10%[fg] attack speed per active set' end, ['swordsman'] = function() return "[fg]the swordsman's damage is [yellow]doubled" end, ['wizard'] = function() return '[fg]the projectile chains [yellow]3[fg] times' end, ['archer'] = function() return '[fg]the arrow ricochets off walls [yellow]3[fg] times' end, @@ -591,7 +591,7 @@ function init() ['chronomancer'] = function() return '[fg]enemies take damave over time [yellow]50%[fg] faster' end, ['spellblade'] = function() return '[fg]faster projectile speed and tighter turns' end, ['psykeeper'] = function() return '[fg]also redistributes damage taken as damage to all enemies at [yellow]double[fg] value' end, - ['engineer'] = function() return '[fg]every 3rd sentry dropped upgrade all sentries with [yellow]+100%[fg] damage and attack speed' end, + ['engineer'] = function() return '[fg]drops [yellow]2[fg] additional turrets and grants all turrets [yellow]+50%[fg] damage and attack speed' end, ['plague_doctor'] = function() return '[fg]nearby enemies take an additional [yellow]' .. get_character_stat('plague_doctor', 3, 'dmg') .. '[fg] damage per second' end, ['barbarian'] = function() return '[fg]stunned enemies also take [yellow]100%[fg] increased damage' end, ['juggernaut'] = function() return '[fg]enemies pushed by the juggernaut take [yellow]' .. 4*get_character_stat('juggernaut', 3, 'dmg') .. '[fg] damage if they hit a wall' end, @@ -601,11 +601,11 @@ function init() ['corruptor'] = function() return '[fg]spawn [yellow]3[fg] small critters if the corruptor hits an enemy' end, ['beastmaster'] = function() return '[fg]spawn [yellow]2[fg] small critters if the beastmaster gets hit' end, ['launcher'] = function() return '[fg]enemies launched take [yellow]300%[fg] more damage when they hit walls' end, - ['bard'] = function() return '[fg]every 8th attack consume the curse to deal [yellow]' .. 4*get_character_stat('bard', 3, 'dmg') .. '[fg] damage to affected enemies' end, + ['jester'] = function() return '[fg]all knives seek enemies and pierce [yellow]2[fg] times' end, ['assassin'] = function() return '[fg]poison inflicted from crits deals [yellow]8x[fg] damage' end, ['host'] = function() return '[fg][yellow]+100%[fg] critter spawn rate and spawn [yellow]2[fg] critters instead' end, ['carver'] = function() return '[fg]carves a tree that heals [yellow]twice[fg] as fast, in a bigger area, and heals [yellow]2[fg] units instead' end, - ['bane'] = function() return '[fg]the area also deals [yellow]' .. get_character_stat('bane', 3, 'dmg') .. '[fg] damage per second and slows enemies by [yellow]50%[fg]' end, + ['bane'] = function() return "[yellow]100%[fg] increased area for bane's void rifts" end, ['psykino'] = function() return '[fg]enemies take [yellow]' .. 4*get_character_stat('psykino', 3, 'dmg') .. '[fg] damage and are pushed away when the area expires' end, ['barrager'] = function() return '[fg]every 3rd attack the barrage shoots [yellow]15[fg] projectiles and they push harder' end, ['highlander'] = function() return '[fg]quickly repeats the attack [yellow]3[fg] times' end, @@ -616,7 +616,7 @@ function init() } character_effect_descriptions_gray = { - ['vagrant'] = function() return '[light_bg]+10% damage and +5% attack speed per active set' end, + ['vagrant'] = function() return '[light_bg]+10% damage and +10% attack speed per active set' end, ['swordsman'] = function() return "[light_bg]the swordsman's damage is doubled" end, ['wizard'] = function() return '[light_bg]the projectile chains 3 times' end, ['archer'] = function() return '[light_bg]the arrow ricochets off walls 3 times' end, @@ -635,7 +635,7 @@ function init() ['chronomancer'] = function() return '[light_bg]enemies take damave over time 50% faster' end, ['spellblade'] = function() return '[light_bg]faster projectile speed and tighter turns' end, ['psykeeper'] = function() return '[light_bg]also redistributes damage taken as damage to all enemies at double value' end, - ['engineer'] = function() return '[light_bg]every 3rd sentry dropped upgrade all sentries with +100% damage and attack speed' end, + ['engineer'] = function() return '[light_bg]drops 3 additional turrets and grants all turrets +100% damage and attack speed' end, ['plague_doctor'] = function() return '[light_bg]nearby enemies take an additional ' .. get_character_stat('plague_doctor', 3, 'dmg') .. ' damage per second' end, ['barbarian'] = function() return '[light_bg]stunned enemies also take 100% increased damage' end, ['juggernaut'] = function() return '[light_bg]enemies pushed by the juggernaut take ' .. 4*get_character_stat('juggernaut', 3, 'dmg') .. ' damage if they hit a wall' end, @@ -645,11 +645,11 @@ function init() ['corruptor'] = function() return '[light_bg]spawn 3 small critters if the corruptor hits an enemy' end, ['beastmaster'] = function() return '[light_bg]spawn 2 small critters if the beastmaster gets hit' end, ['launcher'] = function() return '[light_bg]enemies launched take 300% more damage when they hit walls' end, - ['bard'] = function() return '[light_bg]every 8th attack consume the curse to deal ' .. 4*get_character_stat('bard', 3, 'dmg') .. ' damage to affected enemies' end, + ['jester'] = function() return '[light_bg]curses 6 enemies and all knives seek enemies and pierce 2 times' end, ['assassin'] = function() return '[light_bg]poison inflicted from crits deals 8x damage' end, ['host'] = function() return '[light_bg]+100% critter spawn rate and spawn 2 critters instead' end, ['carver'] = function() return '[light_bg]carves a tree that heals twice as fast, in a bigger area, and heals 2 units instead' end, - ['bane'] = function() return '[light_bg]the area also deals ' .. get_character_stat('bane', 3, 'dmg') .. ' damage per second and slows enemies by 50%' end, + ['bane'] = function() return "[light_bg]100% increased area for bane's void rifts" end, ['psykino'] = function() return '[light_bg]enemies take ' .. 4*get_character_stat('psykino', 3, 'dmg') .. ' damage and are pushed away when the area expires' end, ['barrager'] = function() return '[light_bg]every 3rd attack the barrage shoots 15 projectiles and they push harder' end, ['highlander'] = function() return '[light_bg]quickly repeats the attack 3 times' end, @@ -689,7 +689,7 @@ function init() ['corruptor'] = function(lvl) return get_character_stat_string('corruptor', lvl) end, ['beastmaster'] = function(lvl) return get_character_stat_string('beastmaster', lvl) end, ['launcher'] = function(lvl) return get_character_stat_string('launcher', lvl) end, - ['bard'] = function(lvl) return get_character_stat_string('bard', lvl) end, + ['jester'] = function(lvl) return get_character_stat_string('jester', lvl) end, ['assassin'] = function(lvl) return get_character_stat_string('assassin', lvl) end, ['host'] = function(lvl) return get_character_stat_string('host', lvl) end, ['carver'] = function(lvl) return get_character_stat_string('carver', lvl) end, @@ -743,7 +743,7 @@ function init() tier_to_characters = { [1] = {'vagrant', 'swordsman', 'wizard', 'archer', 'scout', 'cleric'}, - [2] = {'saboteur', 'sage', 'squire', 'dual_gunner', 'hunter', 'chronomancer', 'barbarian', 'cryomancer', 'beastmaster', 'launcher', 'bard', 'carver'}, + [2] = {'saboteur', 'sage', 'squire', 'dual_gunner', 'hunter', 'chronomancer', 'barbarian', 'cryomancer', 'beastmaster', 'launcher', 'jester', 'carver'}, [3] = {'outlaw', 'elementor', 'stormweaver', 'spellblade', 'psykeeper', 'engineer', 'juggernaut', 'pyromancer', 'corruptor', 'assassin', 'bane', 'barrager', 'infestor', 'flagellant'}, [4] = {'priest', 'highlander', 'psykino', 'lich', 'host', 'fairy', 'blade', 'plague_doctor', 'cannoneer'}, } @@ -780,7 +780,7 @@ function init() ['corruptor'] = 3, ['beastmaster'] = 2, ['launcher'] = 2, - ['bard'] = 2, + ['jester'] = 2, ['assassin'] = 3, ['host'] = 4, ['carver'] = 2, @@ -957,7 +957,7 @@ function init() ['assassination'] = '[fg]crits from rogues deal [yellow]8x[fg] damage but normal attacks deal [yellow]half[fg] damage', ['magnify'] = '[yellow]+25%[fg] area size', ['echo_barrage'] = '[yellow]20%[fg] chance to create [yellow]3[fg] secondary AoEs on AoE hit', - ['unleash'] = '[yellow]+2%[fg] area size and damage per second', + ['unleash'] = '[yellow]+1%[fg] area size and damage per second', ['reinforce'] = '[yellow]+10%[fg] damage, defense and attack speed to all allies with at least one enchanter', ['payback'] = '[yellow]+5%[fg] damage to all allies whenever an enchanter is hit', ['blessing'] = '[yellow]+20%[fg] healing effectiveness', @@ -1167,6 +1167,7 @@ function init() } gold = run.gold or 2 passives = run.passives or {} + locked_state = run.locked_state steam.userStats.requestCurrentStats() new_game_plus = state.new_game_plus or 0 if not state.new_game_plus then state.new_game_plus = new_game_plus end @@ -1183,8 +1184,9 @@ function init() --[[ main:add(Arena'arena') - main:go_to('arena', 20, { - {character = 'vagrant', level = 3}, + main:go_to('arena', 9, { + {character = 'dual_gunner', level = 3}, + {character = 'engineer', level = 3}, {character = 'spellblade', level = 3}, {character = 'assassin', level = 3}, {character = 'scout', level = 3}, @@ -1192,9 +1194,6 @@ function init() {character = 'swordsman', level = 3}, {character = 'archer', level = 3}, }, passives) - - main:add(Media'media') - main:go_to('media') ]]-- trigger:every(2, function() diff --git a/objects.lua b/objects.lua index d13c1a6..a66801e 100644 --- a/objects.lua +++ b/objects.lua @@ -229,18 +229,34 @@ function Unit:calculate_stats(first_run) self.base_dmg = 10*math.pow(2, self.level-1) self.base_mvspd = 75 elseif self:is(Seeker) then - if self.boss then - local x = self.level - local y = {0, 0, 3, 0, 0, 6, 0, 0, 9, 0, 0, 12, 0, 0, 15, 0, 0, 18, 0, 0, 21, 0, 0, 24, 25} - self.base_hp = 100 + (new_game_plus*5) + (90 + new_game_plus*10)*y[x] - self.base_dmg = (12 + new_game_plus*2) + (2 + new_game_plus)*y[x] - self.base_mvspd = 35 + 1.5*y[x] + if new_game_plus == 0 then + if self.boss then + local x = self.level + local y = {0, 0, 3, 0, 0, 6, 0, 0, 9, 0, 0, 12, 0, 0, 18, 0, 0, 24, 0, 0, 32, 0, 0, 40, 48} + self.base_hp = 100 + (new_game_plus*5) + (90 + new_game_plus*10)*y[x] + self.base_dmg = (12 + new_game_plus*2) + (2 + new_game_plus)*y[x] + self.base_mvspd = 35 + 1.5*y[x] + else + local x = self.level + local y = {0, 1, 3, 3, 4, 6, 5, 6, 9, 7, 8, 12, 10, 11, 15, 12, 13, 18, 16, 17, 21, 17, 20, 24, 25} + self.base_hp = 28 + 18*y[x] + self.base_dmg = 5 + 3*y[x] + self.base_mvspd = 70 + 3*y[x] + end else - local x = self.level - local y = {0, 1, 3, 3, 4, 6, 5, 6, 9, 7, 8, 12, 10, 11, 15, 12, 13, 18, 16, 17, 21, 17, 20, 24, 25} - self.base_hp = 22 + (new_game_plus*3) + (15 + new_game_plus*2.4)*y[x] - self.base_dmg = (4 + new_game_plus*1) + (2 + new_game_plus)*y[x] - self.base_mvspd = 70 + 3*y[x] + if self.boss then + local x = self.level + local y = {0, 0, 3, 0, 0, 6, 0, 0, 9, 0, 0, 12, 0, 0, 18, 0, 0, 24, 0, 0, 32, 0, 0, 40, 48} + self.base_hp = 100 + (new_game_plus*5) + (90 + new_game_plus*10)*y[x] + self.base_dmg = (12 + new_game_plus*2) + (2 + new_game_plus)*y[x] + self.base_mvspd = 35 + 1.5*y[x] + else + local x = self.level + local y = {0, 1, 3, 3, 4, 6, 5, 6, 9, 7, 8, 12, 10, 11, 15, 12, 13, 18, 16, 17, 21, 17, 20, 24, 25} + self.base_hp = 22 + (new_game_plus*3) + (15 + new_game_plus*2.7)*y[x] + self.base_dmg = (4 + new_game_plus*1.25) + (2 + new_game_plus*1.2)*y[x] + self.base_mvspd = 70 + 3*y[x] + end end elseif self:is(Saboteur) then self.base_hp = 100*math.pow(2, self.level-1) diff --git a/player.lua b/player.lua index 6c9d07b..5f18904 100644 --- a/player.lua +++ b/player.lua @@ -168,23 +168,28 @@ function Player:init(args) self.last_heal_time = love.timer.getTime() elseif self.character == 'engineer' then - self.turret_counter = 0 self.t:every(8, function() SpawnEffect{group = main.current.effects, x = self.x, y = self.y, color = orange[0], action = function(x, y) Turret{group = main.current.main, x = x, y = y, parent = self} end} - self.turret_counter = self.turret_counter + 1 - if self.turret_counter == 3 and self.level == 3 then - self.turret_counter = 0 - local turrets = main.current.main:get_objects_by_class(Turret) - buff1:play{pitch = random:float(0.95, 1.05), volume = 0.5} - for _, turret in ipairs(turrets) do - HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = orange[0], duration = 0.1} - LightningLine{group = main.current.effects, src = self, dst = turret, color = orange[0]} - turret:upgrade() - end - end - end, nil, nil, 'spawn') + end) + + if self.level == 3 then + self.t:every(24, function() + SpawnEffect{group = main.current.effects, x = self.x - 16, y = self.y + 16, color = orange[0], action = function(x, y) Turret{group = main.current.main, x = x, y = y, parent = self} end} + SpawnEffect{group = main.current.effects, x = self.x + 16, y = self.y + 16, color = orange[0], action = function(x, y) Turret{group = main.current.main, x = x, y = y, parent = self} end} + + self.t:after(0.5, function() + local turrets = main.current.main:get_objects_by_class(Turret) + buff1:play{pitch = random:float(0.95, 1.05), volume = 0.5} + for _, turret in ipairs(turrets) do + HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = orange[0], duration = 0.1} + LightningLine{group = main.current.effects, src = self, dst = turret, color = orange[0]} + turret:upgrade() + end + end) + end) + end elseif self.character == 'plague_doctor' then self.t:every(5, function() @@ -204,7 +209,7 @@ function Player:init(args) elseif self.character == 'juggernaut' then self.t:every(8, function() - self:attack(96, {juggernaut_push = true}) + self:attack(128, {juggernaut_push = true}) end, nil, nil, 'attack') elseif self.character == 'lich' then @@ -245,19 +250,32 @@ function Player:init(args) end, nil, nil, 'shoot') elseif self.character == 'launcher' then - self.t:every(8, function() - self:attack(128) + self.t:every({6, 10}, function() + buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5} + local enemies = main.current.main:get_objects_by_classes(main.current.enemies) + for _, enemy in ipairs(enemies) do + if self:distance_to_object(enemy) < 128 then + local resonance_dmg = 0 + if self.resonance then resonance_dmg = (self.level == 3 and 6*self.dmg*0.05*#enemies or 2*self.dmg*0.05*#enemies) end + enemy:curse('launcher', 4*(self.hex_duration_m or 1), (self.level == 3 and 6*self.dmg or 2*self.dmg) + resonance_dmg, self) + HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = yellow[0], duration = 0.1} + LightningLine{group = main.current.effects, src = self, dst = enemy, color = yellow[0]} + end + end end, nil, nil, 'attack') - elseif self.character == 'bard' then - self.bard_counter = 0 - self.attack_sensor = Circle(self.x, self.y, 64) - self.t:cooldown(2, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function() - local closest_enemy = self:get_closest_object_in_shape(self.attack_sensor, main.current.enemies) - if closest_enemy then - self:shoot(self:angle_to_object(closest_enemy)) + elseif self.character == 'jester' then + self.t:every({6, 10}, function() + buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5} + local enemies = table.first(table.shuffle(main.current.main:get_objects_by_classes(main.current.enemies)), 5) + for _, enemy in ipairs(enemies) do + if self:distance_to_object(enemy) < 128 then + enemy:curse('jester', 6*(self.hex_duration_m or 1), self.level == 3, self) + HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = red[0], duration = 0.1} + LightningLine{group = main.current.effects, src = self, dst = enemy, color = red[0]} + end end - end, nil, nil, 'shoot') + end, nil, nil, 'attack') elseif self.character == 'assassin' then self.attack_sensor = Circle(self.x, self.y, 64) @@ -289,10 +307,17 @@ function Player:init(args) end, nil, nil, 'spawn') elseif self.character == 'bane' then - self.t:every(12, function() - self.dot_area = DotArea{group = main.current.effects, x = self.x, y = self.y, rs = self.area_size_m*128, color = self.color, dmg = self.area_dmg_m*(self.level == 3 and self.dmg or 0), - character = self.character, level = self.level, parent = self, duration = 8} - end, nil, nil, 'spawn') + self.t:every({6, 10}, function() + buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5} + local enemies = table.first(table.shuffle(main.current.main:get_objects_by_classes(main.current.enemies)), 5) + for _, enemy in ipairs(enemies) do + if self:distance_to_object(enemy) < 128 then + enemy:curse('bane', 6*(self.hex_duration_m or 1), self.level == 3, self) + HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = purple[0], duration = 0.1} + LightningLine{group = main.current.effects, src = self, dst = enemy, color = purple[0]} + end + end + end, nil, nil, 'attack') elseif self.character == 'psykino' then self.t:every(4, function() @@ -381,7 +406,8 @@ function Player:init(args) end, nil, nil, 'heal') elseif self.character == 'infestor' then - self.t:every(8, function() + self.t:every({6, 10}, function() + buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5} local enemies = main.current.main:get_objects_by_classes(main.current.enemies) for _, enemy in ipairs(enemies) do if self:distance_to_object(enemy) < 128 then @@ -540,8 +566,8 @@ function Player:init(args) self.unleash_area_dmg_m = 1 self.unleash_area_size_m = 1 self.t:every(1, function() - self.unleash_area_dmg_m = self.unleash_area_dmg_m + 0.02 - self.unleash_area_size_m = self.unleash_area_size_m + 0.02 + self.unleash_area_dmg_m = self.unleash_area_dmg_m + 0.01 + self.unleash_area_size_m = self.unleash_area_size_m + 0.01 if self.dot_area then self.dot_area:scale(self.unleash_area_size_m) end @@ -632,7 +658,7 @@ function Player:update(dt) if class_levels.swarmer >= 1 then number_of_active_sets = number_of_active_sets + 1 end if class_levels.voider >= 1 then number_of_active_sets = number_of_active_sets + 1 end self.vagrant_dmg_m = 1 + 0.1*number_of_active_sets - self.vagrant_aspd_m = 1 + 0.05*number_of_active_sets + self.vagrant_aspd_m = 1 + 0.1*number_of_active_sets end if self.character == 'swordsman' and self.level == 3 then @@ -1125,22 +1151,6 @@ function Player:shoot(r, mods) Projectile(table.merge(t, mods or {})) end - if self.character == 'bard' then - self.bard_counter = self.bard_counter + 1 - if self.bard_counter == 8 and self.level == 3 then - self.bard_counter = 0 - bard2:play{pitch = random:float(0.95, 1.05), volume = 0.5} - self.t:after(3, function() - bard1:play{pitch = random:float(0.95, 1.05), volume = 0.5} - local enemies = main.current.main:get_objects_by_classes(main.current.enemies) - for _, enemy in ipairs(enemies) do - enemy:hit(4*self.dmg) - hit2:play{pitch = random:float(0.95, 1.05), volume = 0.2} - end - end) - end - end - if self.character == 'vagrant' then shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.2} elseif self.character == 'dual_gunner' then @@ -1150,7 +1160,7 @@ function Player:shoot(r, mods) archer1:play{pitch = random:float(0.95, 1.05), volume = 0.35} elseif self.character == 'wizard' or self.character == 'lich' then wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.15} - elseif self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' or self.character == 'spellblade' or self.character == 'bard' or self.character == 'assassin' or self.character == 'beastmaster' then + elseif self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' or self.character == 'spellblade' or self.character == 'jester' or self.character == 'assassin' or self.character == 'beastmaster' then _G[random:table{'scout1', 'scout2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.35} if self.character == 'spellblade' then wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.15} @@ -1431,7 +1441,7 @@ function Projectile:on_collision_enter(other, contact) self.ricochet = self.ricochet - 1 end _G[random:table{'arrow_hit_wall1', 'arrow_hit_wall2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.2} - elseif self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' or self.character == 'spellblade' or self.character == 'bard' or self.character == 'beastmaster' then + elseif self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' or self.character == 'spellblade' or self.character == 'jester' or self.character == 'beastmaster' then self:die(x, y, r, 0) knife_hit_wall1:play{pitch = random:float(0.9, 1.1), volume = 0.2} local r = Unit.bounce(self, nx, ny) @@ -1496,7 +1506,7 @@ function Projectile:on_trigger_enter(other, contact) end if self.character == 'archer' or self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' or self.character == 'hunter' or self.character == 'spellblade' or self.character == 'engineer' or - self.character == 'bard' or self.character == 'assassin' or self.character == 'barrager' or self.character == 'beastmaster' then + self.character == 'jester' or self.character == 'assassin' or self.character == 'barrager' or self.character == 'beastmaster' then hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35} if self.character == 'spellblade' then magic_area1:play{pitch = random:float(0.95, 1.05), volume = 0.15} @@ -1531,10 +1541,6 @@ function Projectile:on_trigger_enter(other, contact) end) end - if self.character == 'bard' then - other:curse('bard') - end - if self.character == 'assassin' then other:apply_dot((self.crit and 4*self.dmg or self.dmg/2)*(self.dot_dmg_m or 1)*(main.current.chronomancer_dot or 1), 3) end @@ -1767,6 +1773,7 @@ function DotArea:init(args) end end, nil, nil, 'dot') + --[[ elseif self.character == 'bane' then if self.level == 3 then self.t:every(0.5, function() @@ -1776,7 +1783,7 @@ function DotArea:init(args) buff1:play{pitch = random:float(0.8, 1.2), volume = 0.1} end for _, enemy in ipairs(enemies) do - enemy:curse('bane', 0.5*(self.hex_duration_m or 1)) + enemy:curse('bane', 0.5*(self.hex_duration_m or 1), self.level == 3, self) if self.level == 3 then enemy:slow(0.5, 0.5) enemy:hit((self.dot_dmg_m or 1)*self.dmg/2) @@ -1787,6 +1794,7 @@ function DotArea:init(args) end end, nil, nil, 'dot') end + ]]-- elseif self.void_rift then self.t:every(0.2, function() @@ -2008,7 +2016,7 @@ function Turret:init(args) self.attack_sensor = Circle(self.x, self.y, 256) turret_deploy:play{pitch = 1.2, volume = 0.2} - self.t:every({3.5, 4.5}, function() + self.t:every({2.75, 3.5}, function() self.t:every({0.1, 0.2}, function() self.hfx:use('hit', 0.25, 200, 10) HitCircle{group = main.current.effects, x = self.x + 0.8*self.shape.w*math.cos(self.r), y = self.y + 0.8*self.shape.w*math.sin(self.r), rs = 6} @@ -2053,8 +2061,8 @@ end function Turret:upgrade() - self.upgrade_dmg_m = self.upgrade_dmg_m + 1 - self.upgrade_aspd_m = self.upgrade_aspd_m + 1 + self.upgrade_dmg_m = self.upgrade_dmg_m + 0.5 + self.upgrade_aspd_m = self.upgrade_aspd_m + 0.5 for i = 1, 6 do HitParticle{group = main.current.effects, x = self.x, y = self.y, r = random:float(0, 2*math.pi), color = self.color} end HitCircle{group = main.current.effects, x = self.x, y = self.y}:scale_down() end @@ -2165,7 +2173,7 @@ function Saboteur:init(args) _G[random:table{'saboteur1', 'saboteur2', 'saboteur3'}]:play{pitch = random:float(0.8, 1.2), volume = 0.2} self.target = random:table(self.group:get_objects_by_classes(main.current.enemies)) - self.actual_dmg = get_character_stat('saboteur', self.level, 'dmg') + self.actual_dmg = 2*get_character_stat('saboteur', self.level, 'dmg') end diff --git a/todo b/todo index 057d710..3487c64 100644 --- a/todo +++ b/todo @@ -1,14 +1,15 @@ -Curser buff - change all cursers to trigger like the infestor does and for the effects to be on-death effects -Forcer buff - change all forcers to have a bigger area or to trigger their effects via projectiles (like the hunter) -Conjurer buff - buff saboteur, buff engineer -Vagrant buff - increase "active set" bonuses -AoE nerf - Unleash 1% +* Curser buff - change all cursers to trigger like the infestor does and for the effects to be on-death effects +* Forcer buff - buff juggernaut +* Conjurer buff - buff saboteur, buff engineer +* Vagrant buff - increase "active set" bonuses +* AoE nerf - Unleash 1%, rephrase it to more clear * Save runs * Move units -Lock shop button -Harder difficulty on NG+0 -Increase boss HP on levels 24 and 25 -Show next level in shop (also if elite or not) +* Lock shop button +* Harder difficulty on NG+0 +* Increase boss HP on levels 24 and 25 +* Show next level in shop (also if elite or not) +* Restart run button on shop View synergy after beating game Option to turn off screen shake Option to show cooldowns on snake