QoL update 1/2

master
a327ex 2021-05-28 22:42:16 -03:00
parent a859f6df56
commit 129cf3ff3b
8 changed files with 284 additions and 132 deletions

View File

@ -777,6 +777,7 @@ end
function Arena:die() function Arena:die()
if not self.died_text and not self.won then if not self.died_text and not self.won then
self.died = true 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.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 = { 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}, {text = '[wavy_mid, cbyc]you died...', font = fat_font, alignment = 'center', height_multiplier = 1.25},

View File

@ -20,6 +20,7 @@ function BuyScreen:on_exit()
self.sets_text = nil self.sets_text = nil
self.items_text = nil self.items_text = nil
self.ng_text = nil self.ng_text = nil
self.level_text = nil
self.characters = nil self.characters = nil
self.sets = nil self.sets = nil
self.cards = nil self.cards = nil
@ -31,6 +32,8 @@ function BuyScreen:on_exit()
self.springs = nil self.springs = nil
self.flashes = nil self.flashes = nil
self.hfx = nil self.hfx = nil
self.tutorial_button = nil
self.restart_button = nil
end end
@ -54,7 +57,10 @@ function BuyScreen:on_enter(from, level, units, passives)
self.ui = Group() self.ui = Group()
self.tutorial = 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_party_and_sets()
self:set_items() 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.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.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.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 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} 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.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.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 = { 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}
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) trigger:tween(1, main_song_instance, {volume = 0.2}, math.linear)
if self.level == 1 then 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.party_text then self.party_text:update(dt) end
if self.items_text then self.items_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.ng_text then self.ng_text:update(dt) end
if self.level_text then self.level_text:update(dt) end
else else
self.tutorial:update(dt*slow_amount) self.tutorial:update(dt*slow_amount)
end end
@ -162,6 +194,7 @@ function BuyScreen:draw()
self.main:draw() self.main:draw()
self.effects:draw() self.effects:draw()
if self.items_text then self.items_text:draw(32, 145) end 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() self.ui:draw()
if self.unit_grabbed then 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.shop_text then self.shop_text:draw(64, 20) end
if self.sets_text then self.sets_text:draw(328, 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 self.party_text then self.party_text:draw(440, 20) end
if new_game_plus > 0 then if new_game_plus > 0 then self.ng_text:draw(240, 20) end
self.ng_text:draw(240, 20)
end
if self.in_tutorial then if self.in_tutorial then
graphics.rectangle(gw/2, gh/2, 2*gw, 2*gh, nil, nil, modal_transparent_2) 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 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 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 = {} self.cards = {}
local all_units = {} 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]))]) 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} 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) 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} if first_call and self.locked then
self.cards[2] = ShopCard{group = self.main, x = 140, y = 75, w = 80, h = 90, unit = unit_2, parent = self, i = 2} 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
self.cards[3] = ShopCard{group = self.main, x = 220, y = 75, w = 80, h = 90, unit = unit_3, parent = self, i = 3} 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 end
@ -467,7 +504,7 @@ function RestartButton:update(dt)
max_units = 7 + new_game_plus max_units = 7 + new_game_plus
system.save_state() system.save_state()
main:add(BuyScreen'buy_screen') 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) main:go_to('buy_screen', 0, {}, passives)
end, text = Text({{text = '[wavy, bg]restarting...', font = pixul_font, alignment = 'center'}}, global_text_tags)} end, text = Text({{text = '[wavy, bg]restarting...', font = pixul_font, alignment = 'center'}}, global_text_tags)}
end end
@ -546,6 +583,13 @@ function Button:on_mouse_exit()
end 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() 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') self.t:after(2, function() self.info_text:deactivate(); self.info_text.dead = true; self.info_text = nil end, 'info_text')
else 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} ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
self.spring:pull(0.2, 200, 10) self.spring:pull(0.2, 200, 10)
self.selected = true self.selected = true
@ -612,6 +657,58 @@ function GoButton:on_mouse_exit()
end 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 = Object:extend()
RerollButton:implement(GameObject) RerollButton:implement(GameObject)

