Item update 1/5

master
a327ex 2021-06-14 01:59:16 -03:00
parent b335a62309
commit 4de2640da1
7 changed files with 212 additions and 129 deletions

View File

@ -7,7 +7,7 @@ function Arena:init(name)
end end
function Arena:on_enter(from, level, units, passives, shop_level, shop_xp) function Arena:on_enter(from, level, units, passives, shop_level, shop_xp, lock)
self.hfx:add('condition1', 1) self.hfx:add('condition1', 1)
self.hfx:add('condition2', 1) self.hfx:add('condition2', 1)
self.level = level or 1 self.level = level or 1
@ -15,6 +15,9 @@ function Arena:on_enter(from, level, units, passives, shop_level, shop_xp)
self.passives = passives self.passives = passives
self.shop_level = shop_level or 1 self.shop_level = shop_level or 1
self.shop_xp = shop_xp or 0 self.shop_xp = shop_xp or 0
self.lock = lock
self.starting_units = table.copy(units)
if not state.mouse_control then if not state.mouse_control then
input:set_mouse_visible(false) input:set_mouse_visible(false)
@ -448,11 +451,13 @@ function Arena:update(dt)
end} end}
self.video_button_1 = Button{group = self.ui, x = gw/2 - 86, y = gh - 125, force_update = true, button_text = 'window size-', fg_color = 'bg10', bg_color = 'bg', action = function() self.video_button_1 = Button{group = self.ui, x = gw/2 - 86, y = gh - 125, force_update = true, button_text = 'window size-', fg_color = 'bg10', bg_color = 'bg', action = function()
if sx > 1 and sy > 1 then
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5} ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
sx, sy = sx - 1, sy - 1 sx, sy = sx - 1, sy - 1
love.window.setMode(480*sx, 270*sy) love.window.setMode(480*sx, 270*sy)
state.sx, state.sy = sx, sy state.sx, state.sy = sx, sy
state.fullscreen = false state.fullscreen = false
end
end} end}
self.video_button_2 = Button{group = self.ui, x = gw/2, y = gh - 125, force_update = true, button_text = 'window size+', fg_color = 'bg10', bg_color = 'bg', action = function() self.video_button_2 = Button{group = self.ui, x = gw/2, y = gh - 125, force_update = true, button_text = 'window size+', fg_color = 'bg10', bg_color = 'bg', action = function()
@ -617,18 +622,38 @@ function Arena:quit()
input:set_mouse_visible(true) input:set_mouse_visible(true)
self.won = true self.won = true
locked_state = nil locked_state = nil
if current_new_game_plus == new_game_plus then
new_game_plus = new_game_plus + 1
state.new_game_plus = new_game_plus
end
current_new_game_plus = current_new_game_plus + 1
state.current_new_game_plus = current_new_game_plus
max_units = 7 + current_new_game_plus
system.save_run() system.save_run()
trigger:tween(1, _G, {slow_amount = 0}, math.linear, function() slow_amount = 0 end, 'slow_amount') trigger:tween(1, _G, {slow_amount = 0}, math.linear, function() slow_amount = 0 end, 'slow_amount')
trigger:tween(4, camera, {x = gw/2, y = gh/2, r = 0}, math.linear, function() camera.x, camera.y, camera.r = gw/2, gh/2, 0 end) trigger:tween(4, camera, {x = gw/2, y = gh/2, r = 0}, math.linear, function() camera.x, camera.y, camera.r = gw/2, gh/2, 0 end)
self.win_text = Text2{group = self.ui, x = gw/2, y = gh/2 - 66, force_update = true, lines = {{text = '[wavy_mid, cbyc2]congratulations!', font = fat_font, alignment = 'center'}}} self.win_text = Text2{group = self.ui, x = gw/2 + 40, y = gh/2 - 66, force_update = true, lines = {{text = '[wavy_mid, cbyc2]congratulations!', font = fat_font, alignment = 'center'}}}
trigger:after(2.5, function() trigger:after(2.5, function()
self.build_text = Text2{group = self.ui, x = 40, y = 20, force_update = true, lines = {{text = "[wavy_mid, fg]your build", font = pixul_font, alignment = 'center'}}} self.build_text = Text2{group = self.ui, x = 40, y = 20, force_update = true, lines = {{text = "[wavy_mid, fg]your build", font = pixul_font, alignment = 'center'}}}
for i, unit in ipairs(self.units) do for i, unit in ipairs(self.units) do
CharacterPart{group = self.ui, x = 40, y = 40 + (i-1)*19, character = unit.character, level = unit.level, force_update = true, cant_click = true, parent = self} CharacterPart{group = self.ui, x = 20, y = 40 + (i-1)*19, character = unit.character, level = unit.level, force_update = true, cant_click = true, parent = self}
Text2{group = self.ui, x = 20 + 14 + pixul_font:get_text_width(unit.character)/2, y = 40 + (i-1)*19, force_update = true, lines = {
{text = '[' .. character_color_strings[unit.character] .. ']' .. unit.character, font = pixul_font, alignment = 'left'}
}}
end end
if current_new_game_plus == 5 then if current_new_game_plus == 6 then
self.win_text2 = Text2{group = self.ui, x = gw/2, y = gh/2 + 30, force_update = true, lines = { if current_new_game_plus == new_game_plus then
new_game_plus = 5
state.new_game_plus = new_game_plus
end
current_new_game_plus = 5
state.current_new_game_plus = current_new_game_plus
max_units = 12
self.win_text2 = Text2{group = self.ui, x = gw/2 + 40, y = gh/2 + 30, force_update = true, lines = {
{text = "[fg]now you've really beaten the game!", font = pixul_font, alignment = 'center', height_multiplier = 1.24}, {text = "[fg]now you've really beaten the game!", font = pixul_font, alignment = 'center', height_multiplier = 1.24},
{text = "[fg]thanks a lot for playing it and completing it entirely!", font = pixul_font, alignment = 'center', height_multiplier = 1.24}, {text = "[fg]thanks a lot for playing it and completing it entirely!", font = pixul_font, alignment = 'center', height_multiplier = 1.24},
{text = "[fg]this game was inspired by:", font = pixul_font, alignment = 'center', height_multiplier = 4}, {text = "[fg]this game was inspired by:", font = pixul_font, alignment = 'center', height_multiplier = 4},
@ -636,7 +661,7 @@ function Arena:quit()
{text = "[fg]and to get more games like this in the future:", font = pixul_font, alignment = 'center', height_multiplier = 4}, {text = "[fg]and to get more games like this in the future:", font = pixul_font, alignment = 'center', height_multiplier = 4},
{text = "[wavy_mid, yellow]thanks for playing!", font = pixul_font, alignment = 'center'}, {text = "[wavy_mid, yellow]thanks for playing!", font = pixul_font, alignment = 'center'},
}} }}
SteamFollowButton{group = self.ui, x = gw/2, y = gh/2 + 78, force_update = true} SteamFollowButton{group = self.ui, x = gw/2 + 40, y = gh/2 + 78, force_update = true}
Button{group = self.ui, x = gw - 40, y = gh - 44, force_update = true, button_text = 'credits', fg_color = 'bg10', bg_color = 'bg', action = function() self:create_credits() end} Button{group = self.ui, x = gw - 40, y = gh - 44, force_update = true, button_text = 'credits', fg_color = 'bg10', bg_color = 'bg', action = function() self:create_credits() end}
Button{group = self.ui, x = gw - 32, y = gh - 20, force_update = true, button_text = 'quit', fg_color = 'bg10', bg_color = 'bg', action = function() love.event.quit() end} Button{group = self.ui, x = gw - 32, y = gh - 20, force_update = true, button_text = 'quit', fg_color = 'bg10', bg_color = 'bg', action = function() love.event.quit() end}
local open_url = function(b, url) local open_url = function(b, url)
@ -646,10 +671,10 @@ function Arena:quit()
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5} ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
system.open_url(url) system.open_url(url)
end end
Button{group = self.ui, x = gw/2 - 50, y = gh/2 + 12, force_update = true, button_text = 'nimble quest', fg_color = 'bluem5', bg_color = 'blue', action = function(b) open_url(b, 'https://store.steampowered.com/app/259780/Nimble_Quest/') end} Button{group = self.ui, x = gw/2 - 50 + 40, y = gh/2 + 12, force_update = true, button_text = 'nimble quest', fg_color = 'bluem5', bg_color = 'blue', action = function(b) open_url(b, 'https://store.steampowered.com/app/259780/Nimble_Quest/') end}
Button{group = self.ui, x = gw/2 + 50, y = gh/2 + 12, force_update = true, button_text = 'dota underlords', fg_color = 'bluem5', bg_color = 'blue', action = function(b) open_url(b, 'https://store.steampowered.com/app/1046930/Dota_Underlords/') end} Button{group = self.ui, x = gw/2 + 50 + 40, y = gh/2 + 12, force_update = true, button_text = 'dota underlords', fg_color = 'bluem5', bg_color = 'blue', action = function(b) open_url(b, 'https://store.steampowered.com/app/1046930/Dota_Underlords/') end}
else else
self.win_text2 = Text2{group = self.ui, x = gw/2, y = gh/2 + 20, force_update = true, lines = { self.win_text2 = Text2{group = self.ui, x = gw/2 + 40, y = gh/2 + 20, force_update = true, lines = {
{text = "[fg]you've beaten the game!", font = pixul_font, alignment = 'center', height_multiplier = 1.24}, {text = "[fg]you've beaten the game!", font = pixul_font, alignment = 'center', height_multiplier = 1.24},
{text = "[fg]i made this game in 3 months as a dev challenge", font = pixul_font, alignment = 'center', height_multiplier = 1.24}, {text = "[fg]i made this game in 3 months as a dev challenge", font = pixul_font, alignment = 'center', height_multiplier = 1.24},
{text = "[fg]and i'm happy with how it turned out!", font = pixul_font, alignment = 'center', height_multiplier = 1.24}, {text = "[fg]and i'm happy with how it turned out!", font = pixul_font, alignment = 'center', height_multiplier = 1.24},
@ -657,7 +682,7 @@ function Arena:quit()
{text = "[fg]i will release more games this year, so stay tuned!", font = pixul_font, alignment = 'center', height_multiplier = 1.4}, {text = "[fg]i will release more games this year, so stay tuned!", font = pixul_font, alignment = 'center', height_multiplier = 1.4},
{text = "[wavy_mid, yellow]thanks for playing!", font = pixul_font, alignment = 'center'}, {text = "[wavy_mid, yellow]thanks for playing!", font = pixul_font, alignment = 'center'},
}} }}
SteamFollowButton{group = self.ui, x = gw/2, y = gh/2 + 34, force_update = true} SteamFollowButton{group = self.ui, x = gw/2 + 40, y = gh/2 + 34, force_update = true}
RestartButton{group = self.ui, x = gw - 40, y = gh - 20, force_update = true} RestartButton{group = self.ui, x = gw - 40, y = gh - 20, force_update = true}
trigger:after(8, function() trigger:after(8, function()
self.try_ng_text = Text2{group = self.ui, x = gw - 210, y = gh - 20, force_update = true, lines = { self.try_ng_text = Text2{group = self.ui, x = gw - 210, y = gh - 20, force_update = true, lines = {
@ -789,9 +814,8 @@ function Arena:quit()
steam.userStats.storeStats() steam.userStats.storeStats()
end end
local units = self.player:get_all_units()
local all_units_level_2 = true local all_units_level_2 = true
for _, unit in ipairs(units) do for _, unit in ipairs(self.starting_units) do
if unit.level ~= 2 then if unit.level ~= 2 then
all_units_level_2 = false all_units_level_2 = false
break break
@ -806,7 +830,7 @@ function Arena:quit()
local units = self.player:get_all_units() local units = self.player:get_all_units()
local all_units_level_3 = true local all_units_level_3 = true
for _, unit in ipairs(units) do for _, unit in ipairs(self.starting_units) do
if unit.level ~= 3 then if unit.level ~= 3 then
all_units_level_3 = false all_units_level_3 = false
break break
@ -843,9 +867,9 @@ end
function Arena:set_passives(from_reroll) function Arena:set_passives(from_reroll)
if from_reroll then if from_reroll then
self:restore_passives_to_pool(0) self:restore_passives_to_pool(0)
self.cards[1].dead = true if self.cards[1] then self.cards[1].dead = true end
self.cards[2].dead = true if self.cards[2] then self.cards[2].dead = true end
self.cards[3].dead = true if self.cards[3] then self.cards[3].dead = true end
self.cards = {} self.cards = {}
end end
@ -947,6 +971,7 @@ end
function Arena:die() function Arena:die()
if not self.died_text and not self.won and not self.arena_clear_text then if not self.died_text and not self.won and not self.arena_clear_text then
input:set_mouse_visible(false)
self.t:cancel('divine_punishment') self.t:cancel('divine_punishment')
self.died = true self.died = true
locked_state = nil locked_state = nil
@ -1057,6 +1082,7 @@ end
function Arena:transition() function Arena:transition()
self.transitioning = true self.transitioning = true
if not self.lock then locked_state = nil end
ui_transition2:play{pitch = random:float(0.95, 1.05), volume = 0.5} ui_transition2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
TransitionEffect{group = main.transitions, x = self.player.x, y = self.player.y, color = self.color, transition_action = function(t) TransitionEffect{group = main.transitions, x = self.player.x, y = self.player.y, color = self.color, transition_action = function(t)
if self.level % 2 == 0 and self.shop_level < 5 then if self.level % 2 == 0 and self.shop_level < 5 then

View File

@ -65,7 +65,7 @@ function BuyScreen:on_enter(from, level, units, passives, shop_level, shop_xp)
self.locked = locked_state and locked_state.locked self.locked = locked_state and locked_state.locked
LockButton{group = self.main, x = 205, y = 18, parent = self} LockButton{group = self.main, x = 205, y = 18, parent = self}
self:set_cards(nil, nil, true) self:set_cards(self.shop_level, nil, true)
self:set_party_and_sets() self:set_party_and_sets()
self:set_items() self:set_items()
@ -136,6 +136,7 @@ function BuyScreen:on_enter(from, level, units, passives, shop_level, shop_xp)
ui_transition2:play{pitch = random:float(0.95, 1.05), volume = 0.5} 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_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} ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
locked_state = nil
TransitionEffect{group = main.transitions, x = gw/2, y = gh/2, color = fg[0], transition_action = function() TransitionEffect{group = main.transitions, x = gw/2, y = gh/2, color = fg[0], transition_action = function()
slow_amount = 1 slow_amount = 1
gold = 3 gold = 3
@ -507,7 +508,7 @@ function RestartButton:init(args)
self:init_game_object(args) self:init_game_object(args)
self.shape = Rectangle(self.x, self.y, pixul_font:get_text_width('restart') + 4, pixul_font.h + 4) self.shape = Rectangle(self.x, self.y, pixul_font:get_text_width('restart') + 4, pixul_font.h + 4)
self.interact_with_mouse = true self.interact_with_mouse = true
self.text = Text({{text = '[bg10]NG+' .. tostring(current_new_game_plus+1), font = pixul_font, alignment = 'center'}}, global_text_tags) self.text = Text({{text = '[bg10]NG+' .. tostring(current_new_game_plus), font = pixul_font, alignment = 'center'}}, global_text_tags)
end end
@ -532,13 +533,6 @@ function RestartButton:update(dt)
'reinforce', 'payback', 'whispers_of_doom', 'heavy_impact', 'immolation', 'call_of_the_void'}, 'reinforce', 'payback', 'whispers_of_doom', 'heavy_impact', 'immolation', 'call_of_the_void'},
[3] = {'divine_machine_arrow', 'divine_punishment', 'flying_daggers', 'crucio', 'hive', 'void_rift'}, [3] = {'divine_machine_arrow', 'divine_punishment', 'flying_daggers', 'crucio', 'hive', 'void_rift'},
} }
if current_new_game_plus == new_game_plus then
new_game_plus = new_game_plus + 1
state.new_game_plus = new_game_plus
end
current_new_game_plus = current_new_game_plus + 1
state.current_new_game_plus = current_new_game_plus
max_units = 7 + current_new_game_plus
system.save_state() system.save_state()
main:add(BuyScreen'buy_screen') main:add(BuyScreen'buy_screen')
system.save_run() system.save_run()
@ -561,14 +555,14 @@ function RestartButton:on_mouse_enter()
ui_hover1:play{pitch = random:float(1.3, 1.5), volume = 0.5} 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} pop2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
self.selected = true self.selected = true
self.text:set_text{{text = '[fgm5]NG+' .. tostring(current_new_game_plus+1), font = pixul_font, alignment = 'center'}} self.text:set_text{{text = '[fgm5]NG+' .. tostring(current_new_game_plus), font = pixul_font, alignment = 'center'}}
self.spring:pull(0.2, 200, 10) self.spring:pull(0.2, 200, 10)
end end
function RestartButton:on_mouse_exit() function RestartButton:on_mouse_exit()
if main.current.in_credits then return end if main.current.in_credits then return end
self.text:set_text{{text = '[bg10]NG+' .. tostring(current_new_game_plus+1), font = pixul_font, alignment = 'center'}} self.text:set_text{{text = '[bg10]NG+' .. tostring(current_new_game_plus), font = pixul_font, alignment = 'center'}}
self.selected = false self.selected = false
end end
@ -681,16 +675,17 @@ 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 locked_state = {locked = self.parent.locked, 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}}
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
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5} ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_transition1:play{pitch = random:float(0.95, 1.05), volume = 0.5} ui_transition1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
self.transitioning = true self.transitioning = true
system.save_run(self.parent.level, gold, self.parent.units, passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool_by_tiers, locked_state)
TransitionEffect{group = main.transitions, x = self.x, y = self.y, color = character_colors[random:table(self.parent.units).character], transition_action = function() TransitionEffect{group = main.transitions, x = self.x, y = self.y, color = character_colors[random:table(self.parent.units).character], transition_action = function()
main:add(Arena'arena') main:add(Arena'arena')
main:go_to('arena', ((self.parent.first_screen and 1) or (self.parent.level + 1)), self.parent.units, self.parent.passives, self.parent.shop_level, self.parent.shop_xp) main:go_to('arena', ((self.parent.first_screen and 1) or (self.parent.level + 1)), self.parent.units, self.parent.passives, self.parent.shop_level, self.parent.shop_xp, self.parent.locked)
end, text = Text({{text = '[wavy, bg]level ' .. ((self.parent.first_screen and 1) or (self.parent.level + 1)) .. '/25', font = pixul_font, alignment = 'center'}}, global_text_tags)} end, text = Text({{text = '[wavy, bg]level ' .. ((self.parent.first_screen and 1) or (self.parent.level + 1)) .. '/25', font = pixul_font, alignment = 'center'}}, global_text_tags)}
end end
end end
@ -922,7 +917,7 @@ function RerollButton:init(args)
self.free_reroll = true self.free_reroll = true
self.text = Text({{text = '[bg10]reroll: [yellow]0', font = pixul_font, alignment = 'center'}}, global_text_tags) self.text = Text({{text = '[bg10]reroll: [yellow]0', font = pixul_font, alignment = 'center'}}, global_text_tags)
else else
self.text = Text({{text = '[bg10]reroll: [yellow]15', font = pixul_font, alignment = 'center'}}, global_text_tags) self.text = Text({{text = '[bg10]reroll: [yellow]10', font = pixul_font, alignment = 'center'}}, global_text_tags)
end end
end end
end end
@ -955,7 +950,7 @@ function RerollButton:update(dt)
system.save_run(self.parent.level, gold, self.parent.units, passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool_by_tiers, locked_state) system.save_run(self.parent.level, gold, self.parent.units, passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool_by_tiers, locked_state)
end end
elseif self.parent:is(Arena) then elseif self.parent:is(Arena) then
if gold < 15 and not self.free_reroll then if gold < 10 and not self.free_reroll then
self.spring:pull(0.2, 200, 10) self.spring:pull(0.2, 200, 10)
self.selected = true self.selected = true
error1:play{pitch = random:float(0.95, 1.05), volume = 0.5} error1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
@ -972,10 +967,10 @@ function RerollButton:update(dt)
self.parent:set_passives(true) self.parent:set_passives(true)
self.selected = true self.selected = true
self.spring:pull(0.2, 200, 10) self.spring:pull(0.2, 200, 10)
if not self.free_reroll then gold = gold - 15 end if not self.free_reroll then gold = gold - 10 end
self.parent.shop_text:set_text{{text = '[fg, nudge_down]gold: [yellow, nudge_down]' .. gold, font = pixul_font, alignment = 'center'}} self.parent.shop_text:set_text{{text = '[fg, nudge_down]gold: [yellow, nudge_down]' .. gold, font = pixul_font, alignment = 'center'}}
self.free_reroll = false self.free_reroll = false
self.text = Text({{text = '[bg10]reroll: [yellow]15', font = pixul_font, alignment = 'center'}}, global_text_tags) self.text = Text({{text = '[bg10]reroll: [yellow]10', font = pixul_font, alignment = 'center'}}, global_text_tags)
end end
end end
end end
@ -1004,7 +999,7 @@ function RerollButton:on_mouse_enter()
if self.free_reroll then if self.free_reroll then
self.text:set_text{{text = '[fgm5]reroll: 0', font = pixul_font, alignment = 'center'}} self.text:set_text{{text = '[fgm5]reroll: 0', font = pixul_font, alignment = 'center'}}
else else
self.text:set_text{{text = '[fgm5]reroll: 15', font = pixul_font, alignment = 'center'}} self.text:set_text{{text = '[fgm5]reroll: 10', font = pixul_font, alignment = 'center'}}
end end
end end
self.spring:pull(0.2, 200, 10) self.spring:pull(0.2, 200, 10)
@ -1018,7 +1013,7 @@ function RerollButton:on_mouse_exit()
if self.free_reroll then if self.free_reroll then
self.text:set_text{{text = '[fgm5]reroll: [yellow]0', font = pixul_font, alignment = 'center'}} self.text:set_text{{text = '[fgm5]reroll: [yellow]0', font = pixul_font, alignment = 'center'}}
else else
self.text:set_text{{text = '[fgm5]reroll: [yellow]15', font = pixul_font, alignment = 'center'}} self.text:set_text{{text = '[fgm5]reroll: [yellow]10', font = pixul_font, alignment = 'center'}}
end end
end end
self.selected = false self.selected = false
@ -1155,11 +1150,13 @@ function CharacterPart:update(dt)
table.remove(self.parent.units, self.i) table.remove(self.parent.units, self.i)
self:die() self:die()
self.parent:set_party_and_sets() self.parent:set_party_and_sets()
self.parent:refresh_cards()
else else
self.parent.parent:gain_gold(self:get_sale_price()) self.parent.parent:gain_gold(self:get_sale_price())
self.parent.parent.units[self.i].reserve[self.level] = self.parent.parent.units[self.i].reserve[self.level] - 1 self.parent.parent.units[self.i].reserve[self.level] = self.parent.parent.units[self.i].reserve[self.level] - 1
self:die() self:die()
self.parent.parent:set_party_and_sets() self.parent.parent:set_party_and_sets()
self.parent.parent:refresh_cards()
end end
end end
@ -1195,8 +1192,8 @@ function CharacterPart:on_mouse_enter()
self.spring:pull(0.2, 200, 10) self.spring:pull(0.2, 200, 10)
self.info_text = InfoText{group = main.current.ui, force_update = self.force_update} self.info_text = InfoText{group = main.current.ui, force_update = self.force_update}
self.info_text:activate({ self.info_text:activate({
{text = '[' .. character_color_strings[self.character] .. ']' .. self.character:capitalize() .. '[fg] - [yellow]Lv.' .. self.level .. '[fg] - sells for [yellow]' .. self:get_sale_price(), {text = '[' .. character_color_strings[self.character] .. ']' .. self.character:capitalize() .. '[fg] - [yellow]Lv.' .. self.level .. '[fg], tier [yellow]' .. character_tiers[self.character] .. '[fg] - sells for [yellow]' ..
font = pixul_font, alignment = 'center', height_multiplier = 1.25}, self:get_sale_price(), font = pixul_font, alignment = 'center', height_multiplier = 1.25},
{text = '[fg]Classes: ' .. character_class_strings[self.character], font = pixul_font, alignment = 'center', height_multiplier = 1.25}, {text = '[fg]Classes: ' .. character_class_strings[self.character], font = pixul_font, alignment = 'center', height_multiplier = 1.25},
{text = character_descriptions[self.character](self.level), font = pixul_font, alignment = 'center', height_multiplier = 2}, {text = character_descriptions[self.character](self.level), font = pixul_font, alignment = 'center', height_multiplier = 2},
{text = '[' .. (self.level == 3 and 'yellow' or 'light_bg') .. ']Lv.3 [' .. (self.level == 3 and 'fg' or 'light_bg') .. ']Effect - ' .. {text = '[' .. (self.level == 3 and 'yellow' or 'light_bg') .. ']Lv.3 [' .. (self.level == 3 and 'fg' or 'light_bg') .. ']Effect - ' ..
@ -1408,6 +1405,15 @@ function ItemCard:die()
end end
function BuyScreen:refresh_cards()
for i = 1, 3 do
if self.cards[i] then
self.cards[i]:refresh()
end
end
end
ShopCard = Object:extend() ShopCard = Object:extend()
ShopCard:implement(GameObject) ShopCard:implement(GameObject)
@ -1425,6 +1431,24 @@ function ShopCard:init(args)
end end
self.cost = character_tiers[self.unit] self.cost = character_tiers[self.unit]
self.spring:pull(0.2, 200, 10) self.spring:pull(0.2, 200, 10)
self:refresh()
end
function ShopCard:refresh()
self.owned = table.any(self.parent.units, function(v) return v.character == self.unit end)
if self.owned then
self.owned_n = 0
for _, unit in ipairs(self.parent.units) do
if unit.character == self.unit then
self.owned_n = self.owned_n + ((unit.level == 1 and 1) or (unit.level == 2 and 3) or (unit.level == 3 and 9))
if unit.reserve then
self.owned_n = self.owned_n + (unit.reserve[2] or 0)*3
self.owned_n = self.owned_n + (unit.reserve[1] or 0)
end
end
end
end
end end
@ -1437,6 +1461,7 @@ function ShopCard:update(dt)
_G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5} _G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
self:die() self:die()
self.parent.cards[self.i] = nil self.parent.cards[self.i] = nil
self.parent:refresh_cards()
system.save_run(self.parent.level == 1 and 0 or self.parent.level, gold, self.parent.units, passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool_by_tiers, locked_state) system.save_run(self.parent.level == 1 and 0 or self.parent.level, gold, self.parent.units, passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool_by_tiers, locked_state)
else else
error1:play{pitch = random:float(0.95, 1.05), volume = 0.5} error1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
@ -1475,6 +1500,36 @@ function ShopCard:draw()
if self.selected then if self.selected then
graphics.rectangle(self.x, self.y, self.w, self.h, 6, 6, bg[-1]) graphics.rectangle(self.x, self.y, self.w, self.h, 6, 6, bg[-1])
end end
if self.owned then
local x, y = self.x + self.w/5, self.y - self.h/2 + 12
if self.owned_n == 1 then
graphics.rectangle(x, y, 2, 2, nil, nil, character_colors[self.unit])
elseif self.owned_n == 2 then
graphics.rectangle(x, y, 2, 2, nil, nil, character_colors[self.unit])
graphics.rectangle(x + 4, y, 2, 2, nil, nil, character_colors[self.unit])
elseif self.owned_n == 3 then
graphics.rectangle(x, y, 4, 4, nil, nil, character_colors[self.unit])
elseif self.owned_n == 4 then
graphics.rectangle(x, y, 4, 4, nil, nil, character_colors[self.unit])
graphics.rectangle(x + 5, y, 2, 2, nil, nil, character_colors[self.unit])
elseif self.owned_n == 5 then
graphics.rectangle(x, y, 4, 4, nil, nil, character_colors[self.unit])
graphics.rectangle(x + 5, y, 2, 2, nil, nil, character_colors[self.unit])
graphics.rectangle(x + 9, y, 2, 2, nil, nil, character_colors[self.unit])
elseif self.owned_n == 6 then
graphics.rectangle(x, y, 4, 4, nil, nil, character_colors[self.unit])
graphics.rectangle(x + 6, y, 4, 4, nil, nil, character_colors[self.unit])
elseif self.owned_n == 7 then
graphics.rectangle(x, y, 4, 4, nil, nil, character_colors[self.unit])
graphics.rectangle(x + 6, y, 4, 4, nil, nil, character_colors[self.unit])
graphics.rectangle(x + 11, y, 2, 2, nil, nil, character_colors[self.unit])
elseif self.owned_n == 8 then
graphics.rectangle(x, y, 4, 4, nil, nil, character_colors[self.unit])
graphics.rectangle(x + 6, y, 4, 4, nil, nil, character_colors[self.unit])
graphics.rectangle(x + 11, y, 2, 2, nil, nil, character_colors[self.unit])
graphics.rectangle(x + 15, y, 2, 2, nil, nil, character_colors[self.unit])
end
end
graphics.pop() graphics.pop()
end end

View File

@ -517,6 +517,7 @@ function Seeker:hit(damage, projectile)
if self.jester_cursed then if self.jester_cursed then
trigger:after(0.01, function() trigger:after(0.01, function()
if tostring(self.x) == tostring(0/0) or tostring(self.y) == tostring(0/0) then return end
_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}
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6} HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6}
local r = random:float(0, 2*math.pi) local r = random:float(0, 2*math.pi)

View File

@ -554,7 +554,7 @@ function init()
['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]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, ['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]6[fg] nearby enemies for [yellow]6[fg] seconds, they will explode into [yellow]3[fg] knives on death" end, ['jester'] = function(lvl) return "[fg]curses [yellow]6[fg] nearby enemies for [yellow]6[fg] seconds, they will explode into [yellow]4[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' end, get_character_stat('assassin', lvl, 'dmg')/2 .. '[fg] damage per second' 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,
@ -1465,14 +1465,18 @@ function init()
--[[ --[[
main:add(Arena'arena') main:add(Arena'arena')
main:go_to('arena', 21, { main:go_to('arena', 25, {
{character = 'plague_doctor', level = 2},
{character = 'swordsman', level = 3}, {character = 'swordsman', level = 3},
{character = 'barbarian', level = 2}, {character = 'plague_doctor', level = 3},
{character = 'outlaw', level = 2}, {character = 'pyromancer', level = 3},
{character = 'warden', level = 2}, {character = 'witch', level = 3},
{character = 'juggernaut', level = 2}, {character = 'arcanist', level = 3},
{character = 'blade', level = 2}, {character = 'usurer', level = 3},
{character = 'warden', level = 3},
{character = 'silencer', level = 3},
{character = 'vulcanist', level = 3},
{character = 'bane', level = 3},
{character = 'illusionist', level = 3},
}, passives) }, passives)
]]-- ]]--
@ -1565,7 +1569,7 @@ function update(dt)
end end
--[[ --[[
if input.f12.pressed then if input.f11.pressed then
steam.userStats.resetAllStats(true) steam.userStats.resetAllStats(true)
steam.userStats.storeStats() steam.userStats.storeStats()
end end

View File

@ -232,13 +232,13 @@ function Unit:calculate_stats(first_run)
if current_new_game_plus == 0 then if current_new_game_plus == 0 then
if self.boss then if self.boss then
local x = self.level local x = self.level
local y = {0, 0, 3, 0, 0, 6, 0, 0, 9, 0, 0, 12, 0, 0, 18, 0, 0, 40, 0, 0, 32, 0, 0, 64, 96} local y = {0, 0, 3, 0, 0, 6, 0, 0, 9, 0, 0, 12, 0, 0, 18, 0, 0, 40, 0, 0, 32, 0, 0, 64, 90}
self.base_hp = 100 + (current_new_game_plus*5) + (90 + current_new_game_plus*10)*y[x] self.base_hp = 100 + (current_new_game_plus*5) + (90 + current_new_game_plus*10)*y[x]
self.base_dmg = (12 + current_new_game_plus*2) + (2 + current_new_game_plus)*y[x] self.base_dmg = (12 + current_new_game_plus*2) + (2 + current_new_game_plus)*y[x]
self.base_mvspd = 35 + 1.5*y[x] self.base_mvspd = 35 + 1.5*y[x]
if x == 25 then if x == 25 then
self.base_dmg = (12 + current_new_game_plus*2) + (1.25 + current_new_game_plus)*y[x] self.base_dmg = (12 + current_new_game_plus*2) + (1.25 + current_new_game_plus)*y[x]
self.base_mvspd = 35 + 1.2*y[x] self.base_mvspd = 35 + 1.1*y[x]
end end
else else
local x = self.level local x = self.level
@ -250,12 +250,12 @@ function Unit:calculate_stats(first_run)
else else
if self.boss then if self.boss then
local x = self.level local x = self.level
local y = {0, 0, 3, 0, 0, 6, 0, 0, 9, 0, 0, 12, 0, 0, 18, 0, 0, 40, 0, 0, 32, 0, 0, 64, 96} local y = {0, 0, 3, 0, 0, 6, 0, 0, 9, 0, 0, 12, 0, 0, 18, 0, 0, 40, 0, 0, 32, 0, 0, 64, 84}
self.base_hp = 100 + (current_new_game_plus*5) + (90 + current_new_game_plus*10)*y[x] self.base_hp = 100 + (current_new_game_plus*5) + (90 + current_new_game_plus*10)*y[x]
self.base_dmg = (12 + current_new_game_plus*2) + (2 + current_new_game_plus)*y[x] self.base_dmg = (12 + current_new_game_plus*2) + (2 + current_new_game_plus)*y[x]
self.base_mvspd = 35 + 1.5*y[x] self.base_mvspd = 35 + 1.5*y[x]
if x == 25 then if x == 25 then
self.base_dmg = (12 + current_new_game_plus*2) + (2 + 0.5*current_new_game_plus)*y[x] self.base_dmg = (12 + current_new_game_plus*2) + (1.75 + 0.5*current_new_game_plus)*y[x]
self.base_mvspd = 35 + 1.2*y[x] self.base_mvspd = 35 + 1.2*y[x]
end end
else else

View File

@ -1125,12 +1125,13 @@ function Player:update(dt)
if input.move_right.pressed and not self.move_left_pressed then self.move_right_pressed = love.timer.getTime() end if input.move_right.pressed and not self.move_left_pressed then self.move_right_pressed = love.timer.getTime() end
if input.move_left.released then self.move_left_pressed = nil end if input.move_left.released then self.move_left_pressed = nil end
if input.move_right.released then self.move_right_pressed = nil end if input.move_right.released then self.move_right_pressed = nil end
if input.move_left.down then self.r = self.r - 1.66*math.pi*dt end
if input.move_right.down then self.r = self.r + 1.66*math.pi*dt end
if state.mouse_control then if state.mouse_control then
local v = Vector(math.cos(self.r), math.sin(self.r)):perpendicular():dot(Vector(math.cos(self:angle_to_mouse()), math.sin(self:angle_to_mouse()))) local v = Vector(math.cos(self.r), math.sin(self.r)):perpendicular():dot(Vector(math.cos(self:angle_to_mouse()), math.sin(self:angle_to_mouse())))
self.r = self.r + math.sign(v)*1.66*math.pi*dt self.r = self.r + math.sign(v)*1.66*math.pi*dt
else
if input.move_left.down then self.r = self.r - 1.66*math.pi*dt end
if input.move_right.down then self.r = self.r + 1.66*math.pi*dt end
end end
local total_v = 0 local total_v = 0
@ -2521,6 +2522,7 @@ Volcano:implement(Physics)
function Volcano:init(args) function Volcano:init(args)
self:init_game_object(args) self:init_game_object(args)
if not self.group.world then self.dead = true; return end if not self.group.world then self.dead = true; return end
if tostring(self.x) == tostring(0/0) or tostring(self.y) == tostring(0/0) then self.dead = true; return end
self:set_as_rectangle(9, 9, 'static', 'player') self:set_as_rectangle(9, 9, 'static', 'player')
self:set_restitution(0.5) self:set_restitution(0.5)
self.hfx:add('hit', 1) self.hfx:add('hit', 1)
@ -2562,6 +2564,7 @@ end
function Volcano:draw() function Volcano:draw()
if self.hidden then return end if self.hidden then return end
if not self.hfx.hit then return end
graphics.push(self.x, self.y, math.pi/4, self.spring.x, self.spring.x) graphics.push(self.x, self.y, math.pi/4, self.spring.x, self.spring.x)
graphics.rectangle(self.x, self.y, 1.5*self.shape.w, 4, 2, 2, self.hfx.hit.f and fg[0] or self.color) graphics.rectangle(self.x, self.y, 1.5*self.shape.w, 4, 2, 2, self.hfx.hit.f and fg[0] or self.color)
@ -2670,6 +2673,7 @@ end
function Pet:draw() function Pet:draw()
if not self.hfx.hit then return end
graphics.push(self.x, self.y, self.r, self.hfx.hit.x, self.hfx.hit.x) graphics.push(self.x, self.y, self.r, self.hfx.hit.x, self.hfx.hit.x)
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 3, 3, self.hfx.hit.f and fg[0] or self.color) graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 3, 3, self.hfx.hit.f and fg[0] or self.color)
graphics.pop() graphics.pop()
@ -2876,6 +2880,7 @@ Gold:implement(GameObject)
Gold:implement(Physics) Gold:implement(Physics)
function Gold:init(args) function Gold:init(args)
self:init_game_object(args) self:init_game_object(args)
if tostring(self.x) == tostring(0/0) or tostring(self.y) == tostring(0/0) then self.dead = true; return end
self:set_as_rectangle(3, 3, 'dynamic', 'ghost') self:set_as_rectangle(3, 3, 'dynamic', 'ghost')
self:set_restitution(0.5) self:set_restitution(0.5)
local r = random:float(0, 2*math.pi) local r = random:float(0, 2*math.pi)
@ -2897,6 +2902,7 @@ end
function Gold:draw() function Gold:draw()
if not self.hfx.hit then return end
graphics.push(self.x, self.y, self.r, self.hfx.hit.x, self.hfx.hit.x) graphics.push(self.x, self.y, self.r, self.hfx.hit.x, self.hfx.hit.x)
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 1, 1, self.hfx.hit.f and fg[0] or self.color) graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 1, 1, self.hfx.hit.f and fg[0] or self.color)
graphics.pop() graphics.pop()
@ -2920,6 +2926,7 @@ function Gold:on_trigger_enter(other, contact)
if th then if th then
if th.level == 3 then if th.level == 3 then
trigger:after(0.01, function() trigger:after(0.01, function()
if not main.current.main.world then return end
_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}
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6} HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6}
local r = random:float(0, 2*math.pi) local r = random:float(0, 2*math.pi)
@ -2931,6 +2938,7 @@ function Gold:on_trigger_enter(other, contact)
end) end)
else else
trigger:after(0.01, function() trigger:after(0.01, function()
if not main.current.main.world then return end
_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}
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6} HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6}
local r = random:float(0, 2*math.pi) local r = random:float(0, 2*math.pi)
@ -3004,6 +3012,7 @@ end
function Critter:draw() function Critter:draw()
if not self.hfx.hit then return end
graphics.push(self.x, self.y, self.r, self.hfx.hit.x, self.hfx.hit.x) graphics.push(self.x, self.y, self.r, self.hfx.hit.x, self.hfx.hit.x)
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 2, 2, self.hfx.hit.f and fg[0] or self.color) graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 2, 2, self.hfx.hit.f and fg[0] or self.color)
graphics.pop() graphics.pop()

132
todo
View File

@ -1,89 +1,69 @@
Shop Update Item Update
New units
* Mercenaries (2/4) - +10/20% chance for enemies to drop gold on death
* Miner (tier 1 mercenary) - picking up gold releases 4 homing projectiles that deal X damage, Lv.3 - release 8 homing projectiles instead and they pierce twice
* Merchant (tier 2 mercenary) - gain +1 interest for every 10 gold, Lv.3 - your first item reroll is always free
* Usurer (tier 3 curser, mercenary, voider) - curses 3 nearby enemies indefinitely with debt, dealing X damage over time, Lv.3 - if the same enemy is cursed 3 times it takes 50X damage
* Gambler (tier 3 mercenary, sorcerer) - deal 2X damage to a single random enemy where X is how much gold you have, Lv.3 effect - 60%/40%/20% chance to cast the attack 2/3/4 times
* Thief (tier 4 mercenary, rogue) - throws a knife that deals 2X damage and chains 5 times, Lv.3 - if the knife crits it deals 10X damage, chains 10 times and grants 1 gold
Shop changes
* Shop level up
* Shop level visual
* Shop level up button
* Level up logic
* Level probabilities
* Hook probabilities into reroll
Item changes
* Sorcerer items
Unit changes
* Launcher - removed
* Jester - changed to 4 projectiles
Misc additions and changes
* Added sorcerer achievement
* Added mercenary achievement
QoL
* Removed restart button from end screen
* First item reroll is now free
* Gold is given right after the round ends in the arena rather than on the shop for easier item rerolls
* Added mouse follow control mode
* The cursor is now invisible during waves, unless mouse follow mode is enabled
* Added visuals for tank attack
Balance
* Decreased level 25 boss movement speed
* Change headbutters so they're less likely to kill multiple units at once
Bug fixes
* Fixed a crash when too many illusions would be spawned in short succession
* Fixed a bug where enemy critters would sometimes be unkillable
* Fixed a rare crash involving broken enemy critter state
* Fixed text for the illusionist's Lv.3 effect going outside the screen
* Fixed a crash when hovering over the Lich in the shop due to playing with a save before the sorcerer update
* Fixed a crash when warden's force field would spawn on top of enemies
* Fixed a crash when a volcano would spawn on top of enemies
* Fixed a crash when a pet would spawn on top of enemies
* Fixed a bug where the maximum number of units would be wrong on certain conditions
* Fixed a crash when clicking too fast after unpausing the game
* Fixed unit highlight when hovering over classes
* Fixed Lv.3 plague doctor moving all his created areas with him
* Fixed a bug where quitting on level 2 would go back to level 1
Sacrifice Update
New mechanics New mechanics
Sacrifice units to level items up Sacrifice units to level items up
Items
New items New items
https://steamcommunity.com/app/915310/discussions/0/3106901028662504698/ Position X has +Y% attack speed
Position X has +Y% damage
Position X is 1 tier higher
Position X is also class Y
When a unit dies it explodes, launching enemies away
When a unit dies it explodes, releasing piercing projectiles
Reworked items Reworked items
Items shouldn't just be more powerful versions of other items Items shouldn't just be more powerful versions of other items
Items should have drawbacks Items should have drawbacks
Items that apply to a position on the snake (a good middle step between applying them to individual units like in Underlords) Items that apply to a position on the snake (a good middle step between applying them to individual units like in Underlords)
Item discussions
https://steamcommunity.com/app/915310/discussions/0/3106901028662504698/
https://steamcommunity.com/app/915310/discussions/0/3106901665846294204/
https://steamcommunity.com/app/915310/discussions/0/4658391921151238820/
https://i.imgur.com/cfIyMBL.png
Balance
* Decreased shop reroll cost to 10
Decrease mercenary gold drop chance to 8/16% (from 10/20%)
QoL QoL
Current items visible on item selection screen Current snake/items visible on item selection screen
Endless mode
Volume slider Volume slider
Add visuals for defensive ouroboros, divine intervention, fairy buff Add visuals for defensive ouroboros, divine intervention, fairy buff
Options menu from buy screen Options menu from buy screen
https://i.imgur.com/JJUddT3.png
Improve volcano to not look like spawn marker - https://i.imgur.com/HuS15HG.png
Add option for mouse cursor to always be visible
Add main menu
Soundtrack button
Discord button
Arena run button
Options button
Quit button
* Added tier text to characters on the shop screen
* Added shop unit highlights/markers to make it easier to tell when you already own something
* Added unit names to the "your build" section of the end game screen
Bug fixes Bug fixes
Fix fullscreen with different resolutions that don't scale properly Fix fullscreen with different resolutions that don't scale properly - https://steamcommunity.com/app/915310/discussions/0/3106901665841020282/
Fix enemies still spawning after arena clear (this happens with the extra enemy spawns that were blocked earlier) Fix enemies still spawning after arena clear (this happens with the extra enemy spawns that were blocked earlier)
https://i.imgur.com/ieVqYNI.png * Fixed a bug where passives would sometimes disappear from a run?
https://i.imgur.com/3JCeFuZ.png * Fixed a bug where clicking "window size-" too many times could bug out the game
* Fixed a bug where the shop would be rerolled after quitting in the arena
* Fixed multiple bugs related to locking the shop and quitting
* Fixed a bug where units could be duplicated in the shop by locking and quitting the game at certain steps
* Fixed a bug where quitting on level 2 would go back to level 1 shop (again)
* Fixed a bug where mouse cursor wasn't visible on death
* Fixed a bug where NG+ level wasn't increased when the game is beaten but only when the NG+ button was clicked
* Fixed a bug where level 2 and level 3 achievements (win with only level 2/3 units) were not triggering correctly sometimes
* Fixed a bug where shop level wasn't respected on the shop's first roll
* Fixed multiple crashes that would happen when picking up gold
* Fixed a crash when the jester's curse would trigger
* Fixed a crash when gold would be picked up with a Miner in the party
* Fixed a crash involving broken state for Pets, Critters or Volcanos
* Fixed a crash that happened after rerolling items too many times
Melee Update
New Units
Guardians - https://i.imgur.com/Ynu5Cdw.png
Assists (2/4) -
Ringmaster (tier 4 assist, nuker) - +15% to all stats to adjacent units, Lv.3 effect - create a cross that deals AoE damage 5 times for 10 seconds
Absorber (tier 2 assist, warrior) - absorbs 50% damage from adjacent units, Lv.3 effect - absorbs 75% damage from adjacent units and gives the absorber +25% defense
Pardoner (tier 3 assist, mercenary) -
Oracle (tier 1 assist) - +10% dodge chance to adjacent units, Lv.3 effect - +20% dodge chance to adjacent units
Seraph (tier 2 assist, healer) - periodically chooses 1 random unit and gives it +100% defense for 6 seconds, Lv.3 - choose 2 units instead
Endless Update
Endless mode
Units die permanently when they die
Slower scaling with less individually threatening units
Max snake size goes up every 10 levels
--- ---
@ -95,6 +75,13 @@ Trappers:
Brawlers: units focused on crashing on enemies Brawlers: units focused on crashing on enemies
https://i.imgur.com/5YubukS.png - unit idea https://i.imgur.com/5YubukS.png - unit idea
Conjurer unit that creates an unit that actively protects you from enemy projectiles Conjurer unit that creates an unit that actively protects you from enemy projectiles
Guardians - https://i.imgur.com/Ynu5Cdw.png
Assists (2/4) -
Ringmaster (tier 4 assist, nuker) - +15% to all stats to adjacent units, Lv.3 effect - create a cross that deals AoE damage 5 times for 10 seconds
Absorber (tier 2 assist, warrior) - absorbs 50% damage from adjacent units, Lv.3 effect - absorbs 75% damage from adjacent units and gives the absorber +25% defense
Pardoner (tier 3 assist, mercenary) -
Oracle (tier 1 assist) - +10% dodge chance to adjacent units, Lv.3 effect - +20% dodge chance to adjacent units
Seraph (tier 2 assist, healer) - periodically chooses 1 random unit and gives it +100% defense for 6 seconds, Lv.3 - choose 2 units instead
Passive that makes critters and summons block enemy projectiles Passive that makes critters and summons block enemy projectiles
Hexblaster? - curser that consumes curses to deal damage Hexblaster? - curser that consumes curses to deal damage
Bench? - https://i.imgur.com/B1gNVKk.png Bench? - https://i.imgur.com/B1gNVKk.png
@ -120,13 +107,14 @@ Roguelite update:
Tavern (heal units) Tavern (heal units)
Challenge + reward Challenge + reward
Go through the labyrinth without hitting any walls Go through the labyrinth without hitting any walls
Go through the traps without getting hit
Units die permanently when they die (dead units can be stored in bench to be revived later) Units die permanently when they die (dead units can be stored in bench to be revived later)
Units can have items attached to them like in Underlords Units can have items attached to them like in Underlords
Unit item ideas: Unit item ideas:
This unit's projectiles pierce/chain/fork/seek/split/stun/etc This unit's projectiles pierce/chain/fork/seek/split/stun/etc
This unit is a [class] This unit is a [class]
New stat system: New stat system:
All stats are values from 1 to 10 (can be lower than 1 or higher than due to debuffs/buffs only) that represent consistent internal values between all units All stats are values from 1 to 10 (can be lower than 1 or higher than 10 due to debuffs/buffs only) that represent consistent internal values between all units
i.e. 3 attack speed means the same internal attack rate value (like say 6 seconds) for the entire game i.e. 3 attack speed means the same internal attack rate value (like say 6 seconds) for the entire game
In general it's better if units don't have hidden internal multipliers on these stats, although sometimes that may be inevitable In general it's better if units don't have hidden internal multipliers on these stats, although sometimes that may be inevitable
Damage: Damage: