From 37682d89b052aae729d1b961c0eedc800111edb5 Mon Sep 17 00:00:00 2001 From: a327ex Date: Fri, 11 Jun 2021 07:43:15 -0300 Subject: [PATCH] Shop update 5/5 --- assets/media/achievement_mercenaries_win.png | Bin 0 -> 2182 bytes assets/media/mercenary_cover.png | Bin 0 -> 6783 bytes buy_screen.lua | 101 +++++++++++-------- enemies.lua | 10 +- engine/system.lua | 4 +- main.lua | 66 ++++++------ media.lua | 6 +- player.lua | 12 +-- todo | 33 +++--- 9 files changed, 126 insertions(+), 106 deletions(-) create mode 100644 assets/media/achievement_mercenaries_win.png create mode 100644 assets/media/mercenary_cover.png diff --git a/assets/media/achievement_mercenaries_win.png b/assets/media/achievement_mercenaries_win.png new file mode 100644 index 0000000000000000000000000000000000000000..75ab2bf3753969e4d7d0d5ca7ddc34f7033c0098 GIT binary patch literal 2182 zcma)8YgAKL7Cx6iKp;ZLA_G){byex$BNY(@fgp^C8V0C<4-qhWZ}gpi4R6TJ{|eAF0d@OvbNzs#w|#!yGCP-_wvtb^?J`cecsVut3k$l+B1AtpH8}#>q+&>JLO$$F19(W(*1MHhK+%Ipae>7PNwm#AwCh> zOns-{AlP4NCy!#uug5G5$kdX^Y0}2IeoK$O98zsAJ+gxyyOL#-W>yzi*nsTTEUK0p z@Hx$_>t8iK{<1%yJNuWci87)>*MNXDV}6O$CN_n-Y? zkYq_$(Yn}Tln87yB;swA!Dc&0z|i0@i46Qtz}hz0s=JS15_Z3C7IPVbGA`p-e7lt! zL*Yp6lb7;xeRuZ%iyk|Tx+bpg5ztD%h!2F!?2Le?Y`6e>vzmq6RzS1P{^m+1S{Ic8%WpYZH!dJ1P%g8a3U+YR*Y z?RWXfC*sm%wR_9Gvu^Tf?$}_JHQEpa=PZ2J3#J1q4*UW`11W=`K2X8+&t5*i53B#^ z?xLi?$3>{7>K{ISU0eImm-{FE+%1%3j8GVa7u23`-#R2}hUGm7M!0vD?ky+!I?@&C zv>)(u1Hk78X-XH`vkXj5zVh5o54l8^)Dp^Cj?l}XcGO_mRoo;a-l9oVdB@^Sxjny4 zt9_JzuvSZ>cMc7q=n$+)TZkk^^dDfrILZOBeAdhOz@YJJRj(NCb}%HEd|x|F>vz$; zptu`EZbIs+f8kVwLP}wFkJ*m*imhOdN@V`9SYVz%aBJImkYHLTk$3dA=>_#ZjNtiq z;#rTp|2-?-M3;F#$IMY$$|K>Jc*7xv*B3`@h0o+ESgirS%TZJb`2+SoR8k3He~qz7 zmH1ksh-_P+e`m#H&MKFcI$5Pw$EAsBIcGYSbnR{a+e;6j(!HW8Kp2F&u{6ZXh}j|7 zJ3nW)ssz<)Jn^{9hry{*n<%Mb9tlr$H-r-MxvQQ4c~OH689L?0*sEA~UQg9#FP^Jg zq)Jjg#mscSfqbH=*9X;rjyw8#d!k>8`|_BEhd)f_bF|t@8Pq7v>D`_Z4<9cL-WQl+0AZ@Zbe0fjfWCa*PiGeX9Y`K zkUCIfjB<&1N7Kvm`1wN=RLT|-ZqJqzQLr$LG@)sTC^L`>8k03me9rW;f3#|o26(=4 zf7O+ag}X(-+$9>5utQ)z{~#oS>SmY;Eg0t});i*7jo10A3We-#M21NQzaNdnIbC=Y zMYupdj9lH}?bh)TsUeZpwewe%m24#*Suo0s{q4EAGR)8#3gpj~n;~f479pZ=fl=m( w|7VjpZ!OcAXAx2&Hks-E&9VDaTl$pVp@35m6JU1%{yTu6KL-ai@1dOk58K?9)&Kwi literal 0 HcmV?d00001 diff --git a/assets/media/mercenary_cover.png b/assets/media/mercenary_cover.png new file mode 100644 index 0000000000000000000000000000000000000000..f5864a9717a3f10ae6f4379d07e4dbe677ef7a4a GIT binary patch literal 6783 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 self.max_xp then self.shop_xp = 0 self.parent.shop_level = self.parent.shop_level + 1 - self.max_xp = (self.parent.shop_level == 1 and 3) or (self.parent.shop_level == 2 and 4) or (self.parent.shop_level == 3 and 5) or (self.parent.shop_level == 4 or 6) or (self.parent.shop_level == 5 or 0) - - -- Reload info text - if self.info_text then - self.info_text:deactivate() - self.info_text.dead = true - end - self.info_text = nil - local t11, t12 = get_shop_odds(self.parent.shop_level, 1), get_shop_odds(self.parent.shop_level+1, 1) - local t21, t22 = get_shop_odds(self.parent.shop_level, 2), get_shop_odds(self.parent.shop_level+1, 2) - local t31, t32 = get_shop_odds(self.parent.shop_level, 3), get_shop_odds(self.parent.shop_level+1, 3) - local t41, t42 = get_shop_odds(self.parent.shop_level, 4), get_shop_odds(self.parent.shop_level+1, 4) - self.info_text = InfoText{group = main.current.ui} - self.info_text:activate({ - {text = '[yellow]Lv.' .. self.parent.shop_level .. '[fg] shop, XP: [yellow]' .. self.parent.shop_xp .. '/' .. self.max_xp, font = pixul_font, alignment = 'center', height_multiplier = 1.5}, - {text = '[bg10]chances of units appearing on the shop', font = pixul_font, alignment = 'center', height_multiplier = 1.25}, - {text = '[yellow]current shop level [fgm10]next shop level', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, - {text = '[fg]tier 1: ' .. t11 .. '%' .. tostring(t11 < 10 and ' ' or '') .. ' [fgm8]tier 1: ' .. t12 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, - {text = '[green]tier 2: ' .. t21 .. '%' .. tostring(t21 < 10 and ' ' or '') .. ' [fgm6]tier 2: ' .. t22 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, - {text = '[blue]tier 3: ' .. t31 .. '%' .. tostring(t31 < 10 and ' ' or '') .. ' [fgm4]tier 3: ' .. t32 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, - {text = '[purple]tier 4: ' .. t41 .. '%' .. tostring(t41 < 10 and ' ' or '') .. ' [fgm2]tier 4: ' .. t42 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, - }, nil, nil, nil, nil, 16, 4, nil, 2) - self.info_text.x, self.info_text.y = gw/2, gh/2 - 45 + self.max_xp = (self.parent.shop_level == 1 and 3) or (self.parent.shop_level == 2 and 4) or (self.parent.shop_level == 3 and 5) or (self.parent.shop_level == 4 and 6) or (self.parent.shop_level == 5 and 0) end self.parent.shop_xp = self.shop_xp + self:create_info_text() self.selected = true self.spring:pull(0.2, 200, 10) gold = gold - 5 - 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 = '[wavy_mid, fg]shop [fg]- [fg, nudge_down]gold: [yellow, nudge_down]' .. gold, font = pixul_font, alignment = 'center'}} self.text = Text({{text = '[bg10]' .. tostring(self.parent.shop_level), font = pixul_font, alignment = 'center'}}, global_text_tags) + 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 end @@ -862,28 +842,55 @@ function LevelButton:draw() end +function LevelButton:create_info_text() + if self.info_text then + self.info_text:deactivate() + self.info_text.dead = true + end + self.info_text = nil + if self.parent.shop_level < 5 then + local t11, t12 = get_shop_odds(self.parent.shop_level, 1), get_shop_odds(self.parent.shop_level+1, 1) + local t21, t22 = get_shop_odds(self.parent.shop_level, 2), get_shop_odds(self.parent.shop_level+1, 2) + local t31, t32 = get_shop_odds(self.parent.shop_level, 3), get_shop_odds(self.parent.shop_level+1, 3) + local t41, t42 = get_shop_odds(self.parent.shop_level, 4), get_shop_odds(self.parent.shop_level+1, 4) + self.info_text = InfoText{group = main.current.ui} + self.info_text:activate({ + {text = '[yellow]Lv.' .. self.parent.shop_level .. '[fg] shop, XP: [yellow]' .. self.shop_xp .. '/' .. self.max_xp, font = pixul_font, alignment = 'center', height_multiplier = 1.5}, + {text = '[bg10]chances of units appearing on the shop', font = pixul_font, alignment = 'center', height_multiplier = 1.25}, + {text = '[yellow]current shop level [fgm10]next shop level', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, + {text = '[fg]tier 1: ' .. t11 .. '%' .. tostring(t11 < 10 and ' ' or '') .. ' [fgm8]tier 1: ' .. t12 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, + {text = '[green]tier 2: ' .. t21 .. '%' .. tostring(t21 < 10 and ' ' or '') .. ' [fgm6]tier 2: ' .. t22 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, + {text = '[blue]tier 3: ' .. t31 .. '%' .. tostring(t31 < 10 and ' ' or '') .. ' [fgm4]tier 3: ' .. t32 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, + {text = '[purple]tier 4: ' .. t41 .. '%' .. tostring(t41 < 10 and ' ' or '') .. ' [fgm2]tier 4: ' .. t42 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, + }, nil, nil, nil, nil, 16, 4, nil, 2) + self.info_text.x, self.info_text.y = gw/2, gh/2 - 45 + elseif self.parent.shop_level == 5 then + local t11 = get_shop_odds(self.parent.shop_level, 1) + local t21 = get_shop_odds(self.parent.shop_level, 2) + local t31 = get_shop_odds(self.parent.shop_level, 3) + local t41 = get_shop_odds(self.parent.shop_level, 4) + self.info_text = InfoText{group = main.current.ui} + self.info_text:activate({ + {text = '[yellow]Lv.' .. self.parent.shop_level .. '[fg] shop, XP: [yellow]' .. self.shop_xp .. '/' .. self.max_xp, font = pixul_font, alignment = 'center', height_multiplier = 1.5}, + {text = '[bg10]chances of units appearing on the shop', font = pixul_font, alignment = 'center', height_multiplier = 1.25}, + {text = '[yellow]current shop level', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, + {text = '[fg]tier 1: ' .. t11 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, + {text = '[green]tier 2: ' .. t21 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, + {text = '[blue]tier 3: ' .. t31 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, + {text = '[purple]tier 4: ' .. t41 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, + }, nil, nil, nil, nil, 16, 4, nil, 2) + self.info_text.x, self.info_text.y = gw/2, gh/2 - 45 + end +end + + function LevelButton: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.shop_level), font = pixul_font, alignment = 'center'}} self.spring:pull(0.2, 200, 10) - - local t11, t12 = get_shop_odds(self.parent.shop_level, 1), get_shop_odds(self.parent.shop_level+1, 1) - local t21, t22 = get_shop_odds(self.parent.shop_level, 2), get_shop_odds(self.parent.shop_level+1, 2) - local t31, t32 = get_shop_odds(self.parent.shop_level, 3), get_shop_odds(self.parent.shop_level+1, 3) - local t41, t42 = get_shop_odds(self.parent.shop_level, 4), get_shop_odds(self.parent.shop_level+1, 4) - self.info_text = InfoText{group = main.current.ui} - self.info_text:activate({ - {text = '[yellow]Lv.' .. self.parent.shop_level .. '[fg] shop, XP: [yellow]' .. self.parent.shop_xp .. '/' .. self.max_xp, font = pixul_font, alignment = 'center', height_multiplier = 1.5}, - {text = '[bg10]chances of units appearing on the shop', font = pixul_font, alignment = 'center', height_multiplier = 1.25}, - {text = '[yellow]current shop level [fgm10]next shop level', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, - {text = '[fg]tier 1: ' .. t11 .. '%' .. tostring(t11 < 10 and ' ' or '') .. ' [fgm8]tier 1: ' .. t12 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, - {text = '[green]tier 2: ' .. t21 .. '%' .. tostring(t21 < 10 and ' ' or '') .. ' [fgm6]tier 2: ' .. t22 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, - {text = '[blue]tier 3: ' .. t31 .. '%' .. tostring(t31 < 10 and ' ' or '') .. ' [fgm4]tier 3: ' .. t32 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, - {text = '[purple]tier 4: ' .. t41 .. '%' .. tostring(t41 < 10 and ' ' or '') .. ' [fgm2]tier 4: ' .. t42 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, - }, nil, nil, nil, nil, 16, 4, nil, 2) - self.info_text.x, self.info_text.y = gw/2, gh/2 - 45 + self:create_info_text() end @@ -945,7 +952,7 @@ function RerollButton:update(dt) self.spring:pull(0.2, 200, 10) gold = gold - 2 self.parent.shop_text:set_text{{text = '[wavy_mid, fg]shop [fg]- [fg, nudge_down]gold: [yellow, nudge_down]' .. gold, font = pixul_font, alignment = 'center'}} - 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, gold, self.parent.units, passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool_by_tiers, locked_state) end elseif self.parent:is(Arena) then if gold < 15 and not self.free_reroll then @@ -1171,8 +1178,8 @@ function CharacterPart:draw(y) graphics.print_centered(self.level, pixul_font, self.x + 0.5, self.y + 2, 0, 1, 1, 0, 0, bg[10]) ]]-- else - graphics.rectangle(self.x, self.y, 14, 14, 3, 3, self.highlighted and fg[0] or character_colors[self.character]) - graphics.print_centered(self.level, pixul_font, self.x + 0.5, self.y + 2, 0, 1, 1, 0, 0, self.highlighted and fg[-5] or _G[character_color_strings[self.character]][-5]) + graphics.rectangle(self.x, self.y, 14, 14, 3, 3, self.highlighted and bg[10] or character_colors[self.character]) + graphics.print_centered(self.level, pixul_font, self.x + 0.5, self.y + 2, 0, 1, 1, 0, 0, self.highlighted and bg[5] or _G[character_color_strings[self.character]][-5]) end if y then graphics.rectangle(self.x, y, 14, 14, 3, 3, bg[5]) @@ -1783,6 +1790,9 @@ function ClassIcon:on_mouse_enter() for _, character in ipairs(self.parent.characters) do if table.any(character_classes[character.character], function(v) return v == self.class end) then character:highlight() + for _, c in ipairs(character.parts) do + c:highlight() + end end end end @@ -1800,6 +1810,9 @@ function ClassIcon:on_mouse_exit() for _, character in ipairs(self.parent.characters) do if table.any(character_classes[character.character], function(v) return v == self.class end) then character:unhighlight() + for _, c in ipairs(character.parts) do + c:unhighlight() + end end end end diff --git a/enemies.lua b/enemies.lua index 6ff1211..1e15ca8 100644 --- a/enemies.lua +++ b/enemies.lua @@ -66,7 +66,9 @@ function Seeker:init(args) end, function() wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.5} local enemies = self:get_objects_in_shape(self.pull_sensor, main.current.enemies) + HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = yellow[0], duration = 0.1} for _, enemy in ipairs(enemies) do + LightningLine{group = main.current.effects, src = self, dst = enemy, color = yellow[0]} enemy:push(random:float(40, 80), enemy:angle_to_object(main.current.player), true) end self.px, self.py = nil, nil @@ -213,6 +215,8 @@ function Seeker:init(args) local enemy = self:get_closest_object_in_shape(Circle(self.x, self.y, 128), main.current.enemies) if enemy then wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.5} + 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]} enemy:push(random:float(40, 80), enemy:angle_to_object(main.current.player), true) end end) @@ -396,7 +400,7 @@ function Seeker:on_collision_enter(other, contact) HitCircle{group = main.current.effects, x = x, y = y, rs = 6, color = fg[0], duration = 0.1} for i = 1, 2 do HitParticle{group = main.current.effects, x = x, y = y, color = self.color} end hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35} - if other:is(Seeker) then self.headbutting = false end + if other:is(Seeker) or other:is(Player) then self.headbutting = false end end elseif other:is(Turret) then @@ -516,11 +520,11 @@ function Seeker:hit(damage, projectile) _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 + for i = 1, 4 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 + r = r + math.pi/2 end end) end diff --git a/engine/system.lua b/engine/system.lua index 9d9d048..3467b6c 100644 --- a/engine/system.lua +++ b/engine/system.lua @@ -140,12 +140,12 @@ end function system.save_run(level, gold, units, passives, shop_level, shop_xp, run_passive_pool_by_tiers, locked_state) local run = {level = level, gold = gold, units = units, passives = passives, shop_level = shop_level, shop_xp = shop_xp, run_passive_pool_by_tiers = run_passive_pool_by_tiers, locked_state = locked_state} local str = "return " .. table.tostring(run) - love.filesystem.write("run.txt", str) + love.filesystem.write("run_v2.txt", str) end function system.load_run() - local chunk = love.filesystem.load("run.txt") + local chunk = love.filesystem.load("run_v2.txt") if chunk then return chunk() else return {} end end diff --git a/main.lua b/main.lua index f01f047..495e167 100644 --- a/main.lua +++ b/main.lua @@ -502,7 +502,7 @@ function init() ['psychic'] = '[blue2]Sorcerer, [fg]Psyker', ['miner'] = '[yellow2]Mercenary', ['merchant'] = '[yellow2]Mercenary', - ['usurer'] = '[purple]Curser, [yellow2]Mercenary, [purple]Curser', + ['usurer'] = '[purple]Curser, [yellow2]Mercenary, [purple]Voider', ['gambler'] = '[yellow2]Mercenary, [blue2]Sorcerer', ['thief'] = '[red]Rogue, [yellow2]Mercenary', } @@ -569,7 +569,7 @@ function init() ['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, ['arcanist'] = function(lvl) return '[fg]launches a slow moving orb that launches projectiles, each dealing [yellow]' .. get_character_stat('arcanist', lvl, 'dmg') .. '[fg] damage' end, ['illusionist'] = function(lvl) return '[fg]launches a projectile that deals [yellow]' .. get_character_stat('illusionist', lvl, 'dmg') .. '[fg] damage and creates copies that do the same' end, - ['witch'] = function(lvl) return '[fg]creates an area that ricochets around the arena and deals [yellow]' .. get_character_stat('witch', lvl, 'dmg') .. '[fg] damage per second' end, + ['witch'] = function(lvl) return '[fg]creates an area that ricochets and deals [yellow]' .. get_character_stat('witch', lvl, 'dmg') .. '[fg] damage per second' end, ['silencer'] = function(lvl) return '[fg]curses [yellow]5[fg] nearby enemies for [yellow]6[fg] seconds, preventing them from using special attacks' end, ['vulcanist'] = function(lvl) return '[fg]creates a volcano that explodes the nearby area [yellow]4[fg] times, dealing [yellow]' .. get_character_stat('vulcanist', lvl, 'dmg') .. ' AoE [fg]damage' end, ['warden'] = function(lvl) return '[fg]creates a force field around a random unit that prevents enemies from entering' end, @@ -740,7 +740,7 @@ function init() ['flagellant'] = function() return '[fg]deals [yellow]' .. 2*get_character_stat('flagellant', 3, 'dmg') .. '[fg] damage to all allies and grants [yellow]+12%[fg] damage to all allies per cast' end, ['arcanist'] = function() return '[yellow]+50%[fg] attack speed for the orb and [yellow]2[fg] projectiles are released per cast' end, ['illusionist'] = function() return '[yellow]doubles[fg] the number of copies created and they release [yellow]12[fg] projectiles on death' end, - ['witch'] = function() return '[fg]the area periodically releases projectiles, each dealing [yellow]' .. get_character_stat('witch', 3, 'dmg') .. '[fg] damage and chaining once' end, + ['witch'] = function() return '[fg]the area releases projectiles, each dealing [yellow]' .. get_character_stat('witch', 3, 'dmg') .. '[fg] damage and chaining once' end, ['silencer'] = function() return '[fg]the curse also deals [yellow]' .. get_character_stat('silencer', 3, 'dmg') .. '[fg] damage per second' end, ['vulcanist'] = function() return '[fg]the number and speed of explosions is [yellow]doubled[fg]' end, ['warden'] = function() return '[fg]creates the force field around [yellow]2[fg] units' end, @@ -806,7 +806,7 @@ function init() ['merchant'] = function() return '[light_bg]your first item reroll is always free' end, ['usurer'] = function() return '[light_bg]if the same enemy is cursed 3 times it takes ' .. 10*get_character_stat('usurer', 3, 'dmg') .. ' damage' end, ['gambler'] = function() return '[light_bg]60/40/20% chance to cast the attack 2/3/4 times' end, - ['thief'] = function() return '[light_bg]if the coin crits it deals ' .. 10*get_character_stat('thief', 3, 'dmg') .. ' damage, chains 10 times and grants 1 gold' end, + ['thief'] = function() return '[light_bg]if the knife crits it deals ' .. 10*get_character_stat('thief', 3, 'dmg') .. ' damage, chains 10 times and grants 1 gold' end, } character_stats = { @@ -925,7 +925,7 @@ function init() tier_to_characters = { [1] = {'vagrant', 'swordsman', 'magician', 'archer', 'scout', 'cleric', 'arcanist', 'miner'}, - [2] = {'wizard', 'saboteur', 'sage', 'squire', 'dual_gunner', 'hunter', 'chronomancer', 'barbarian', 'cryomancer', 'beastmaster', 'launcher', 'jester', 'carver', 'psychic', 'witch', 'silencer', 'outlaw', 'merchant'}, + [2] = {'wizard', 'saboteur', 'sage', 'squire', 'dual_gunner', 'hunter', 'chronomancer', 'barbarian', 'cryomancer', 'beastmaster', 'jester', 'carver', 'psychic', 'witch', 'silencer', 'outlaw', 'merchant'}, [3] = {'elementor', 'stormweaver', 'spellblade', 'psykeeper', 'engineer', 'juggernaut', 'pyromancer', 'host', 'assassin', 'bane', 'barrager', 'infestor', 'flagellant', 'illusionist', 'usurer', 'gambler'}, [4] = {'priest', 'highlander', 'psykino', 'fairy', 'blade', 'plague_doctor', 'cannoneer', 'vulcanist', 'warden', 'corruptor', 'thief'}, } @@ -963,7 +963,7 @@ function init() ['pyromancer'] = 3, ['corruptor'] = 4, ['beastmaster'] = 2, - ['launcher'] = 2, + -- ['launcher'] = 2, ['jester'] = 2, ['assassin'] = 3, ['host'] = 3, @@ -1156,9 +1156,9 @@ function init() ['blunt_arrow'] = '[fg]all arrows fired by rangers have a [yellow]20%[fg] chance to knockback', ['explosive_arrow'] = '[fg]arrows fired by rangers have a [yellow]30%[fg] chance to explode, dealing [yellow]20%[fg] AoE damage', ['divine_machine_arrow'] = '[fg]arrows fired by rangers have a [yellow]40%[fg] chance to seek enemies and pierce [yellow]4[fg] times', - ['chronomancy'] = '[fg]all mages cast their spells [yellow]25%[fg] faster', - ['awakening'] = '[fg]every round [yellow]1[fg] mage is granted [yellow]+100%[fg] attack speed and damage for that round', - ['divine_punishment'] = '[fg]periodically deal [yellow]10X[fg] damage to all enemies, where [yellow]X[fg] is how many mages you have', + ['chronomancy'] = '[fg]all mages and sorcerers cast their spells [yellow]25%[fg] faster', + ['awakening'] = '[yellow]+100%[fg] aspd and damage to [yellow]1[fg] mage or sorcerer every round for that round', + ['divine_punishment'] = '[fg]repeatedly deal damage to all enemies based on how many mages or sorcerers you have', ['berserking'] = '[fg]all warriors have up to [yellow]+50%[fg] attack speed based on missing HP', ['unwavering_stance'] = '[fg]all warriors gain [yellow]+5%[fg] defense every [yellow]5[fg] seconds', ['ultimatum'] = '[fg]projectiles that chain gain [yellow]+25%[fg] damage with each chain', @@ -1270,15 +1270,15 @@ function init() [4] = {3, 5}, [5] = {4, 7}, [6] = {6, 10}, - [7] = {10, 14}, - [8] = {12, 16}, - [9] = {14, 18}, - [10] = {10, 14}, - [11] = {12, 16}, - [12] = {20, 24}, - [13] = {12, 16}, - [14] = {14, 18}, - [15] = {16, 20}, + [7] = {8, 10}, + [8] = {10, 12}, + [9] = {12, 15}, + [10] = {10, 13}, + [11] = {12, 15}, + [12] = {18, 20}, + [13] = {10, 14}, + [14] = {12, 16}, + [15] = {14, 18}, [16] = {12, 12}, [17] = {12, 12}, [18] = {20, 24}, @@ -1372,9 +1372,11 @@ function init() elseif lvl == 2 then return {50, 30, 15, 5} elseif lvl == 3 then - return {30, 40, 20, 10} + return {25, 45, 20, 10} elseif lvl == 4 then - return {20, 25, 35, 20} + return {10, 25, 45, 20} + elseif lvl == 5 then + return {5, 15, 30, 50} end end @@ -1401,9 +1403,9 @@ function init() end elseif lvl == 3 then if tier == 1 then - return 30 + return 25 elseif tier == 2 then - return 40 + return 45 elseif tier == 3 then return 20 elseif tier == 4 then @@ -1411,23 +1413,23 @@ function init() end elseif lvl == 4 then if tier == 1 then - return 20 + return 10 elseif tier == 2 then return 25 elseif tier == 3 then - return 35 + return 45 elseif tier == 4 then return 20 end elseif lvl == 5 then if tier == 1 then - return 10 + return 5 elseif tier == 2 then - return 20 + return 15 elseif tier == 3 then - return 25 + return 30 elseif tier == 4 then - return 40 + return 50 end end end @@ -1440,7 +1442,7 @@ function init() 'reinforce', 'payback', 'whispers_of_doom', 'heavy_impact', 'immolation', 'call_of_the_void'}, [3] = {'divine_machine_arrow', 'divine_punishment', 'flying_daggers', 'crucio', 'hive', 'void_rift'}, } - gold = run.gold or 2 + gold = run.gold or 3 passives = run.passives or {} locked_state = run.locked_state steam.userStats.requestCurrentStats() @@ -1463,10 +1465,8 @@ function init() --[[ main:add(Arena'arena') - main:go_to('arena', 13, { - {character = 'thief', level = 3}, - {character = 'scout', level = 1}, - {character = 'beastmaster', level = 1}, + main:go_to('arena', 4, { + {character = 'plague_doctor', level = 3}, }, passives) ]]-- diff --git a/media.lua b/media.lua index 094a5a9..1d52128 100644 --- a/media.lua +++ b/media.lua @@ -11,10 +11,10 @@ function Media:on_enter(from) self.effects = Group() self.ui = Group() - graphics.set_background_color(bg[0]) + graphics.set_background_color(yellow2[0]) Text2{group = self.ui, x = gw/2, y = gh/2, lines = { {text = '[fg]SNKRX', font = fat_font, alignment = 'center', height_offset = -15}, - {text = '[fg]sorcerer update', font = pixul_font, alignment = 'center'}, + {text = '[fg]mercenary update', font = pixul_font, alignment = 'center'}, }} end @@ -31,5 +31,5 @@ function Media:draw() self.effects:draw() self.ui:draw() - lock_image:draw(30, 30, 0, 1, 1, 0, 0, bg[4]) + mercenary:draw(30, 30, 0, 1, 1, 0, 0, yellow2[-5]) end diff --git a/player.lua b/player.lua index c9529dc..7d7573a 100644 --- a/player.lua +++ b/player.lua @@ -404,7 +404,7 @@ function Player:init(args) elseif self.character == 'plague_doctor' then self.t:every(5, function() - self:dot_attack(24, {duration = 12}) + self:dot_attack(24, {duration = 12, plague_doctor_unmovable = true}) end, nil, nil, 'attack') if self.level == 3 then @@ -846,7 +846,7 @@ function Player:init(args) end if self.chronomancy then - if table.any(self.classes, function(v) return v == 'mage' end) then + if table.any(self.classes, function(v) return v == 'mage' end) or table.any(self.classes, function(v) return v == 'sorcerer' end) then self.chronomancy_aspd_m = 1.25 end end @@ -856,7 +856,7 @@ function Player:init(args) local units = self:get_all_units() local mages = {} for _, unit in ipairs(units) do - if table.any(unit.classes, function(v) return v == 'mage' end) then + if table.any(unit.classes, function(v) return v == 'mage' end) or table.any(unit.classes, function(v) return v == 'sorcerer' end) then table.insert(mages, unit) end end @@ -873,14 +873,14 @@ function Player:init(args) local units = self:get_all_units() local mages = {} for _, unit in ipairs(units) do - if table.any(unit.classes, function(v) return v == 'mage' end) then + if table.any(unit.classes, function(v) return v == 'mage' end) or table.any(unit.classes, function(v) return v == 'sorcerer' end) then table.insert(mages, unit) end end local leader = main.current.player:get_leader() local enemies = main.current.main:get_objects_by_classes(main.current.enemies) if #enemies > 0 then - thunder1:play{volume = 0.5} + thunder1:play{volume = 0.4} camera:shake(4, 0.5) end for _, enemy in ipairs(enemies) do @@ -2284,7 +2284,7 @@ function DotArea:update(dt) self.vr = self.vr + self.dvr*dt if self.parent then - if (self.character == 'plague_doctor' and self.level == 3) or self.character == 'cryomancer' or self.character == 'pyromancer' then + if (self.character == 'plague_doctor' and self.level == 3 and not self.plague_doctor_unmovable) or self.character == 'cryomancer' or self.character == 'pyromancer' then self.x, self.y = self.parent.x, self.parent.y self.shape:move_to(self.x, self.y) end diff --git a/todo b/todo index bcc3447..53ab18d 100644 --- a/todo +++ b/todo @@ -16,27 +16,27 @@ Shop Update * Hook probabilities into reroll Item changes - Sorcerer items - Mercenary items + * Sorcerer items Unit changes - Launcher - remove - Beastmaster + * Launcher - removed + * Jester - changed to 4 projectiles + + Misc additions and changes + * Added sorcerer achievement + * Added mercenary achievement QoL - * Added sorcerer achievement * 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 - Options menu from buy screen - Add visuals for tank attack - Owned units highlighted in shop - Fix highlight colors and highlight reserve + * 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 @@ -49,12 +49,9 @@ Shop Update * 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 - Fix bug where quitting on level 2 arena goes back to level 1 shop - Fix fullscreen with different resolutions that don't scale properly - Fix enemies still spawning after arena clear (this happens with the extra enemy spawns that were blocked earlier) - https://i.imgur.com/ieVqYNI.png - https://i.imgur.com/3JCeFuZ.png - https://i.imgur.com/cvC1TBz.png + * 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 @@ -70,6 +67,12 @@ Sacrifice Update Endless mode Volume slider Add visuals for defensive ouroboros, divine intervention, fairy buff + Options menu from buy screen + Bug fixes + Fix fullscreen with different resolutions that don't scale properly + Fix enemies still spawning after arena clear (this happens with the extra enemy spawns that were blocked earlier) + https://i.imgur.com/ieVqYNI.png + https://i.imgur.com/3JCeFuZ.png Melee Update New Units