Healer & psyker update 2/4

master
a327ex 2021-06-24 12:09:29 -03:00
parent dbdd585c48
commit 009623c0d5
8 changed files with 322 additions and 102 deletions

View File

@ -243,13 +243,17 @@ function Arena:on_enter(from, level, units, passives, shop_level, shop_xp, lock)
local t1 = Text2{group = self.floor, x = gw/2, y = gh/2 + 2, sx = 0.6, sy = 0.6, lines = {{text = '[light_bg]<- or a -> or d', font = fat_font, alignment = 'center'}}}
local t2 = Text2{group = self.floor, x = gw/2, y = gh/2 + 18, lines = {{text = '[light_bg]turn left turn right', font = pixul_font, alignment = 'center'}}}
local t3 = Text2{group = self.floor, x = gw/2, y = gh/2 + 46, sx = 0.6, sy = 0.6, lines = {{text = '[light_bg]esc - options', font = fat_font, alignment = 'center'}}}
--[[
local t4 = Text2{group = self.floor, x = gw/2, y = gh/2 + 68, sx = 0.6, sy = 0.6, lines = {{text = '[light_bg]n - mute sfx', font = fat_font, alignment = 'center'}}}
local t5 = Text2{group = self.floor, x = gw/2, y = gh/2 + 90, sx = 0.6, sy = 0.6, lines = {{text = '[light_bg]m - mute music', font = fat_font, alignment = 'center'}}}
]]--
t1.t:after(8, function() t1.t:tween(0.2, t1, {sy = 0}, math.linear, function() t1.sy = 0 end) end)
t2.t:after(8, function() t2.t:tween(0.2, t2, {sy = 0}, math.linear, function() t2.sy = 0 end) end)
t3.t:after(8, function() t3.t:tween(0.2, t3, {sy = 0}, math.linear, function() t3.sy = 0 end) end)
--[[
t4.t:after(8, function() t4.t:tween(0.2, t4, {sy = 0}, math.linear, function() t4.sy = 0 end) end)
t5.t:after(8, function() t4.t:tween(0.2, t5, {sy = 0}, math.linear, function() t5.sy = 0 end) end)
]]--
end
-- Calculate class levels
@ -647,7 +651,7 @@ function Arena:quit()
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)
self:set_passives()
RerollButton{group = main.current.ui, x = gw - 40, y = 40, parent = self, force_update = true}
RerollButton{group = main.current.ui, x = gw - 40, y = gh - 40, parent = self, force_update = true}
self.shop_text = Text({{text = '[wavy_mid, fg]gold: [yellow]' .. gold, font = pixul_font, alignment = 'center'}}, global_text_tags)
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'}}}
@ -682,15 +686,15 @@ function Arena:set_passives(from_reroll)
local passive_2 = random:table_remove(run_passive_pool)
local passive_3 = random:table_remove(run_passive_pool)
if passive_1 then
table.insert(self.cards, PassiveCard{group = main.current.ui, x = gw/2 - w/2 + 0*(card_w + 20) + card_w/2 + 45, y = gh/2 - 6 + 10, w = card_w, h = card_h, card_i = 1, arena = self, passive = passive_1, force_update = true})
table.insert(self.cards, PassiveCard{group = main.current.ui, x = gw/2 - w/2 + 0*(card_w + 20) + card_w/2 + 45, y = gh/2 - 20, w = card_w, h = card_h, card_i = 1, arena = self, passive = passive_1, force_update = true})
end
if passive_2 then
table.insert(self.cards, PassiveCard{group = main.current.ui, x = gw/2 - w/2 + 1*(card_w + 20) + card_w/2 + 45, y = gh/2 - 6 + 10, w = card_w, h = card_h, card_i = 2, arena = self, passive = passive_2, force_update = true})
table.insert(self.cards, PassiveCard{group = main.current.ui, x = gw/2 - w/2 + 1*(card_w + 20) + card_w/2 + 45, y = gh/2 - 20, w = card_w, h = card_h, card_i = 2, arena = self, passive = passive_2, force_update = true})
end
if passive_3 then
table.insert(self.cards, PassiveCard{group = main.current.ui, x = gw/2 - w/2 + 2*(card_w + 20) + card_w/2 + 45, y = gh/2 - 6 + 10, w = card_w, h = card_h, card_i = 3, arena = self, passive = passive_3, force_update = true})
table.insert(self.cards, PassiveCard{group = main.current.ui, x = gw/2 - w/2 + 2*(card_w + 20) + card_w/2 + 45, y = gh/2 - 20, w = card_w, h = card_h, card_i = 3, arena = self, passive = passive_3, force_update = true})
end
self.passive_text = Text2{group = self.ui, x = gw/2 + 45, y = gh/2 - 65 + 10, lines = {{text = '[fg, wavy]choose one', font = fat_font, alignment = 'center'}}}
self.passive_text = Text2{group = self.ui, x = gw/2 + 45, y = gh/2 - 75, lines = {{text = '[fg, wavy]choose one', font = fat_font, alignment = 'center'}}}
if not passive_1 and not passive_2 and not passive_3 then
self:transition()
end
@ -757,7 +761,7 @@ function Arena:draw()
if self.choosing_passives or self.won or self.paused or self.died then graphics.rectangle(gw/2, gh/2, 2*gw, 2*gh, nil, nil, modal_transparent) end
self.ui:draw()
if self.shop_text then self.shop_text:draw(gw - 40, 20) end
if self.shop_text then self.shop_text:draw(gw - 40, gh - 17) end
if self.in_credits then graphics.rectangle(gw/2, gh/2, 2*gw, 2*gh, nil, nil, modal_transparent_2) end
self.credits:draw()