View File

@ -265,7 +265,6 @@ function Seeker:update(dt)
self:calculate_stats() self:calculate_stats()
self.stun_dmg_m = (self.barbarian_stunned and 2 or 1) 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 if self.shooter then
self.t:set_every_multiplier('shooter', (1 - self.level*0.02)) 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 if self.push_invulnerable then return end
self:show_hp() 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 if self.vulnerable then actual_damage = actual_damage*1.2 end
self.hp = self.hp - actual_damage self.hp = self.hp - actual_damage
if self.hp > self.max_hp then self.hp = self.max_hp end 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) 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
end end
@ -528,11 +548,16 @@ function Seeker:curse(curse, duration, arg1, arg2, arg3)
self.launcher = arg2 self.launcher = arg2
self:push(random:float(50, 75)*self.launcher.knockback_m, random:table{0, math.pi, math.pi/2, -math.pi/2}) self:push(random:float(50, 75)*self.launcher.knockback_m, random:table{0, math.pi, math.pi/2, -math.pi/2})
end, 'launcher_curse') end, 'launcher_curse')
elseif curse == 'bard' then elseif curse == 'jester' then
self.bard_cursed = true 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 elseif curse == 'bane' then
self.baned = true self.bane_cursed = true
self.t:after(duration*curse_m, function() self.baned = false end, 'bane_curse') 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 elseif curse == 'infestor' then
self.infested = arg1 self.infested = arg1
self.infested_dmg = arg2 self.infested_dmg = arg2
@ -703,11 +728,16 @@ function EnemyCritter:curse(curse, duration, arg1, arg2, arg3)
self.launcher = arg2 self.launcher = arg2
self:push(random:float(50, 75)*self.launcher.knockback_m, random:table{0, math.pi, math.pi/2, -math.pi/2}) self:push(random:float(50, 75)*self.launcher.knockback_m, random:table{0, math.pi, math.pi/2, -math.pi/2})
end, 'launcher_curse') end, 'launcher_curse')
elseif curse == 'bard' then elseif curse == 'jester' then
self.bard_cursed = true 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 elseif curse == 'bane' then
self.baned = true self.bane_cursed = true
self.t:after(duration*curse_m, function() self.baned = false end, 'bane_curse') 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 elseif curse == 'infestor' then
self.infested = arg1 self.infested = arg1
self.infested_dmg = arg2 self.infested_dmg = arg2

View File

@ -137,8 +137,8 @@ function system.load_state()
end end
function system.save_run(level, gold, units, passives, 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} 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) local str = "return " .. table.tostring(run)
love.filesystem.write("run.txt", str) love.filesystem.write("run.txt", str)
end end

View File

@ -232,7 +232,7 @@ function init()
['corruptor'] = 'Corruptor', ['corruptor'] = 'Corruptor',
['beastmaster'] = 'Beastmaster', ['beastmaster'] = 'Beastmaster',
['launcher'] = 'Launcher', ['launcher'] = 'Launcher',
['bard'] = 'Bard', ['jester'] = 'Jester',
['assassin'] = 'Assassin', ['assassin'] = 'Assassin',
['host'] = 'Host', ['host'] = 'Host',
['carver'] = 'Carver', ['carver'] = 'Carver',
@ -276,7 +276,7 @@ function init()
['corruptor'] = orange[0], ['corruptor'] = orange[0],
['beastmaster'] = red[0], ['beastmaster'] = red[0],
['launcher'] = yellow[0], ['launcher'] = yellow[0],
['bard'] = red[0], ['jester'] = red[0],
['assassin'] = purple[0], ['assassin'] = purple[0],
['host'] = orange[0], ['host'] = orange[0],
['carver'] = green[0], ['carver'] = green[0],
@ -320,7 +320,7 @@ function init()
['corruptor'] = 'orange', ['corruptor'] = 'orange',
['beastmaster'] = 'red', ['beastmaster'] = 'red',
['launcher'] = 'yellow', ['launcher'] = 'yellow',
['bard'] = 'red', ['jester'] = 'red',
['assassin'] = 'purple', ['assassin'] = 'purple',
['host'] = 'orange', ['host'] = 'orange',
['carver'] = 'green', ['carver'] = 'green',
@ -364,7 +364,7 @@ function init()
['corruptor'] = {'ranger', 'swarmer'}, ['corruptor'] = {'ranger', 'swarmer'},
['beastmaster'] = {'rogue', 'swarmer'}, ['beastmaster'] = {'rogue', 'swarmer'},
['launcher'] = {'curser', 'forcer'}, ['launcher'] = {'curser', 'forcer'},
['bard'] = {'curser', 'rogue'}, ['jester'] = {'curser', 'rogue'},
['assassin'] = {'rogue', 'voider'}, ['assassin'] = {'rogue', 'voider'},
['host'] = {'swarmer'}, ['host'] = {'swarmer'},
['carver'] = {'conjurer', 'healer'}, ['carver'] = {'conjurer', 'healer'},
@ -408,7 +408,7 @@ function init()
['corruptor'] = '[green]Ranger, [orange]Swarmer', ['corruptor'] = '[green]Ranger, [orange]Swarmer',
['beastmaster'] = '[red]Rogue, [orange]Swarmer', ['beastmaster'] = '[red]Rogue, [orange]Swarmer',
['launcher'] = '[yellow]Forcer, [purple]Curser', ['launcher'] = '[yellow]Forcer, [purple]Curser',
['bard'] = '[purple]Curser, [red]Rogue', ['jester'] = '[purple]Curser, [red]Rogue',
['assassin'] = '[red]Rogue, [purple]Voider', ['assassin'] = '[red]Rogue, [purple]Voider',
['host'] = '[orange]Swarmer', ['host'] = '[orange]Swarmer',
['carver'] = '[orange]Conjurer, [green]Healer', ['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, ['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, ['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, ['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, ['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,
['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, ['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]' .. ['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, 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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['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', ['chronomancer'] = '[blue]Quicken',
['spellblade'] = '[blue]Spiralism', ['spellblade'] = '[blue]Spiralism',
['psykeeper'] = '[fg]Crucio', ['psykeeper'] = '[fg]Crucio',
['engineer'] = '[orange]Upgrade', ['engineer'] = '[orange]Upgrade!!!',
['plague_doctor'] = '[purple]Black Death Steam', ['plague_doctor'] = '[purple]Black Death Steam',
['barbarian'] = '[yellow]Seism', ['barbarian'] = '[yellow]Seism',
['juggernaut'] = '[yellow]Brutal Impact', ['juggernaut'] = '[yellow]Brutal Impact',
@ -513,7 +513,7 @@ function init()
['corruptor'] = '[orange]Corruption', ['corruptor'] = '[orange]Corruption',
['beastmaster'] = '[red]Call of the Wild', ['beastmaster'] = '[red]Call of the Wild',
['launcher'] = '[orange]Kineticism', ['launcher'] = '[orange]Kineticism',
['bard'] = "[red]The Bard's Song", ['jester'] = "[red]Pandemonium",
['assassin'] = '[purple]Toxic Delivery', ['assassin'] = '[purple]Toxic Delivery',
['host'] = '[orange]Invasion', ['host'] = '[orange]Invasion',
['carver'] = '[green]World Tree', ['carver'] = '[green]World Tree',
@ -547,7 +547,7 @@ function init()
['chronomancer'] = '[light_bg]Quicken', ['chronomancer'] = '[light_bg]Quicken',
['spellblade'] = '[light_bg]Spiralism', ['spellblade'] = '[light_bg]Spiralism',
['psykeeper'] = '[light_bg]Crucio', ['psykeeper'] = '[light_bg]Crucio',
['engineer'] = '[light_bg]Upgrade', ['engineer'] = '[light_bg]Upgrade!!!',
['plague_doctor'] = '[light_bg]Black Death Steam', ['plague_doctor'] = '[light_bg]Black Death Steam',
['barbarian'] = '[light_bg]Seism', ['barbarian'] = '[light_bg]Seism',
['juggernaut'] = '[light_bg]Brutal Impact', ['juggernaut'] = '[light_bg]Brutal Impact',
@ -557,7 +557,7 @@ function init()
['corruptor'] = '[light_bg]Corruption', ['corruptor'] = '[light_bg]Corruption',
['beastmaster'] = '[light_bg]Call of the Wild', ['beastmaster'] = '[light_bg]Call of the Wild',
['launcher'] = '[light_bg]Kineticism', ['launcher'] = '[light_bg]Kineticism',
['bard'] = "[light_bg]The Bard's Song", ['jester'] = "[light_bg]Pandemonium",
['assassin'] = '[light_bg]Toxic Delivery', ['assassin'] = '[light_bg]Toxic Delivery',
['host'] = '[light_bg]Invasion', ['host'] = '[light_bg]Invasion',
['carver'] = '[light_bg]World Tree', ['carver'] = '[light_bg]World Tree',
@ -572,7 +572,7 @@ function init()
} }
character_effect_descriptions = { 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, ['swordsman'] = function() return "[fg]the swordsman's damage is [yellow]doubled" end,
['wizard'] = function() return '[fg]the projectile chains [yellow]3[fg] times' 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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['highlander'] = function() return '[fg]quickly repeats the attack [yellow]3[fg] times' end,
@ -616,7 +616,7 @@ function init()
} }
character_effect_descriptions_gray = { 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, ['swordsman'] = function() return "[light_bg]the swordsman's damage is doubled" end,
['wizard'] = function() return '[light_bg]the projectile chains 3 times' 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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['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, ['corruptor'] = function(lvl) return get_character_stat_string('corruptor', lvl) end,
['beastmaster'] = function(lvl) return get_character_stat_string('beastmaster', lvl) end, ['beastmaster'] = function(lvl) return get_character_stat_string('beastmaster', lvl) end,
['launcher'] = function(lvl) return get_character_stat_string('launcher', 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, ['assassin'] = function(lvl) return get_character_stat_string('assassin', lvl) end,
['host'] = function(lvl) return get_character_stat_string('host', lvl) end, ['host'] = function(lvl) return get_character_stat_string('host', lvl) end,
['carver'] = function(lvl) return get_character_stat_string('carver', lvl) end, ['carver'] = function(lvl) return get_character_stat_string('carver', lvl) end,
@ -743,7 +743,7 @@ function init()
tier_to_characters = { tier_to_characters = {
[1] = {'vagrant', 'swordsman', 'wizard', 'archer', 'scout', 'cleric'}, [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'}, [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'}, [4] = {'priest', 'highlander', 'psykino', 'lich', 'host', 'fairy', 'blade', 'plague_doctor', 'cannoneer'},
} }
@ -780,7 +780,7 @@ function init()
['corruptor'] = 3, ['corruptor'] = 3,
['beastmaster'] = 2, ['beastmaster'] = 2,
['launcher'] = 2, ['launcher'] = 2,
['bard'] = 2, ['jester'] = 2,
['assassin'] = 3, ['assassin'] = 3,
['host'] = 4, ['host'] = 4,
['carver'] = 2, ['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', ['assassination'] = '[fg]crits from rogues deal [yellow]8x[fg] damage but normal attacks deal [yellow]half[fg] damage',
['magnify'] = '[yellow]+25%[fg] area size', ['magnify'] = '[yellow]+25%[fg] area size',
['echo_barrage'] = '[yellow]20%[fg] chance to create [yellow]3[fg] secondary AoEs on AoE hit', ['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', ['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', ['payback'] = '[yellow]+5%[fg] damage to all allies whenever an enchanter is hit',
['blessing'] = '[yellow]+20%[fg] healing effectiveness', ['blessing'] = '[yellow]+20%[fg] healing effectiveness',
@ -1167,6 +1167,7 @@ function init()
} }
gold = run.gold or 2 gold = run.gold or 2
passives = run.passives or {} passives = run.passives or {}
locked_state = run.locked_state
steam.userStats.requestCurrentStats() steam.userStats.requestCurrentStats()
new_game_plus = state.new_game_plus or 0 new_game_plus = state.new_game_plus or 0
if not state.new_game_plus then state.new_game_plus = new_game_plus end 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:add(Arena'arena')
main:go_to('arena', 20, { main:go_to('arena', 9, {
{character = 'vagrant', level = 3}, {character = 'dual_gunner', level = 3},
{character = 'engineer', level = 3},
{character = 'spellblade', level = 3}, {character = 'spellblade', level = 3},
{character = 'assassin', level = 3}, {character = 'assassin', level = 3},
{character = 'scout', level = 3}, {character = 'scout', level = 3},
@ -1192,9 +1194,6 @@ function init()
{character = 'swordsman', level = 3}, {character = 'swordsman', level = 3},
{character = 'archer', level = 3}, {character = 'archer', level = 3},
}, passives) }, passives)
main:add(Media'media')
main:go_to('media')
]]-- ]]--
trigger:every(2, function() trigger:every(2, function()

View File

@ -229,18 +229,34 @@ function Unit:calculate_stats(first_run)
self.base_dmg = 10*math.pow(2, self.level-1) self.base_dmg = 10*math.pow(2, self.level-1)
self.base_mvspd = 75 self.base_mvspd = 75
elseif self:is(Seeker) then elseif self:is(Seeker) then
if self.boss then if new_game_plus == 0 then
local x = self.level if self.boss then
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} local x = self.level
self.base_hp = 100 + (new_game_plus*5) + (90 + new_game_plus*10)*y[x] 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_dmg = (12 + new_game_plus*2) + (2 + new_game_plus)*y[x] self.base_hp = 100 + (new_game_plus*5) + (90 + new_game_plus*10)*y[x]
self.base_mvspd = 35 + 1.5*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 else
local x = self.level if self.boss then
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} local x = self.level
self.base_hp = 22 + (new_game_plus*3) + (15 + new_game_plus*2.4)*y[x] 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_dmg = (4 + new_game_plus*1) + (2 + new_game_plus)*y[x] self.base_hp = 100 + (new_game_plus*5) + (90 + new_game_plus*10)*y[x]
self.base_mvspd = 70 + 3*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 end
elseif self:is(Saboteur) then elseif self:is(Saboteur) then
self.base_hp = 100*math.pow(2, self.level-1) self.base_hp = 100*math.pow(2, self.level-1)

View File

@ -168,23 +168,28 @@ function Player:init(args)
self.last_heal_time = love.timer.getTime() self.last_heal_time = love.timer.getTime()
elseif self.character == 'engineer' then elseif self.character == 'engineer' then
self.turret_counter = 0
self.t:every(8, function() self.t:every(8, function()
SpawnEffect{group = main.current.effects, x = self.x, y = self.y, color = orange[0], action = function(x, y) 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} Turret{group = main.current.main, x = x, y = y, parent = self}
end} end}
self.turret_counter = self.turret_counter + 1 end)
if self.turret_counter == 3 and self.level == 3 then
self.turret_counter = 0 if self.level == 3 then
local turrets = main.current.main:get_objects_by_class(Turret) self.t:every(24, function()
buff1:play{pitch = random:float(0.95, 1.05), volume = 0.5} 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}
for _, turret in ipairs(turrets) do 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}
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]} self.t:after(0.5, function()
turret:upgrade() local turrets = main.current.main:get_objects_by_class(Turret)
end buff1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
end for _, turret in ipairs(turrets) do
end, nil, nil, 'spawn') 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 elseif self.character == 'plague_doctor' then
self.t:every(5, function() self.t:every(5, function()
@ -204,7 +209,7 @@ function Player:init(args)
elseif self.character == 'juggernaut' then elseif self.character == 'juggernaut' then
self.t:every(8, function() self.t:every(8, function()
self:attack(96, {juggernaut_push = true}) self:attack(128, {juggernaut_push = true})
end, nil, nil, 'attack') end, nil, nil, 'attack')
elseif self.character == 'lich' then elseif self.character == 'lich' then
@ -245,19 +250,32 @@ function Player:init(args)
end, nil, nil, 'shoot') end, nil, nil, 'shoot')
elseif self.character == 'launcher' then elseif self.character == 'launcher' then
self.t:every(8, function() self.t:every({6, 10}, function()
self:attack(128) 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') end, nil, nil, 'attack')
elseif self.character == 'bard' then elseif self.character == 'jester' then
self.bard_counter = 0 self.t:every({6, 10}, function()
self.attack_sensor = Circle(self.x, self.y, 64) buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
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 enemies = table.first(table.shuffle(main.current.main:get_objects_by_classes(main.current.enemies)), 5)
local closest_enemy = self:get_closest_object_in_shape(self.attack_sensor, main.current.enemies) for _, enemy in ipairs(enemies) do
if closest_enemy then if self:distance_to_object(enemy) < 128 then
self:shoot(self:angle_to_object(closest_enemy)) 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
end, nil, nil, 'shoot') end, nil, nil, 'attack')
elseif self.character == 'assassin' then elseif self.character == 'assassin' then
self.attack_sensor = Circle(self.x, self.y, 64) self.attack_sensor = Circle(self.x, self.y, 64)
@ -289,10 +307,17 @@ function Player:init(args)
end, nil, nil, 'spawn') end, nil, nil, 'spawn')
elseif self.character == 'bane' then elseif self.character == 'bane' then
self.t:every(12, function() self.t:every({6, 10}, 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), buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
character = self.character, level = self.level, parent = self, duration = 8} local enemies = table.first(table.shuffle(main.current.main:get_objects_by_classes(main.current.enemies)), 5)
end, nil, nil, 'spawn') 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 elseif self.character == 'psykino' then
self.t:every(4, function() self.t:every(4, function()
@ -381,7 +406,8 @@ function Player:init(args)
end, nil, nil, 'heal') end, nil, nil, 'heal')
elseif self.character == 'infestor' then 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) local enemies = main.current.main:get_objects_by_classes(main.current.enemies)
for _, enemy in ipairs(enemies) do for _, enemy in ipairs(enemies) do
if self:distance_to_object(enemy) < 128 then 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_dmg_m = 1
self.unleash_area_size_m = 1 self.unleash_area_size_m = 1
self.t:every(1, function() self.t:every(1, function()
self.unleash_area_dmg_m = self.unleash_area_dmg_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.02 self.unleash_area_size_m = self.unleash_area_size_m + 0.01
if self.dot_area then if self.dot_area then
self.dot_area:scale(self.unleash_area_size_m) self.dot_area:scale(self.unleash_area_size_m)
end 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.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 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_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 end
if self.character == 'swordsman' and self.level == 3 then if self.character == 'swordsman' and self.level == 3 then
@ -1125,22 +1151,6 @@ function Player:shoot(r, mods)
Projectile(table.merge(t, mods or {})) Projectile(table.merge(t, mods or {}))
end 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 if self.character == 'vagrant' then
shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.2} shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.2}
elseif self.character == 'dual_gunner' then 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} archer1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
elseif self.character == 'wizard' or self.character == 'lich' then elseif self.character == 'wizard' or self.character == 'lich' then
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.15} 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} _G[random:table{'scout1', 'scout2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.35}
if self.character == 'spellblade' then if self.character == 'spellblade' then
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.15} 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 self.ricochet = self.ricochet - 1
end end
_G[random:table{'arrow_hit_wall1', 'arrow_hit_wall2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.2} _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) self:die(x, y, r, 0)
knife_hit_wall1:play{pitch = random:float(0.9, 1.1), volume = 0.2} knife_hit_wall1:play{pitch = random:float(0.9, 1.1), volume = 0.2}
local r = Unit.bounce(self, nx, ny) local r = Unit.bounce(self, nx, ny)
@ -1496,7 +1506,7 @@ function Projectile:on_trigger_enter(other, contact)
end 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 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} hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
if self.character == 'spellblade' then if self.character == 'spellblade' then
magic_area1:play{pitch = random:float(0.95, 1.05), volume = 0.15} 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)
end end
if self.character == 'bard' then
other:curse('bard')
end
if self.character == 'assassin' then 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) 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 end
@ -1767,6 +1773,7 @@ function DotArea:init(args)
end end
end, nil, nil, 'dot') end, nil, nil, 'dot')
--[[
elseif self.character == 'bane' then elseif self.character == 'bane' then
if self.level == 3 then if self.level == 3 then
self.t:every(0.5, function() 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} buff1:play{pitch = random:float(0.8, 1.2), volume = 0.1}
end end
for _, enemy in ipairs(enemies) do 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 if self.level == 3 then
enemy:slow(0.5, 0.5) enemy:slow(0.5, 0.5)
enemy:hit((self.dot_dmg_m or 1)*self.dmg/2) enemy:hit((self.dot_dmg_m or 1)*self.dmg/2)
@ -1787,6 +1794,7 @@ function DotArea:init(args)
end end
end, nil, nil, 'dot') end, nil, nil, 'dot')
end end
]]--
elseif self.void_rift then elseif self.void_rift then
self.t:every(0.2, function() self.t:every(0.2, function()
@ -2008,7 +2016,7 @@ function Turret:init(args)
self.attack_sensor = Circle(self.x, self.y, 256) self.attack_sensor = Circle(self.x, self.y, 256)
turret_deploy:play{pitch = 1.2, volume = 0.2} 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.t:every({0.1, 0.2}, function()
self.hfx:use('hit', 0.25, 200, 10) 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} 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() function Turret:upgrade()
self.upgrade_dmg_m = self.upgrade_dmg_m + 1 self.upgrade_dmg_m = self.upgrade_dmg_m + 0.5
self.upgrade_aspd_m = self.upgrade_aspd_m + 1 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 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() HitCircle{group = main.current.effects, x = self.x, y = self.y}:scale_down()
end 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} _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.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 end

19
todo
View File

@ -1,14 +1,15 @@
Curser buff - change all cursers to trigger like the infestor does and for the effects to be on-death effects * 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) * Forcer buff - buff juggernaut
Conjurer buff - buff saboteur, buff engineer * Conjurer buff - buff saboteur, buff engineer
Vagrant buff - increase "active set" bonuses * Vagrant buff - increase "active set" bonuses
AoE nerf - Unleash 1% * AoE nerf - Unleash 1%, rephrase it to more clear
* Save runs * Save runs
* Move units * Move units
Lock shop button * Lock shop button
Harder difficulty on NG+0 * Harder difficulty on NG+0
Increase boss HP on levels 24 and 25 * Increase boss HP on levels 24 and 25
Show next level in shop (also if elite or not) * Show next level in shop (also if elite or not)
* Restart run button on shop
View synergy after beating game View synergy after beating game
Option to turn off screen shake Option to turn off screen shake
Option to show cooldowns on snake Option to show cooldowns on snake