View File

@ -241,8 +241,6 @@ function BuyScreen:draw()
self.effects:draw()
if self.items_text then self.items_text:draw(32, 145) end
if self.level_text then self.level_text:draw(265, gh - 20) end
if self.paused then graphics.rectangle(gw/2, gh/2, 2*gw, 2*gh, nil, nil, modal_transparent) end
self.ui:draw()
if self.unit_grabbed then
local x, y = camera:get_mouse_position()
@ -261,13 +259,15 @@ function BuyScreen:draw()
if self.party_text then self.party_text:draw(440, 20) end
if current_new_game_plus > 0 then self.ng_text:draw(265, gh - 40) end
if self.paused then graphics.rectangle(gw/2, gh/2, 2*gw, 2*gh, nil, nil, modal_transparent) end
self.ui:draw()
if self.in_tutorial then
graphics.rectangle(gw/2, gh/2, 2*gw, 2*gh, nil, nil, modal_transparent_2)
arrow:draw(gw/2 + 93, gh/2 - 30, 0, 0.4, 0.35)
arrow:draw(gw/2 + 93, gh/2 - 10, 0, 0.4, 0.35)
end
self.tutorial:draw()
end
@ -1345,7 +1345,7 @@ function PassiveCard:on_mouse_enter()
self.info_text:activate({
{text = self.passive_description, font = pixul_font, alignment = 'center', height_multiplier = 1.25},
}, nil, nil, nil, nil, 16, 4, nil, 2)
self.info_text.x, self.info_text.y = gw/2, gh/2 + gh/4 + 22
self.info_text.x, self.info_text.y = gw/2, gh/2 + gh/4 - 6
end

View File

@ -482,6 +482,14 @@ function Seeker:hit(damage, projectile, dot)
end
end
if main.current.healer_level > 0 then
if random:bool((main.current.healer_level == 2 and 16) or (main.current.healer_level == 1 and 8) or 0) then
trigger:after(0.01, function()
HealingOrb{group = main.current.main, x = self.x, y = self.y}
end)
end
end
if self.boss then
slow(0.25, 1)
magic_die1:play{pitch = random:float(0.95, 1.05), volume = 0.5}

View File

@ -24,6 +24,7 @@ function init()
unlock1 = Sound('Unlock 3.ogg', s)
gambler1 = Sound('Collect 5.ogg', s)
usurer1 = Sound('Shadow Punch 2.ogg', s)
orb1 = Sound('Collect 2.ogg', s)
gold1 = Sound('Collect 5.ogg', s)
gold2 = Sound('Coins - Gears - Slot.ogg', s)
psychic1 = Sound('Magical Impact 13.ogg', s)
@ -546,7 +547,7 @@ function init()
['magician'] = function(lvl) return '[fg]creates a small area that deals [yellow]' .. get_character_stat('magician', lvl, 'dmg') .. ' AoE[fg] damage' end,
['archer'] = function(lvl) return '[fg]shoots an arrow that deals [yellow]' .. get_character_stat('archer', lvl, 'dmg') .. '[fg] damage and pierces' end,
['scout'] = function(lvl) return '[fg]throws a knife that deals [yellow]' .. get_character_stat('scout', lvl, 'dmg') .. '[fg] damage and chains [yellow]3[fg] times' end,
['cleric'] = function(lvl) return '[fg]heals a unit for [yellow]20%[fg] of its max hp when it drops below [yellow]50%[fg] max hp' end,
['cleric'] = function(lvl) return '[fg]creates [yellow]1[fg] healing orb' end,
['outlaw'] = function(lvl) return '[fg]throws a fan of [yellow]5[fg] knives, each dealing [yellow]' .. get_character_stat('outlaw', lvl, 'dmg') .. '[fg] damage' end,
['blade'] = function(lvl) return '[fg]throws multiple blades that deal [yellow]' .. get_character_stat('blade', lvl, 'dmg') .. ' AoE[fg] damage' end,
['elementor'] = function(lvl) return '[fg]deals [yellow]' .. get_character_stat('elementor', lvl, 'dmg') .. ' AoE[fg] damage in a large area centered on a random target' end,
@ -579,8 +580,8 @@ function init()
['psykino'] = function(lvl) return '[fg]pulls enemies together for [yellow]2[fg] seconds' end,
['barrager'] = function(lvl) return '[fg]shoots a barrage of [yellow]3[fg] arrows, each dealing [yellow]' .. get_character_stat('barrager', lvl, 'dmg') .. '[fg] damage and pushing enemies' end,
['highlander'] = function(lvl) return '[fg]deals [yellow]' .. 5*get_character_stat('highlander', lvl, 'dmg') .. '[fg] AoE damage' end,
['fairy'] = function(lvl) return '[fg]periodically heals [yellow]1[fg] unit at random and grants it [yellow]+100%[fg] attack speed for [yellow]6[fg] seconds' end,
['priest'] = function(lvl) return '[fg]heals all allies for [yellow]20%[fg] their max HP' end,
['fairy'] = function(lvl) return '[fg]creates [yellow]1[fg] healing orb and grants [yellow]1[fg] unit [yellow]+100%[fg] attack speed for [yellow]6[fg] seconds' end,
['priest'] = function(lvl) return '[fg]creates [yellow]5[fg] healing orbs' end,
['infestor'] = function(lvl) return '[fg]curses [yellow]8[fg] 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,
['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,
@ -718,7 +719,7 @@ function init()
['magician'] = function() return '[fg]the magician becomes invulnerable for [yellow]6[fg] seconds but also cannot attack' end,
['archer'] = function() return '[fg]the arrow ricochets off walls [yellow]3[fg] times' end,
['scout'] = function() return '[yellow]+25%[fg] damage per chain and [yellow]+3[fg] chains' end,
['cleric'] = function() return '[fg]heals all units' end,
['cleric'] = function() return '[fg]creates [yellow]4[fg] healing orbs' end,
['outlaw'] = function() return "[yellow]+50%[fg] outlaw attack speed and his knives seek enemies" end,
['blade'] = function() return '[fg]deal additional [yellow]' .. math.round(get_character_stat('blade', 3, 'dmg')/3, 2) .. '[fg] damage per enemy hit' end,
['elementor'] = function() return '[fg]slows enemies by [yellow]60%[fg] for [yellow]6[fg] seconds on hit' end,
@ -750,10 +751,10 @@ function init()
['psykino'] = function() return '[fg]enemies take [yellow]' .. 4*get_character_stat('psykino', 3, 'dmg') .. '[fg] damage and are pushed away when the area expires' end,
['barrager'] = function() return '[fg]every 3rd attack the barrage shoots [yellow]15[fg] projectiles and they push harder' end,
['highlander'] = function() return '[fg]quickly repeats the attack [yellow]3[fg] times' end,
['fairy'] = function() return '[fg]heals [yellow]2[fg] units instead and grants them an additional [yellow]100%[fg] attack speed' end,
['fairy'] = function() return '[fg]creates [yellow]2[fg] healing orbs and grants [yellow]2[fg] units [yellow]+100%[fg] attack speed' end,
['priest'] = function() return '[fg]picks [yellow]3[fg] units at random and grants them a buff that prevents death once' end,
['infestor'] = function() return '[fg][yellow]triples[fg] the number of critters released' end,
['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,
['flagellant'] = function() return '[yellow]2X[fg] flagellant max HP and grants [yellow]+12%[fg] damage to all allies per cast instead' 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 releases projectiles, each dealing [yellow]' .. get_character_stat('witch', 3, 'dmg') .. '[fg] damage and chaining once' end,
@ -775,7 +776,7 @@ function init()
['magician'] = function() return '[light_bg]the magician becomes invulnerable for 6 seconds but also cannot attack' end,
['archer'] = function() return '[light_bg]the arrow ricochets off walls 3 times' end,
['scout'] = function() return '[light_bg]+25% damage per chain and +3 chains' end,
['cleric'] = function() return '[light_bg]heals all units' end,
['cleric'] = function() return '[light_bg]creates 4 healing orbs' end,
['outlaw'] = function() return "[light_bg]+50% outlaw attack speed and his knives seek enemies" end,
['blade'] = function() return '[light_bg]deal additional ' .. math.round(get_character_stat('blade', 3, 'dmg')/2, 2) .. ' damage per enemy hit' end,
['elementor'] = function() return '[light_bg]slows enemies by 60% for 6 seconds on hit' end,
@ -807,10 +808,10 @@ function init()
['psykino'] = function() return '[light_bg]enemies take ' .. 4*get_character_stat('psykino', 3, 'dmg') .. ' damage and are pushed away when the area expires' end,
['barrager'] = function() return '[light_bg]every 3rd attack the barrage shoots 15 projectiles and they push harder' end,
['highlander'] = function() return '[light_bg]quickly repeats the attack 3 times' end,
['fairy'] = function() return '[light_bg]heals 2 units instead and grants them an additional 100% attack speed' end,
['fairy'] = function() return '[light_bg]creates 2 healing orbs and grants 2 units +100% attack speed' end,
['priest'] = function() return '[light_bg]picks 3 units at random and grants them a buff that prevents death once' end,
['infestor'] = function() return '[light_bg]triples the number of critters released' end,
['flagellant'] = function() return '[light_bg]deals ' .. 2*get_character_stat('flagellant', 3, 'dmg') .. ' damage to all allies and grants +12% damage to all allies per cast' end,
['flagellant'] = function() return '[light_bg]2X flagellant max HP and grants +12% damage to all allies per cast instead' end,
['arcanist'] = function() return '[light_bg]+50% attack speed for the orb and 2 projectiles are released per cast' end,
['illusionist'] = function() return '[light_bg]doubles the number of copies created and they release 12 projectiles on death' end,
['witch'] = function() return '[light_bg]the area periodically releases projectiles, each dealing ' .. get_character_stat('witch', 3, 'dmg') .. ' damage and chaining once' end,
@ -928,7 +929,7 @@ function init()
['enchanter'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+15%[light_bg]/[' .. ylb2(lvl) .. ']+25% [fg]damage to all allies' end,
['nuker'] = function(lvl) return '[' .. ylb1(lvl) .. ']3[light_bg]/[' .. ylb2(lvl) .. ']6 [fg]- [' .. ylb1(lvl) .. ']+15%[light_bg]/[' .. ylb2(lvl) .. ']+25% [fg]area damage and size to allied nukers' end,
['conjurer'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+25%[light_bg]/[' .. ylb2(lvl) .. ']+50% [fg]summon damage and duration' end,
['psyker'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+10%[light_bg]/[' .. ylb2(lvl) .. ']+20% [fg]damage and attack speed per active set to allied psykers' end,
['psyker'] = function(lvl) return '[fg]create a piercing, damaging orb around each psyker, it inherits damage from its target' end,
['curser'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+25%[light_bg]/[' .. ylb2(lvl) .. ']+50% [fg]curse duration' end,
['forcer'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+25%[light_bg]/[' .. ylb2(lvl) .. ']+50% [fg]knockback force to all allies' end,
['swarmer'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+1[light_bg]/[' .. ylb2(lvl) .. ']+3 [fg]hits to critters' end,
@ -1484,8 +1485,11 @@ function init()
main_song_instance = _G[random:table{'song1', 'song2', 'song3', 'song4', 'song5'}]:play{volume = 0.5}
main = Main()
--[[
main:add(MainMenu'mainmenu')
main:go_to('mainmenu')
]]--
--[[
main:add(BuyScreen'buy_screen')
@ -1493,15 +1497,18 @@ function init()
]]--
-- main:go_to('buy_screen', 7, run.units or {}, {'unleash'})
--[[
main:add(Arena'arena')
main:go_to('arena', 4, {
{character = 'arcanist', level = 1},
{character = 'witch', level = 1},
{character = 'gambler', level = 1},
{character = 'illusionist', level = 1},
}, {{passive = 'freezing_field', level = 1}})
]]--
{character = 'psykeeper', level = 3},
{character = 'vagrant', level = 1},
{character = 'psychic', level = 1},
{character = 'flagellant', level = 1},
--[[
{character = 'priest', level = 1},
{character = 'cleric', level = 1},
{character = 'fairy', level = 1},
]]--
}, {})
--[[
main:add(Media'media')
@ -1624,7 +1631,7 @@ function open_options(self)
self.ng_t = Text2{group = self.ui, x = gw/2 + 63, y = gh - 50, lines = {{text = '[bg10]current: ' .. current_new_game_plus, font = pixul_font, alignment = 'center'}}}
end
self.resume_button = Button{group = self.ui, x = gw/2, y = gh - 225, force_update = true, button_text = 'resume game (esc)', fg_color = 'bg10', bg_color = 'bg', action = function(b)
self.resume_button = Button{group = self.ui, x = gw/2, y = gh - 225, force_update = true, button_text = self:is(MainMenu) and 'main menu (esc)' or 'resume game (esc)', fg_color = 'bg10', bg_color = 'bg', action = function(b)
trigger:tween(0.25, _G, {slow_amount = 1}, math.linear, function()
slow_amount = 1
self.paused = false
@ -1648,7 +1655,10 @@ function open_options(self)
if self.arrow_snake_button then self.arrow_snake_button.dead = true; self.arrow_snake_button = nil end
if self.ng_plus_plus_button then self.ng_plus_plus_button.dead = true; self.ng_plus_plus_button = nil end
if self.ng_plus_minus_button then self.ng_plus_minus_button.dead = true; self.ng_plus_minus_button = nil end
if self.main_menu_button then self.main_menu_button.dead = true; self.main_menu_button = nil end
system.save_state()
if self:is(MainMenu) or self:is(BuyScreen) then input:set_mouse_visible(true)
elseif self:is(Arena) then input:set_mouse_visible(state.mouse_control or false) end
end, 'pause')
end}
@ -1815,7 +1825,6 @@ function open_options(self)
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 = state.dark_transitions and bg[-2] or fg[0], transition_action = function()
system.save_run()
main:add(MainMenu'main_menu')
main:go_to('main_menu')
end, text = Text({{text = '[wavy, ' .. tostring(state.dark_transitions and 'fg' or 'bg') .. ']..', font = pixul_font, alignment = 'center'}}, global_text_tags)}
@ -1832,12 +1841,6 @@ end
function close_options(self)
if not state.mouse_control then
input:set_mouse_visible(false)
end
if self:is(Arena) then
input:set_mouse_visible(state.mouse_control or false)
end
trigger:tween(0.25, _G, {slow_amount = 1}, math.linear, function()
slow_amount = 1
self.paused = false
@ -1863,6 +1866,8 @@ function close_options(self)
if self.ng_plus_minus_button then self.ng_plus_minus_button.dead = true; self.ng_plus_minus_button = nil end
if self.main_menu_button then self.main_menu_button.dead = true; self.main_menu_button = nil end
system.save_state()
if self:is(MainMenu) or self:is(BuyScreen) then input:set_mouse_visible(true)
elseif self:is(Arena) then input:set_mouse_visible(state.mouse_control or false) end
end, 'pause')
end

View File

@ -83,11 +83,11 @@ function MainMenu:on_enter(from)
self.title_text = Text({{text = '[wavy_mid, fg]SNKRX', font = fat_font, alignment = 'center'}}, global_text_tags)
self.arena_run_button = Button{group = self.main_ui, x = 55, y = gh/2 - 10, force_update = true, button_text = 'arena run', 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 = state.dark_transitions and bg[-2] or fg[0], transition_action = function()
self.transitioning = true
slow_amount = 1
local run = system.load_run()
run_passive_pool = run.run_passive_pool or {

View File

@ -137,7 +137,39 @@ function Player:init(args)
end, nil, nil, 'shoot')
elseif self.character == 'cleric' then
self.t:every(6, function()
self.t:every(8, function()
if self.level == 3 then
for i = 1, 4 do
local check_circle = Circle(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16), 2)
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
while #objects > 0 do
check_circle:move_to(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16))
objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
end
SpawnEffect{group = main.current.effects, x = check_circle.x, y = check_circle.y, color = green[0], action = function(x, y)
local check_circle = Circle(x, y, 2)
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
if #objects == 0 then
HealingOrb{group = main.current.main, x = x, y = y}
end
end}
end
else
local check_circle = Circle(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16), 2)
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
while #objects > 0 do
check_circle:move_to(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16))
objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
end
SpawnEffect{group = main.current.effects, x = check_circle.x, y = check_circle.y, color = green[0], action = function(x, y)
local check_circle = Circle(x, y, 2)
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
if #objects == 0 then
HealingOrb{group = main.current.main, x = x, y = y}
end
end}
end
--[[
local all_units = self:get_all_units()
local unit_index = table.contains(all_units, function(v) return v.hp <= 0.5*v.max_hp end)
if unit_index then
@ -150,6 +182,7 @@ function Player:init(args)
end
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
end
]]--
end, nil, nil, 'heal')
elseif self.character == 'arcanist' then
@ -653,26 +686,52 @@ function Player:init(args)
local unit_1 = random:table_remove(units)
local unit_2 = random:table_remove(units)
if unit_1 then
unit_1:heal(0.2*unit_1.max_hp*(self.heal_effect_m or 1))
unit_1.fairy_aspd_m = 3
unit_1.t:after(5.98, function() unit_1.fairy_aspd_m = 1 end)
end
if unit_2 then
unit_2:heal(0.2*unit_2.max_hp*(self.heal_effect_m or 1))
unit_2.fairy_aspd_m = 3
unit_2.t:after(5.98, function() unit_2.fairy_aspd_m = 1 end)
end
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
buff1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
for i = 1, 2 do
local check_circle = Circle(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16), 2)
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
while #objects > 0 do
check_circle:move_to(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16))
objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
end
SpawnEffect{group = main.current.effects, x = check_circle.x, y = check_circle.y, color = green[0], action = function(x, y)
local check_circle = Circle(x, y, 2)
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
if #objects == 0 then
HealingOrb{group = main.current.main, x = x, y = y}
end
end}
end
else
local unit = random:table(self:get_all_units())
if unit then
unit:heal(0.2*unit.max_hp*(self.heal_effect_m or 1))
unit.fairy_aspd_m = 2
unit.t:after(5.98, function() unit.fairy_aspd_m = 1 end)
end
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
buff1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
local check_circle = Circle(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16), 2)
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
while #objects > 0 do
check_circle:move_to(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16))
objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
end
SpawnEffect{group = main.current.effects, x = check_circle.x, y = check_circle.y, color = green[0], action = function(x, y)
local check_circle = Circle(x, y, 2)
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
if #objects == 0 then
HealingOrb{group = main.current.main, x = x, y = y}
end
end}
end
end, nil, nil, 'heal')
@ -748,10 +807,20 @@ function Player:init(args)
end)
end
self.t:every(10, function()
self.t:every(15, function()
local x, y = random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16)
for i = 1, 5 do
SpawnEffect{group = main.current.effects, x = x, y = y, color = green[0], action = function(x, y)
local check_circle = Circle(x, y, 2)
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
if #objects == 0 then HealingOrb{group = main.current.main, x = x, y = y} end
end}
end
--[[
local all_units = self:get_all_units()
for _, unit in ipairs(all_units) do unit:heal(0.2*unit.max_hp*(self.heal_effect_m or 1)) end
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
]]--
end, nil, nil, 'heal')
elseif self.character == 'infestor' then
@ -769,32 +838,20 @@ function Player:init(args)
elseif self.character == 'flagellant' then
self.t:every(8, function()
if self.level == 3 then
flagellant1:play{pitch = random:float(0.95, 1.05), volume = 0.4}
buff1:play{pitch = random:float(0.95, 1.05), volume = 0.3}
local all_units = self:get_all_units()
local dmg = self.dmg
for _, unit in ipairs(all_units) do
buff1:play{pitch = random:float(0.95, 1.05), volume = 0.3}
flagellant1:play{pitch = random:float(0.95, 1.05), volume = 0.4}
local all_units = self:get_all_units()
for _, unit in ipairs(all_units) do
if unit.character == 'flagellant' then
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.4}
unit:hit(2*dmg)
if not unit.flagellant_dmg_m then
unit.flagellant_dmg_m = 1
end
unit.flagellant_dmg_m = unit.flagellant_dmg_m + 0.12
unit:hit(self.level == unit.dmg or 2*unit.dmg)
end
else
buff1:play{pitch = random:float(0.95, 1.05), volume = 0.3}
flagellant1:play{pitch = random:float(0.95, 1.05), volume = 0.4}
local all_units = self:get_all_units()
for _, unit in ipairs(all_units) do
if unit.character == 'flagellant' then
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.4}
unit:hit(2*unit.dmg)
end
if not unit.flagellant_dmg_m then
unit.flagellant_dmg_m = 1
end
if not unit.flagellant_dmg_m then
unit.flagellant_dmg_m = 1
end
if self.level == 3 then
unit.flagellant_dmg_m = unit.flagellant_dmg_m + 0.12
else
unit.flagellant_dmg_m = unit.flagellant_dmg_m + 0.04
end
end
@ -1011,6 +1068,21 @@ function Player:init(args)
end)
end
if self.character == 'flagellant' and self.level == 3 then
self.hp = 2*self.max_hp
end
if self.leader then
self.t:after(0.5, function()
local units = self:get_all_units()
for _, unit in ipairs(units) do
if table.any(self.classes, function(v) return v == 'psyker' end) then
Projectile{group = main.current.main, x = unit.x + 24*math.cos(unit.r), y = unit.y + 24*math.sin(unit.r), color = fg[0], v = 200, dmg = unit.dmg, character = 'psyker', parent = unit}
end
end
end)
end
self.mouse_control_v_buffer = {}
if main.current:is(MainMenu) then
@ -1109,6 +1181,7 @@ function Player:update(dt)
elseif main.current.enchanter_level == 1 then self.enchanter_dmg_m = 1.15
else self.enchanter_dmg_m = 1 end
--[[
if table.any(self.classes, function(v) return v == 'psyker' end) then
local class_levels = get_class_levels(self:get_all_units())
local number_of_active_sets = 0
@ -1138,6 +1211,7 @@ function Player:update(dt)
self.psyker_aspd_m = 1
end
end
]]--
if main.current.forcer_level == 2 then self.knockback_m = 1.5
elseif main.current.forcer_level == 1 then self.knockback_m = 1.25
@ -1205,6 +1279,10 @@ function Player:update(dt)
self.dividends_dmg_m = (1 + gold/100)
end
if self.character == 'flagellant' and self.level == 3 then
self.flagellant_hp_m = 2
end
self.buff_def_a = (self.warrior_def_a or 0)
self.buff_aspd_m = (self.chronomancer_aspd_m or 1)*(self.vagrant_aspd_m or 1)*(self.outlaw_aspd_m or 1)*(self.fairy_aspd_m or 1)*(self.psyker_aspd_m or 1)*(self.chronomancy_aspd_m or 1)*(self.awakening_aspd_m or 1)*(self.berserking_aspd_m or 1)*(self.reinforce_aspd_m or 1)*(self.squire_aspd_m or 1)*(self.speed_3_aspd_m or 1)*(self.last_stand_aspd_m or 1)*(self.enchanted_aspd_m or 1)
self.buff_dmg_m = (self.squire_dmg_m or 1)*(self.vagrant_dmg_m or 1)*(self.enchanter_dmg_m or 1)*(self.swordsman_dmg_m or 1)*(self.flagellant_dmg_m or 1)*(self.psyker_dmg_m or 1)*(self.ballista_dmg_m or 1)*(self.awakening_dmg_m or 1)*(self.reinforce_dmg_m or 1)*(self.payback_dmg_m or 1)*(self.immolation_dmg_m or 1)*(self.damage_4_dmg_m or 1)*(self.offensive_stance_dmg_m or 1)*(self.last_stand_dmg_m or 1)*(self.dividends_dmg_m or 1)
@ -1212,6 +1290,7 @@ function Player:update(dt)
self.buff_area_size_m = (self.nuker_area_size_m or 1)*(self.magnify_area_size_m or 1)*(self.unleash_area_size_m or 1)*(self.last_stand_area_size_m or 1)
self.buff_area_dmg_m = (self.nuker_area_dmg_m or 1)*(self.amplify_area_dmg_m or 1)*(self.unleash_area_dmg_m or 1)*(self.last_stand_area_dmg_m or 1)
self.buff_mvspd_m = (self.wall_rider_mvspd_m or 1)*(self.centipede_mvspd_m or 1)*(self.squire_mvspd_m or 1)*(self.last_stand_mvspd_m or 1)
self.buff_hp_m = (self.flagellant_hp_m or 1)
self:calculate_stats()
if self.attack_sensor then self.attack_sensor:move_to(self.x, self.y) end
@ -1425,26 +1504,30 @@ function Player:hit(damage, from_undead)
end
end
local psykeeper = self:get_unit'psykeeper'
if psykeeper then
psykeeper.stored_heal = psykeeper.stored_heal + actual_damage
if psykeeper.stored_heal > (0.5*psykeeper.max_hp) and love.timer.getTime() - psykeeper.last_heal_time > 6 then
psykeeper.last_heal_time = love.timer.getTime()
local all_units = self:get_all_units()
for _, unit in ipairs(all_units) do
unit:heal(psykeeper.stored_heal*(self.heal_effect_m or 1)/#all_units)
if self.character == 'psykeeper' then
self.stored_heal = self.stored_heal + actual_damage
if self.stored_heal > (0.2*self.max_hp) then
self.stored_heal = 0
local check_circle = Circle(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16), 2)
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
while #objects > 0 do
check_circle:move_to(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16))
objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
end
if self.level == 3 then
buff1: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(2*psykeeper.stored_heal/#enemies)
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = fg[0], duration = 0.1}
LightningLine{group = main.current.effects, src = self, dst = enemy, color = fg[0]}
SpawnEffect{group = main.current.effects, x = check_circle.x, y = check_circle.y, color = green[0], action = function(x, y)
local check_circle = Circle(x, y, 2)
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
if #objects == 0 then
HealingOrb{group = main.current.main, x = x, y = y}
end
end}
end
if self.level == 3 then
local enemies = main.current.main:get_objects_by_classes(main.current.enemies)
for _, enemy in ipairs(enemies) do
enemy:hit(2*actual_damage/#enemies)
end
psykeeper.stored_heal = 0
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
end
end
@ -1871,6 +1954,12 @@ function Projectile:init(args)
end)
end
elseif self.character == 'psyker' then
self.pierce = 10000
self.orbit_distance = random:float(28, 36)
self.orbit_speed = random:float(4, 6)
self.orbit_offset = random:float(0, 2*math.pi)
elseif self.character == 'lich' then
self.spring:pull(0.15)
self.t:every(0.08, function()
@ -1937,6 +2026,16 @@ end
function Projectile:update(dt)
self:update_game_object(dt)
if self.character == 'psyker' then
if self.parent.dead then self.dead = true; self.parent = nil; return end
self:set_position(self.parent.x + self.orbit_distance*math.cos(self.orbit_speed*time + self.orbit_offset), self.parent.y + self.orbit_distance*math.sin(self.orbit_speed*time + self.orbit_offset))
local dx, dy = self.x - (self.previous_x or 0), self.y - (self.previous_y or 0)
self.r = Vector(dx, dy):angle()
self:set_angle(self.r)
self.previous_x, self.previous_y = self.x, self.y
return
end
if self.character == 'spellblade' then
self.orbit_r = self.orbit_r + self.orbit_vr*dt
end
@ -1966,6 +2065,7 @@ function Projectile:update(dt)
self.vr = self.vr + self.dvr*dt
end
--[[
if self.parent.point_blank or self.parent.longshot then
self.distance_travelled = self.distance_travelled + math.length(self:get_velocity())
if self.parent.point_blank and self.parent.longshot then
@ -1976,6 +2076,7 @@ function Projectile:update(dt)
self.distance_dmg_m = math.remap(self.distance_travelled, 0, 15000, 0.75, 2)
end
end
]]--
end
@ -2000,6 +2101,11 @@ function Projectile:draw()
graphics.circle(self.x, self.y, 4, self.hfx.hit.f and fg[0] or self.color)
graphics.pop()
elseif self.character == 'psyker' then
graphics.push(self.x, self.y, self.r, self.hfx.hit.x, self.hfx.hit.x)
graphics.circle(self.x, self.y, 2.5, self.hfx.hit.f and fg[0] or self.color)
graphics.pop()
else
graphics.push(self.x, self.y, self.r + (self.orbit_r or 0))
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 2, 2, self.color)
@ -2086,6 +2192,7 @@ function Projectile:on_collision_enter(other, contact)
elseif self.character == 'engineer' or self.character == 'dual_gunner' or self.character == 'miner' then
self:die(x, y, r, random:int(2, 3))
_G[random:table{'turret_hit_wall1', 'turret_hit_wall2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.2}
elseif self.character == 'psyker' then
else
self:die(x, y, r, random:int(2, 3))
proj_hit_wall1:play{pitch = random:float(0.9, 1.1), volume = 0.2}
@ -2132,9 +2239,10 @@ function Projectile:on_trigger_enter(other, contact)
end
if self.character == 'archer' or self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' or self.character == 'hunter' or self.character == 'spellblade' or self.character == 'engineer' or
self.character == 'jester' or self.character == 'assassin' or self.character == 'barrager' or self.character == 'beastmaster' or self.character == 'witch' or self.character == 'miner' or self.character == 'thief' then
self.character == 'jester' or self.character == 'assassin' or self.character == 'barrager' or self.character == 'beastmaster' or self.character == 'witch' or self.character == 'miner' or self.character == 'thief' or
self.character == 'psyker' then
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
if self.character == 'spellblade' then
if self.character == 'spellblade' or self.character == 'psyker' then
magic_area1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
end
elseif self.character == 'wizard' or self.character == 'lich' or self.character == 'arcanist' then
@ -3145,6 +3253,7 @@ function Gold:draw()
graphics.pop()
end
function Gold:on_trigger_enter(other, contact)
if self.cant_be_picked_up then return end
@ -3195,6 +3304,92 @@ end
HealingOrb = Object:extend()
HealingOrb:implement(GameObject)
HealingOrb:implement(Physics)
function HealingOrb: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(4, 4, 'dynamic', 'ghost')
self:set_restitution(0.5)
local r = random:float(0, 2*math.pi)
local f = random:float(2, 4)
self:apply_impulse(f*math.cos(r), f*math.sin(r))
self:apply_angular_impulse(random:table{random:float(-6*math.pi, -2*math.pi), random:float(2*math.pi, 6*math.pi)})
self:set_damping(2.5)
self:set_angular_damping(5)
self.color = yellow2[0]
self.hfx:add('hit', 1)
self.cant_be_picked_up = true
self.t:after(0.5, function() self.cant_be_picked_up = false end)
illusion1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
self.magnet_sensor = Circle(self.x, self.y, 32)
end
function HealingOrb:update(dt)
self:update_game_object(dt)
self.r = self:get_angle()
if main.current.player.magnetism then
local players = self:get_objects_in_shape(self.magnet_sensor, {Player})
if players and #players > 0 then
local x, y = 0, 0
for _, p in ipairs(players) do
x = x + p.x
y = y + p.y
end
x = x/#players
y = y/#players
local r = self:angle_to_point(x, y)
self:apply_force(20*math.cos(r), 20*math.sin(r))
end
end
if self.magnet_sensor then self.magnet_sensor:move_to(self.x, self.y) end
end
function HealingOrb:draw()
if not self.hfx.hit then return end
local sr = random:float(-0.1, 0.1)
graphics.push(self.x, self.y, self.r, self.hfx.hit.x + sr, self.hfx.hit.x + sr)
graphics.circle(self.x, self.y, 1.2*self.shape.w, self.hfx.hit.f and fg[0] or green_transparent_weak)
graphics.circle(self.x, self.y, 0.5*self.shape.w, self.hfx.hit.f and fg[0] or green[0])
graphics.pop()
end
function HealingOrb:on_trigger_enter(other, contact)
if self.cant_be_picked_up then return end
if other:is(Player) then
self.dead = true
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 4, color = fg[0], duration = 0.1}
for i = 1, 2 do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = green[0]} end
orb1:play{pitch = random:float(0.95, 1.05), volume = 1}
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
local units = other:get_all_units()
local lowest_hp = 10000
local lowest_unit
for _, unit in ipairs(units) do
if unit.hp < lowest_hp and unit.hp < unit.max_hp then
lowest_hp = unit.hp
lowest_unit = unit
end
end
if lowest_unit then
lowest_unit:heal(0.1*lowest_unit.max_hp*(lowest_unit.heal_effect_m or 1))
else
end
end
end
Critter = Object:extend()
Critter:implement(GameObject)
Critter:implement(Physics)

View File

@ -31,9 +31,9 @@ function shared_init()
slow_amount = 1
sfx = SoundTag()
sfx.volume = 0.5
sfx.volume = state.sfx_volume or 0.5
music = SoundTag()
music.volume = 0.5
music.volume = state.music_volume or 0.5
if state.volume_muted then sfx.volume = 0 end
if state.music_muted then music.volume = 0 end

40
todo
View File

@ -1,4 +1,4 @@
Looping Update
Healer & Psyker Update
New items:
General:
Intimidation - enemies spawn with -10/20/30% max HP
@ -10,7 +10,7 @@ Looping Update
Infesting Strike - X/Y/Z% chance for attacks to spawn 2 critters on kill
Kinetic Strike - X/Y/Z% chance for attacks to push enemies away with high force
Burning Strike - X% chance for attacks to ignite, dealing 20% dps for 3 seconds, ignited enemies ignite nearby enemies on death
Lucky Strike - X% chance for attacks to cause enemies to drop gold
Lucky Strike - X% chance for attacks to cause enemies to drop gold on death
Healing Strike - X% chance for attacks to spawn a healing orb on kill
Stunning Strike - X/Y/Z% chance for attacks to stun for 2 seconds
Silencing Strike - X/Y/Z% chance for attacks to silence on hit
@ -23,26 +23,25 @@ Looping Update
Divine Barrage - 10/20/30% chance to release a homing barrage when picking up a healing orb
Psyker:
Orbitism - 33/66/99% faster orb speed
Psychic Leak - orbs deal extra damage based on the amount of damage all psykers have taken recently
Psychokinesis -
Psychosink - orbs move faster based on the amount of damage all psykers have taken recently
Psychosense - 20/40/60% increased orb range
Conjurer:
Rearm - summons repeat their attacks once
Taunt - 10/20/30% chance for summons to taunt nearby enemies on attack
Summon Instability - summons explode when disappearing, dealing 100/150/200% damage
https://i.imgur.com/yzCVMah.png
Changes:
Magnetism - also attracts healing orbs
Enchanted - 30/60/90%
* Magnetism - also attracts healing orbs
Enchanted - 33/66/99%
Healer rework:
Enemies have a 8/16% chance to spawn healing orbs on death, orbs prioritize healing low health allies
Cleric: creates 1 healing orb, Lv.3: creates 4 healing orbs and grants +20% healing effectiveness
Priest: creates 6 healing orbs
Fairy: grants a random unit 100% attack speed for 6 seconds and creates 1 healing orb
* Enemies have a 8/16% chance to spawn healing orbs on death, orbs prioritize healing low health allies
* Cleric: creates 1 healing orb, Lv.3: creates 4 healing orbs
* Priest: creates 5 healing orbs
* Fairy: grants a random unit 100% attack speed for 6 seconds and creates 1 healing orb
Psyker rework:
Create orbitting, damaging balls at the head of the snake equal to the number of psykers
Flagellant - Lv.3: 2X flagellant max HP and grants +10% damage to all allies per cast
Psychic - Lv.3: gains up to 300% damage the less HP the psychic has
Psykino - Lv.3: gains up to 100% attack speed the less HP the psykino has
Psykeeper - creates a healing orb every time the psykeeper takes 30% of its max HP in damage, Lv.3: deal double the damage taken by the psykeeper to all enemies
* Create a piercing, damaging orb around each psyker, it inherits damage from its target
* Flagellant - Lv.3: 4X flagellant max HP and +12% damage to all allies per cast
* Psykeeper - creates a healing orb every time the psykeeper takes 20% of its max HP in damage, Lv.3: deal double the damage taken by the psykeeper to all enemies
Looping
Change end screen
Loop button on end screen
@ -50,9 +49,16 @@ Looping Update
Difficulty is increased according to the formula for levels 25+
Snake size goes up by 1 every loop, up to 12
Balance
* Decreased reroll cost to 8
Change cursers to add more curse targets as set bonuses
Decrease reroll cost to 5
* Increased sage's attack speed
Increase spawn marker time
Decrease range and thrown speed for forcers
Decrease damage for blue and white on higher NG
Increase gold rewards at higher NG
QoL
Lowered sound effect for gambler
Selling items
Show cooldown on elite attack
* Options menu from buy screen
* Add main menu
@ -70,6 +76,7 @@ Looping Update
Add visuals divine intervention, fairy buff
Change text for enchanted to "if you have >= 2 enchanters" and change text for reinforce to "if you have >= 1 enchanter"
Bug fixes
Fix barbarian stun just slowing and not stunning
* Fixed fullscreen button and general resolution issues
Fixed a series of crashes that happened rarely right before changing from the arena back to the shop
https://i.imgur.com/Rk6qbDD.png - merchant doesnt give reroll if dies
@ -81,6 +88,7 @@ Looping Update
---
30 refresh rate makes enemies faster?!?!
Future ideas:
Chaos related classes