Loop update 4/5

master
a327ex 2021-07-04 01:50:31 -03:00
parent 894a492cc3
commit 868cae93ed
11 changed files with 228 additions and 135 deletions

View File

@ -380,6 +380,7 @@ function Arena:update(dt)
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()
slow_amount = 1
music_slow_amount = 1
gold = 3
passives = {}
main_song_instance:stop()
@ -388,9 +389,9 @@ function Arena:update(dt)
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'hextouch', 'whispers_of_doom',
'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment',
'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism',
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosense', 'rearm', 'taunt', 'construct_instability',
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosink', 'rearm', 'taunt', 'construct_instability',
'intimidation', 'vulnerability', 'temporal_chains', 'ceremonial_dagger', 'homing_barrage', 'critical_strike', 'noxious_strike', 'infesting_strike', 'burning_strike', 'lucky_strike', 'healing_strike', 'stunning_strike',
'silencing_strike', 'culling_strike', 'lightning_strike', 'psycholeak', 'divine_blessing',
'silencing_strike', 'culling_strike', 'lightning_strike', 'psycholeak', 'divine_blessing', 'hardening',
}
max_units = math.clamp(7 + current_new_game_plus + self.loop, 7, 12)
main:add(BuyScreen'buy_screen')
@ -411,9 +412,7 @@ function Arena:update(dt)
end
self:update_game_object(dt*slow_amount)
if not self.slow_transitioning then
main_song_instance.pitch = math.clamp(slow_amount*self.main_slow_amount, 0.05, 1)
end
main_song_instance.pitch = math.clamp(slow_amount*music_slow_amount, 0.05, 1)
star_group:update(dt*slow_amount)
self.floor:update(dt*slow_amount)
@ -446,6 +445,7 @@ function Arena:quit()
system.save_run()
trigger:tween(1, _G, {slow_amount = 0}, math.linear, function() slow_amount = 0 end, 'slow_amount')
trigger:tween(1, _G, {music_slow_amount = 0}, math.linear, function() music_slow_amount = 0 end, 'music_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.win_text = Text2{group = self.ui, x = gw/2 + 40, y = gh/2 - 69, force_update = true, lines = {{text = '[wavy_mid, cbyc2]congratulations!', font = fat_font, alignment = 'center'}}}
trigger:after(2.5, function()
@ -593,7 +593,7 @@ function Arena:quit()
steam.userStats.storeStats()
end
if self.psyker_level >= 1 then
if self.psyker_level >= 2 then
state.achievement_psykers_win = true
system.save_state()
steam.userStats.setAchievement('PSYKERS_WIN')
@ -684,6 +684,7 @@ function Arena:quit()
input:set_mouse_visible(true)
self.arena_clear_text.dead = true
trigger:tween(1, _G, {slow_amount = 0}, math.linear, function() slow_amount = 0 end, 'slow_amount')
trigger:tween(1, _G, {music_slow_amount = 0}, math.linear, function() music_slow_amount = 0 end, 'music_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 = gh - 40, parent = self, force_update = true}
@ -713,34 +714,39 @@ function Arena:set_passives(from_reroll)
if self.cards[1] then self.cards[1].dead = true end
if self.cards[2] then self.cards[2].dead = true end
if self.cards[3] then self.cards[3].dead = true end
if self.cards[4] then self.cards[4].dead = true end
self.cards = {}
end
local card_w, card_h = 100, 100
local w = 3*card_w + 2*20
local card_w, card_h = 70, 100
local w = 4*card_w + 3*20
self.choosing_passives = true
self.cards = {}
local passive_1 = random:table_remove(run_passive_pool)
local passive_2 = random:table_remove(run_passive_pool)
local passive_3 = random:table_remove(run_passive_pool)
local passive_4 = 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 - 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 - 20, 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, 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 - 20, w = card_w, h = card_h, card_i = 3, arena = self, passive = passive_3, force_update = true})
end
if passive_4 then
table.insert(self.cards, PassiveCard{group = main.current.ui, x = gw/2 - w/2 + 3*(card_w + 20) + card_w/2 + 45, y = gh/2, w = card_w, h = card_h, card_i = 4, arena = self, passive = passive_4, force_update = true})
end
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
if not passive_1 and not passive_2 and not passive_3 and not passive_4 then
self:transition()
end
end
function Arena:restore_passives_to_pool(j)
for i = 1, 3 do
for i = 1, 4 do
if i ~= j then
if self.cards[i] then
table.insert(run_passive_pool, self.cards[i].passive)
@ -814,10 +820,22 @@ function Arena:die()
locked_state = nil
system.save_run()
self.t:tween(2, self, {main_slow_amount = 0}, math.linear, function() self.main_slow_amount = 0 end)
self.t:tween(2, _G, {music_slow_amount = 0}, math.linear, function() music_slow_amount = 0 end)
self.died_text = Text2{group = self.ui, x = gw/2, y = gh/2 - 32, lines = {
{text = '[wavy_mid, cbyc]you died...', font = fat_font, alignment = 'center', height_multiplier = 1.25},
}}
trigger:tween(2, 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.t:after(2, 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'}}}
for i, unit in ipairs(self.units) do
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
for i, passive in ipairs(self.passives) do
ItemCard{group = self.ui, x = 120 + (i-1)*30, y = 30, w = 30, h = 45, sx = 0.75, sy = 0.75, force_update = true, passive = passive.passive , level = passive.level, xp = passive.xp, parent = self}
end
self.death_info_text = Text2{group = self.ui, x = gw/2, y = gh/2, sx = 0.7, sy = 0.7, lines = {
{text = '[wavy_mid, fg]level reached: [wavy_mid, yellow]' .. self.level, font = fat_font, alignment = 'center'},
}}
@ -828,6 +846,7 @@ function Arena:die()
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()
slow_amount = 1
music_slow_amount = 1
gold = 3
passives = {}
main_song_instance:stop()
@ -836,9 +855,9 @@ function Arena:die()
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'hextouch', 'whispers_of_doom',
'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment',
'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism',
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosense', 'rearm', 'taunt', 'construct_instability',
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosink', 'rearm', 'taunt', 'construct_instability',
'intimidation', 'vulnerability', 'temporal_chains', 'ceremonial_dagger', 'homing_barrage', 'critical_strike', 'noxious_strike', 'infesting_strike', 'burning_strike', 'lucky_strike', 'healing_strike', 'stunning_strike',
'silencing_strike', 'culling_strike', 'lightning_strike', 'psycholeak', 'divine_blessing',
'silencing_strike', 'culling_strike', 'lightning_strike', 'psycholeak', 'divine_blessing', 'hardening',
}
max_units = math.clamp(7 + current_new_game_plus + self.loop, 7, 12)
main:add(BuyScreen'buy_screen')
@ -965,6 +984,7 @@ function Arena:transition()
end
end
slow_amount = 1
music_slow_amount = 1
main:add(BuyScreen'buy_screen')
system.save_run(self.level+1, self.loop, gold, self.units, self.passives, self.shop_level, self.shop_xp, run_passive_pool, locked_state)
main:go_to('buy_screen', self.level+1, self.loop, self.units, self.passives, self.shop_level, self.shop_xp)

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

View File

@ -136,6 +136,7 @@ function BuyScreen:on_enter(from, level, loop, units, passives, shop_level, shop
locked_state = nil
TransitionEffect{group = main.transitions, x = gw/2, y = gh/2, color = state.dark_transitions and bg[-2] or fg[0], transition_action = function()
slow_amount = 1
music_slow_amount = 1
gold = 3
passives = {}
main_song_instance:stop()
@ -144,9 +145,9 @@ function BuyScreen:on_enter(from, level, loop, units, passives, shop_level, shop
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'hextouch', 'whispers_of_doom',
'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment',
'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism',
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosense', 'rearm', 'taunt', 'construct_instability',
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosink', 'rearm', 'taunt', 'construct_instability',
'intimidation', 'vulnerability', 'temporal_chains', 'ceremonial_dagger', 'homing_barrage', 'critical_strike', 'noxious_strike', 'infesting_strike', 'burning_strike', 'lucky_strike', 'healing_strike', 'stunning_strike',
'silencing_strike', 'culling_strike', 'lightning_strike', 'psycholeak', 'divine_blessing',
'silencing_strike', 'culling_strike', 'lightning_strike', 'psycholeak', 'divine_blessing', 'hardening',
}
max_units = math.clamp(7 + current_new_game_plus + self.loop, 7, 12)
main:add(BuyScreen'buy_screen')
@ -541,6 +542,7 @@ function RestartButton:update(dt)
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()
slow_amount = 1
music_slow_amount = 1
gold = 3
passives = {}
main_song_instance:stop()
@ -549,9 +551,9 @@ function RestartButton:update(dt)
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'hextouch', 'whispers_of_doom',
'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment',
'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism',
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosense', 'rearm', 'taunt', 'construct_instability',
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosink', 'rearm', 'taunt', 'construct_instability',
'intimidation', 'vulnerability', 'temporal_chains', 'ceremonial_dagger', 'homing_barrage', 'critical_strike', 'noxious_strike', 'infesting_strike', 'burning_strike', 'lucky_strike', 'healing_strike', 'stunning_strike',
'silencing_strike', 'culling_strike', 'lightning_strike', 'psycholeak', 'divine_blessing',
'silencing_strike', 'culling_strike', 'lightning_strike', 'psycholeak', 'divine_blessing', 'hardening',
}
system.save_state()
main:add(BuyScreen'buy_screen')
@ -1330,8 +1332,9 @@ function PassiveCard:update(dt)
self.arena.choosing_passives = false
table.insert(self.arena.passives, {passive = self.passive, level = 1, xp = 0})
self.arena:restore_passives_to_pool(self.card_i)
trigger:tween(0.25, _G, {slow_amount = 1}, math.linear, function()
trigger:tween(0.25, _G, {slow_amount = 1, music_slow_amount = 1}, math.linear, function()
slow_amount = 1
music_slow_amount = 1
self.arena:transition()
end)
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}

View File

@ -29,7 +29,7 @@ function Seeker:init(args)
enemy:speed_boost(3 + self.level*0.025 + current_new_game_plus*0.1)
end
end
end)
end, nil, nil, 'boss_attack')
elseif self.boss == 'forcer' then
self.color = yellow[0]:clone()
@ -76,7 +76,7 @@ function Seeker:init(args)
end
self.px, self.py = nil, nil
end)
end)
end, nil, nil, 'boss_attack')
elseif self.boss == 'swarmer' then
self.color = purple[0]:clone()
@ -92,7 +92,7 @@ function Seeker:init(args)
critter3:play{pitch = random:float(0.95, 1.05), volume = 0.6}
for i = 1, random:int(4, 6) do EnemyCritter{group = main.current.main, x = enemy.x, y = enemy.y, color = purple[0], r = random:float(0, 2*math.pi), v = 8 + 0.1*enemy.level, dmg = 2*enemy.dmg} end
end
end)
end, nil, nil, 'boss_attack')
elseif self.boss == 'exploder' then
self.color = blue[0]:clone()
@ -107,7 +107,7 @@ function Seeker:init(args)
mine1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ExploderMine{group = main.current.main, x = enemy.x, y = enemy.y, color = blue[0], parent = enemy}
end
end)
end, nil, nil, 'boss_attack')
elseif self.boss == 'randomizer' then
self.t:every_immediate(0.07, function() self.color = _G[random:table{'green', 'purple', 'yellow', 'blue'}][0]:clone() end)
@ -158,7 +158,7 @@ function Seeker:init(args)
end
end
end
end)
end, nil, nil, 'boss_attack')
end
else
@ -355,6 +355,13 @@ function Seeker:draw()
end
graphics.pop()
if self.boss then
local t, c = self.t:get_timer_and_delay('boss_attack')
local n = t/c
graphics.line(self.x - self.shape.w/2, self.y + 8, self.x + self.shape.w/2, self.y + 8, bg[-3], 2)
graphics.line(self.x - self.shape.w/2, self.y + 8, self.x - self.shape.w/2 + self.shape.w*n, self.y + 8, self.color, 2)
end
if self.px and self.py then
if self.phidden then return end
graphics.push(self.px, self.py, self.vr, self.spring.x, self.spring.x)
@ -546,6 +553,7 @@ function Seeker:hit(damage, projectile, dot, from_enemy)
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()
@ -553,6 +561,7 @@ function Seeker:hit(damage, projectile, dot, from_enemy)
end)
end
end
]]--
if self.boss then
slow(0.25, 1)

View File

@ -140,12 +140,12 @@ end
function system.save_run(level, loop, gold, units, passives, shop_level, shop_xp, run_passive_pool, locked_state)
local run = {level = level, loop = loop, gold = gold, units = units, passives = passives, shop_level = shop_level, shop_xp = shop_xp, run_passive_pool= run_passive_pool, locked_state = locked_state}
local str = "return " .. table.tostring(run)
love.filesystem.write("run_v3.txt", str)
love.filesystem.write("run_v4.txt", str)
end
function system.load_run()
local chunk = love.filesystem.load("run_v3.txt")
local chunk = love.filesystem.load("run_v4.txt")
if chunk then return chunk()
else return {} end
end

View File

@ -213,6 +213,7 @@ function init()
orbitism = Image('orbitism')
psyker_orbs = Image('psyker_orbs')
psychosense = Image('psychosense')
psychosink = Image('psychosink')
rearm = Image('rearm')
taunt = Image('taunt')
construct_instability = Image('construct_instability')
@ -235,6 +236,7 @@ function init()
lightning_strike = Image('lightning_strike')
psycholeak = Image('psycholeak')
divine_blessing = Image('divine_blessing')
hardening = Image('hardening')
class_colors = {
['warrior'] = yellow[0],
@ -597,7 +599,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]creates [yellow]1[fg] healing orb' end,
['cleric'] = function(lvl) return '[fg]creates [yellow]1[fg] healing orb every [yellow]8[fg] seconds' 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,
@ -612,7 +614,7 @@ function init()
['sentry'] = function(lvl) return '[fg]spawns a rotating turret that shoots [yellow]4[fg] projectiles, each dealing [yellow]' .. get_character_stat('sentry', lvl, 'dmg') .. '[fg] damage' end,
['chronomancer'] = function(lvl) return '[yellow]+20%[fg] attack speed to all allies' end,
['spellblade'] = function(lvl) return '[fg]throws knives that deal [yellow]' .. get_character_stat('spellblade', lvl, 'dmg') .. '[fg] damage, pierce and spiral outwards' end,
['psykeeper'] = function(lvl) return '[fg]creates [yellow]1[fg] healing orb every time the psykeeper takes [yellow]20%[fg] of its max HP in damage' end,
['psykeeper'] = function(lvl) return '[fg]creates [yellow]3[fg] healing orbs every time the psykeeper takes [yellow]25%[fg] of its max HP in damage' end,
['engineer'] = function(lvl) return '[fg]drops sentries that shoot bursts of projectiles, each dealing [yellow]' .. get_character_stat('engineer', lvl, 'dmg') .. '[fg] damage' end,
['plague_doctor'] = function(lvl) return '[fg]creates an area that deals [yellow]' .. get_character_stat('plague_doctor', lvl, 'dmg') .. '[fg] damage per second' end,
['barbarian'] = function(lvl) return '[fg]deals [yellow]' .. get_character_stat('barbarian', lvl, 'dmg') .. '[fg] AoE damage and stuns enemies hit for [yellow]4[fg] seconds' end,
@ -633,7 +635,7 @@ function init()
['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]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,
['priest'] = function(lvl) return '[fg]creates [yellow]3[fg] healing orbs every [yellow]12[fg] seconds' 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,
@ -778,7 +780,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]creates [yellow]4[fg] healing orbs' end,
['cleric'] = function() return '[fg]creates [yellow]4[fg] healing orbs every [yellow]8[fg] seconds' 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,
@ -994,11 +996,11 @@ function init()
['warrior'] = function(lvl) return '[' .. ylb1(lvl) .. ']3[light_bg]/[' .. ylb2(lvl) .. ']6 [fg]- [' .. ylb1(lvl) .. ']+25[light_bg]/[' .. ylb2(lvl) .. ']+50 [fg]defense to allied warriors' end,
['mage'] = function(lvl) return '[' .. ylb1(lvl) .. ']3[light_bg]/[' .. ylb2(lvl) .. ']6 [fg]- [' .. ylb1(lvl) .. ']-15[light_bg]/[' .. ylb2(lvl) .. ']-30 [fg]enemy defense' end,
['rogue'] = function(lvl) return '[' .. ylb1(lvl) .. ']3[light_bg]/[' .. ylb2(lvl) .. ']6 [fg]- [' .. ylb1(lvl) .. ']15%[light_bg]/[' .. ylb2(lvl) .. ']30% [fg]chance to crit to allied rogues, dealing [yellow]4x[] damage' end,
['healer'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+8%[light_bg]/[' .. ylb2(lvl) .. ']+16% [fg] chance for enemies to drop healing orbs on death' end,
['healer'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+15%[light_bg]/[' .. ylb2(lvl) .. ']+30% [fg] chance to create [yellow]+1[fg] healing orb on healing orb creation' end,
['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]construct damage and duration' end,
['psyker'] = function(lvl) return '[fg]create a piercing, damaging orb around each psyker' end,
['psyker'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+2[light_bg]/[' .. ylb2(lvl) .. ']+4 [fg]total psyker orbs and [yellow]+1[fg] orb for each psyker' end,
['curser'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+1[light_bg]/[' .. ylb2(lvl) .. ']+3 [fg]max curse targets to allied cursers' 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,
@ -1135,7 +1137,7 @@ function init()
if number_of_units >= 6 then return 2
elseif number_of_units >= 3 then return 1
else return 0 end
elseif class == 'healer' or class == 'conjurer' or class == 'enchanter' or class == 'curser' or class == 'forcer' or class == 'swarmer' or class == 'voider' or class == 'mercenary' then
elseif class == 'healer' or class == 'conjurer' or class == 'enchanter' or class == 'curser' or class == 'forcer' or class == 'swarmer' or class == 'voider' or class == 'mercenary' or class == 'psyker' then
if number_of_units >= 4 then return 2
elseif number_of_units >= 2 then return 1
else return 0 end
@ -1144,7 +1146,7 @@ function init()
elseif number_of_units >= 4 then return 2
elseif number_of_units >= 2 then return 1
else return 0 end
elseif class == 'explorer' or class == 'psyker' then
elseif class == 'explorer' then
if number_of_units >= 1 then return 1
else return 0 end
end
@ -1186,7 +1188,7 @@ function init()
['healer'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).healer end,
['conjurer'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).conjurer end,
['enchanter'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).enchanter end,
['psyker'] = function(units) return 1, 1, nil, get_number_of_units_per_class(units).psyker end,
['psyker'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).psyker end,
['curser'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).curser end,
['forcer'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).forcer end,
['swarmer'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).swarmer end,
@ -1257,6 +1259,7 @@ function init()
['orbitism'] = 'Orbitism',
['psyker_orbs'] = 'Psyker Orbs',
['psychosense'] = 'Psychosense',
['psychosink'] = 'Psychosink',
['rearm'] = 'Rearm',
['taunt'] = 'Taunt',
['construct_instability'] = 'Construct Instability',
@ -1279,6 +1282,7 @@ function init()
['lightning_strike'] = 'Lightning Strike',
['psycholeak'] = 'Psycholeak',
['divine_blessing'] = 'Divine Blessing',
['hardening'] = 'Hardening',
}
passive_descriptions = {
@ -1330,7 +1334,7 @@ function init()
['freezing_field'] = '[fg]creates an area that slows enemies by [yellow]50%[fg] for [yellow]2[fg] seconds on sorcerer spell repeat',
['burning_field'] = '[fg]creates an area that deals [yellow]30[fg] dps for [yellow]2[fg] seconds on sorcerer spell repeat',
['gravity_field'] = '[fg]creates an area that pulls enemies in for [yellow]1[fg] seconds on sorcerer spell repeat',
['magnetism'] = '[fg]gold coins and healing orbs are attracted to the snake',
['magnetism'] = '[fg]gold coins and healing orbs are attracted to the snake from a longer range',
['insurance'] = "[fg]heroes have [yellow]4[fg] times the chance of mercenary's bonus to drop [yellow]2[fg] gold on death",
['dividends'] = '[fg]mercenaries deal [yellow]+X%[fg] damage, where X is how much gold you have',
['berserking'] = '[fg]all warriors have up to [yellow]+50/75/100%[fg] attack speed based on missing HP',
@ -1339,9 +1343,10 @@ function init()
['blessing'] = '[yellow]+10/20/30%[fg] healing effectiveness',
['haste'] = '[yellow]+50%[fg] movement speed that decays over [yellow]4[fg] seconds on healing orb pick up',
['divine_barrage'] = '[yellow]20/40/60%[fg] chance to release a ricocheting barrage on healing orb pick up',
['orbitism'] = '[yellow]+33/66/99%[fg] orb movement speed',
['psyker_orbs'] = '[yellow]+1/2/3[fg] psyker orbs',
['orbitism'] = '[yellow]+25/50/75%[fg] psyker orb movement speed',
['psyker_orbs'] = '[yellow]+1/2/4[fg] total psyker orbs',
['psychosense'] = '[yellow]+33/66/99%[fg] orb range',
['psychosink'] = '[fg]psyker orbs deal [yellow]+40/80/120%[fg] damage',
['rearm'] = '[fg]constructs repeat their attacks once',
['taunt'] = '[yellow]10/20/30%[fg] chance for constructs to taunt nearby enemies on attack',
['construct_instability'] = '[fg]constructs explode when disappearing, dealing [yellow]100/150/200%[fg] damage',
@ -1364,6 +1369,7 @@ function init()
['lightning_strike'] = '[yellow]5/10/15%[fg] chance for projectiles to create chain lightning, dealing [yellow]60/80/100%[fg] damage',
['psycholeak'] = '[fg]position [yellow]1[fg] generates [yellow]1[fg] psyker orb every [yellow]10[fg] seconds',
['divine_blessing'] = '[fg]generate [yellow]1[fg] healing orb every [yellow]8[fg] seconds',
['hardening'] = '[yellow]+150%[fg] defense to all allies for [yellow]3[fg] seconds after an ally dies',
}
local ts = function(lvl, a, b, c) return '[' .. ylb1(lvl) .. ']' .. tostring(a) .. '[light_bg]/[' .. ylb2(lvl) .. ']' .. tostring(b) .. '[light_bg]/[' .. ylb3(lvl) .. ']' .. tostring(c) .. '[fg]' end
@ -1416,7 +1422,7 @@ function init()
['freezing_field'] = function(lvl) return '[fg]creates an area that slows enemies by [yellow]50%[fg] for [yellow]2[fg] seconds on sorcerer spell repeat' end,
['burning_field'] = function(lvl) return '[fg]creates an area that deals [yellow]30[fg] dps for [yellow]2[fg] seconds on sorcerer spell repeat' end,
['gravity_field'] = function(lvl) return '[fg]creates an area that pulls enemies in for [yellow]1[fg] seconds on sorcerer spell repeat' end,
['magnetism'] = function(lvl) return '[fg]gold coins and healing orbs are attracted to the snake' end,
['magnetism'] = function(lvl) return '[fg]gold coins and healing orbs are attracted to the snake from a longer range' end,
['insurance'] = function(lvl) return "[fg]heroes have [yellow]4[fg] times the chance of mercenary's bonus to drop [yellow]2[fg] gold on death" end,
['dividends'] = function(lvl) return '[fg]mercenaries deal [yellow]+X%[fg] damage, where X is how much gold you have' end,
['berserking'] = function(lvl) return '[fg]all warriors have up to ' .. ts(lvl, '+50%', '75%', '100%') .. ' attack speed based on missing HP' end,
@ -1425,9 +1431,10 @@ function init()
['blessing'] = function(lvl) return ts(lvl, '+10%', '20%', '30%') .. ' healing effectiveness' end,
['haste'] = function(lvl) return '[yellow]+50%[fg] movement speed that decays over [yellow]4[fg] seconds on healing orb pick up' end,
['divine_barrage'] = function(lvl) return ts(lvl, '20%', '40%', '60%') .. ' chance to release a ricocheting barrage on healing orb pick up' end,
['orbitism'] = function(lvl) return ts(lvl, '+33%', '66%', '99%') .. ' orb movement speed' end,
['orbitism'] = function(lvl) return ts(lvl, '+25%', '50%', '75%') .. ' psyker orb movement speed' end,
['psyker_orbs'] = function(lvl) return ts(lvl, '+1', '2', '3') .. ' psyker orbs' end,
['psychosense'] = function(lvl) return ts(lvl, '+33%', '66%', '99%') .. ' orb range' end,
['psychosink'] = function(lvl) return '[fg]psyker orbs deal ' .. ts(lvl, '+40%', '80%', '120%') .. ' damage' end,
['rearm'] = function(lvl) return '[fg]constructs repeat their attacks once' end,
['taunt'] = function(lvl) return ts(lvl, '10%', '20%', '30%') .. ' chance for constructs to taunt nearby enemies on attack' end,
['construct_instability'] = function(lvl) return '[fg]constructs explode when disappearing, dealing ' .. ts(lvl, '100', '150', '200%') .. ' damage' end,
@ -1450,6 +1457,7 @@ function init()
['lightning_strike'] = function(lvl) return ts(lvl, '5', '10', '15%') .. ' chance for projectiles to create chain lightning, dealing ' .. ts(lvl, '60', '80', '100%') .. ' damage' end,
['psycholeak'] = function(lvl) return '[fg]position [yellow]1[fg] generates [yellow]1[fg] psyker orb every [yellow]10[fg] seconds' end,
['divine_blessing'] = function(lvl) return '[fg]generate [yellow]1[fg] healing orb every [yellow]8[fg] seconds' end,
['hardening'] = function(lvl) return '[yellow]+150%[fg] defense to all allies for [yellow]3[fg] seconds after an ally dies' end,
}
level_to_tier_weights = {
@ -1685,7 +1693,7 @@ function init()
unlevellable_items = {
'speed_3', 'damage_4', 'shoot_5', 'death_6', 'lasting_7', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'annihilation',
'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'divine_punishment', 'unleash', 'freezing_field', 'burning_field', 'gravity_field',
'magnetism', 'insurance', 'dividends', 'haste', 'rearm', 'ceremonial_dagger', 'burning_strike', 'lucky_strike', 'healing_strike', 'psycholeak', 'divine_blessing'
'magnetism', 'insurance', 'dividends', 'haste', 'rearm', 'ceremonial_dagger', 'burning_strike', 'lucky_strike', 'healing_strike', 'psycholeak', 'divine_blessing', 'hardening',
}
steam.userStats.requestCurrentStats()
@ -1698,10 +1706,8 @@ 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')
@ -1709,25 +1715,30 @@ function init()
-- main:go_to('buy_screen', 7, run.units or {}, {'unleash'})
]]--
--[[
gold = 10
run_passive_pool = {
'centipede', 'ouroboros_technique_r', 'ouroboros_technique_l', 'amplify', 'resonance', 'ballista', 'call_of_the_void', 'crucio', 'speed_3', 'damage_4', 'shoot_5', 'death_6', 'lasting_7',
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'hextouch', 'whispers_of_doom',
'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment',
'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism',
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosense', 'rearm', 'taunt', 'construct_instability',
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosink', 'rearm', 'taunt', 'construct_instability',
'intimidation', 'vulnerability', 'temporal_chains', 'ceremonial_dagger', 'homing_barrage', 'critical_strike', 'noxious_strike', 'infesting_strike', 'burning_strike', 'lucky_strike', 'healing_strike', 'stunning_strike',
'silencing_strike', 'culling_strike', 'lightning_strike', 'psycholeak', 'divine_blessing',
'silencing_strike', 'culling_strike', 'lightning_strike', 'psycholeak', 'divine_blessing', 'hardening',
}
main:add(Arena'arena')
main:go_to('arena', 2, 0, {
{character = 'carver', level = 3},
-- {character = 'carver', level = 2},
-- {character = 'saboteur', level = 2},
-- {character = 'hunter', level = 2},
main:go_to('arena', 6, 0, {
{character = 'cleric', level = 1},
{character = 'priest', level = 3},
{character = 'carver', level = 1},
{character = 'psykeeper', level = 1},
{character = 'fairy', level = 3},
}, {
{passive = 'rearm', level = 1},
{passive = 'psychosink', level = 3},
{passive = 'psyker_orbs', level = 3},
{passive = 'awakening', level = 3},
})
]]--
--[[
main:add(Media'media')
@ -1897,7 +1908,7 @@ function open_options(self)
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'hextouch', 'whispers_of_doom',
'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment',
'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism',
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosense', 'rearm', 'taunt', 'construct_instability',
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosink', 'rearm', 'taunt', 'construct_instability',
}
max_units = 7 + current_new_game_plus
main:add(BuyScreen'buy_screen')

View File

@ -63,7 +63,7 @@ function MainMenu:on_enter(from)
end)
self.units = {
{character = 'vagrant', level = 1},
{character = 'psykino', level = 1},
{character = 'magician', level = 1},
{character = 'bane', level = 1},
{character = 'scout', level = 1},

View File

@ -24,7 +24,7 @@ function Player:init(args)
end, nil, nil, 'shoot')
elseif self.character == 'swordsman' then
self.attack_sensor = Circle(self.x, self.y, 64)
self.attack_sensor = Circle(self.x, self.y, 48)
self.t:cooldown(3, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
self:attack(96)
end, nil, nil, 'attack')
@ -458,12 +458,14 @@ function Player:init(args)
end, nil, nil, 'attack')
elseif self.character == 'barbarian' then
self.t:every(8, function()
self.attack_sensor = Circle(self.x, self.y, 48)
self.t:cooldown(8, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
self:attack(96, {stun = 4})
end, nil, nil, 'attack')
elseif self.character == 'juggernaut' then
self.t:every(8, function()
self.attack_sensor = Circle(self.x, self.y, 64)
self.t:cooldown(8, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
self:attack(128, {juggernaut_push = true})
end, nil, nil, 'attack')
@ -662,7 +664,7 @@ function Player:init(args)
end, nil, nil, 'shoot')
elseif self.character == 'highlander' then
self.attack_sensor = Circle(self.x, self.y, 48)
self.attack_sensor = Circle(self.x, self.y, 36)
self.t:cooldown(4, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
if self.level == 3 then
self.t:every(0.25, function()
@ -681,11 +683,13 @@ function Player:init(args)
local unit_2 = random:table_remove(units)
if unit_1 then
unit_1.fairy_aspd_m = 3
unit_1.t:after(5.98, function() unit_1.fairy_aspd_m = 1 end)
unit_1.fairyd = true
unit_1.t:after(5.98, function() unit_1.fairy_aspd_m = 1; unit_1.fairyd = false end)
end
if unit_2 then
unit_2.fairy_aspd_m = 3
unit_2.t:after(5.98, function() unit_2.fairy_aspd_m = 1 end)
unit_2.fairyd = true
unit_2.t:after(5.98, function() unit_2.fairy_aspd_m = 1; unit_2.fairyd = false 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}
@ -708,8 +712,9 @@ function Player:init(args)
else
local unit = random:table(self:get_all_units())
if unit then
unit.fairyd = true
unit.fairy_aspd_m = 2
unit.t:after(5.98, function() unit.fairy_aspd_m = 1 end)
unit.t:after(5.98, function() unit.fairy_aspd_m = 1; unit.fairyd = false 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}
@ -801,9 +806,9 @@ function Player:init(args)
end)
end
self.t:every(15, function()
self.t:every(12, 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
for i = 1, 3 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, Volcano, Saboteur, Bomb, Pet, Turret, Sentry, Automaton})
@ -1067,7 +1072,7 @@ function Player:init(args)
end
if self.leader then
self.t:after(0.5, function()
self.t:after(1, function()
local units = self:get_all_units()
for _, unit in ipairs(units) do
if table.any(unit.classes, function(v) return v == 'psyker' end) then
@ -1075,9 +1080,21 @@ function Player:init(args)
end
end
local psykers = {}
for _, unit in ipairs(units) do
if table.any(unit.classes, function(v) return v == 'psyker' end) then
table.insert(psykers, unit)
end
end
for i = 1, ((main.current.psyker_level == 2 and 4) or (main.current.psyker_level == 1 and 2) or (main.current.psyker_level == 0 and 0) or 0) do
local unit = random:table(#psykers > 0 and psykers or units)
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
if self.psyker_orbs then
for i = 1, self.psyker_orbs do
local unit = random:table(units)
for i = 1, ((self.psyker_orbs == 1 and 1) or (self.psyker_orbs == 2 and 2) or (self.psyker_orbs == 3 and 4) or 0) do
local unit = random:table(#psykers > 0 and psykers or units)
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
@ -1302,7 +1319,7 @@ function Player:update(dt)
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.explorer_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)*(self.explorer_dmg_m or 1)
self.buff_def_m = (self.squire_def_m or 1)*(self.ouroboros_def_m or 1)*(self.unwavering_stance_def_m or 1)*(self.reinforce_def_m or 1)*(self.defensive_stance_def_m or 1)*(self.last_stand_def_m or 1)*(self.unrelenting_stance_def_m or 1)
self.buff_def_m = (self.squire_def_m or 1)*(self.ouroboros_def_m or 1)*(self.unwavering_stance_def_m or 1)*(self.reinforce_def_m or 1)*(self.defensive_stance_def_m or 1)*(self.last_stand_def_m or 1)*(self.unrelenting_stance_def_m or 1)*(self.hardening_def_m or 1)
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.haste_mvspd_m or 1)
@ -1413,6 +1430,14 @@ function Player:draw()
if self.ouroboros_def_m and self.ouroboros_def_m > 1 then
graphics.rectangle(self.x, self.y, 1.25*self.shape.w, 1.25*self.shape.h, 3, 3, yellow_transparent)
end
if self.divined then
graphics.rectangle(self.x, self.y, 1.25*self.shape.w, 1.25*self.shape.h, 3, 3, green_transparent)
end
if self.fairyd then
graphics.rectangle(self.x, self.y, 1.25*self.shape.w, 1.25*self.shape.h, 3, 3, blue_transparent)
end
end
graphics.pop()
end
@ -1525,7 +1550,7 @@ function Player:hit(damage, from_undead)
if self.character == 'psykeeper' then
self.stored_heal = self.stored_heal + actual_damage
if self.stored_heal > (0.2*self.max_hp) then
if self.stored_heal > (0.25*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, Volcano, Saboteur, Bomb, Pet, Turret, Sentry, Automaton})
@ -1533,6 +1558,7 @@ function Player:hit(damage, from_undead)
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, Volcano, Saboteur, Bomb, Pet, Turret, Sentry, Automaton})
end
for i = 1, 3 do
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, Sentry, Volcano, Saboteur, Bomb, Pet, Turret, Automaton})
@ -1541,6 +1567,7 @@ function Player:hit(damage, from_undead)
end
end}
end
end
if self.level == 3 then
local enemies = main.current.main:get_objects_by_classes(main.current.enemies)
@ -1609,6 +1636,14 @@ function Player:hit(damage, from_undead)
end)
end
if self.hardening then
local units = self:get_all_units()
for _, unit in ipairs(units) do
unit.hardening_def_m = 2.5
unit.t:after(3, function() unit.hardening_def_m = 1 end)
end
end
if self.annihilation and table.any(self.classes, function(v) return v == 'voider' end) then
local enemies = self.group:get_objects_by_classes({Seeker, EnemyCritter})
for _, enemy in ipairs(enemies) do
@ -1921,7 +1956,7 @@ Projectile:implement(Physics)
function Projectile:init(args)
self:init_game_object(args)
self.hfx:add('hit', 1)
self:set_as_rectangle(10, 4, 'dynamic', main.current.player.warping_shots and 'true_ghost' or 'projectile')
self:set_as_rectangle(10, 4, 'dynamic', 'projectile')
self.pierce = args.pierce or 0
self.chain = args.chain or 0
self.ricochet = args.ricochet or 0
@ -1976,9 +2011,10 @@ function Projectile:init(args)
elseif self.character == 'psyker' then
self.pierce = 10000
self.orbit_distance = random:float(32, 40)*((self.parent.psychosense == 1 and 1.33) or (self.parent.psychosense == 2 and 1.66) or (self.parent.psychosense == 3 and 1.99) or 1)
self.orbit_speed = random:float(4, 6)*((self.parent.orbitism == 1 and 1.33) or (self.parent.orbitism == 2 and 1.66) or (self.parent.orbitism == 3 and 1.99) or 1)
self.orbit_distance = random:float(56, 64)
self.orbit_speed = random:float(2, 4)*((self.parent.orbitism == 1 and 1.25) or (self.parent.orbitism == 2 and 1.50) or (self.parent.orbitism == 3 and 1.75) or 1)*(1/self.parent.aspd_m)
self.orbit_offset = random:float(0, 2*math.pi)
self.dmg = self.dmg*((self.parent.psychosink == 1 and 1.4) or (self.parent.psychosink == 2 and 1.8) or (self.parent.psychosink == 3 and 2.2) or 1)
elseif self.character == 'lich' then
self.spring:pull(0.15)
@ -2048,8 +2084,8 @@ function Projectile:update(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))
self:set_position(self.parent.x + self.orbit_distance*math.cos(self.orbit_speed*main.current.t.time + self.orbit_offset),
self.parent.y + self.orbit_distance*math.sin(self.orbit_speed*main.current.t.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)
@ -3070,7 +3106,7 @@ function Sentry:init(args)
archer1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
HitCircle{group = main.current.effects, x = self.x + 0.8*self.shape.w*math.cos(r), y = self.y + 0.8*self.shape.w*math.sin(r), rs = 6}
local t = {group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(r), y = self.y + 1.6*self.shape.w*math.sin(r), v = 200, r = r, color = self.color,
dmg = self.parent.dmg*(self.parent.conjurer_buff_m or 1), character = 'sentry', parent = self.parent}
dmg = self.parent.dmg*(self.parent.conjurer_buff_m or 1), character = 'sentry', parent = self.parent, ricochet = self.parent.level == 3 and 2 or 0}
Projectile(table.merge(t, mods or {}))
r = r + math.pi/2
end
@ -3093,7 +3129,7 @@ function Sentry:init(args)
archer1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
HitCircle{group = main.current.effects, x = self.x + 0.8*self.shape.w*math.cos(r), y = self.y + 0.8*self.shape.w*math.sin(r), rs = 6}
local t = {group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(r), y = self.y + 1.6*self.shape.w*math.sin(r), v = 200, r = r, color = self.color,
dmg = self.parent.dmg*(self.parent.conjurer_buff_m or 1), character = 'sentry', parent = self.parent}
dmg = self.parent.dmg*(self.parent.conjurer_buff_m or 1), character = 'sentry', parent = self.parent, ricochet = self.parent.level == 3 and 2 or 0}
Projectile(table.merge(t, mods or {}))
r = r + math.pi/2
end
@ -3109,7 +3145,7 @@ function Sentry:init(args)
end
end)
end
end)
end, nil, nil, 'attack')
end
@ -3117,6 +3153,7 @@ function Sentry:update(dt)
self:update_game_object(dt)
self.r = self.r + math.pi*dt
self:set_angle(self.r)
self.t:set_every_multiplier('attack', self.parent.level == 3 and 0.75 or 1)
end
@ -3606,7 +3643,8 @@ function Gold:init(args)
self.cant_be_picked_up = true
self.t:after(0.5, function() self.cant_be_picked_up = false end)
gold1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
self.magnet_sensor = Circle(self.x, self.y, 32)
self.weak_magnet_sensor = Circle(self.x, self.y, 16)
self.magnet_sensor = Circle(self.x, self.y, 56)
end
@ -3614,8 +3652,7 @@ function Gold:update(dt)
self:update_game_object(dt)
self.r = self:get_angle()
if main.current.player.magnetism and self.magnet_sensor then
local players = self:get_objects_in_shape(self.magnet_sensor, {Player})
local players = self:get_objects_in_shape(main.current.player.magnetism and self.magnet_sensor or self.weak_magnet_sensor, {Player})
if players and #players > 0 then
local x, y = 0, 0
for _, p in ipairs(players) do
@ -3627,8 +3664,8 @@ function Gold:update(dt)
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
if self.weak_magnet_sensor then self.weak_magnet_sensor:move_to(self.x, self.y) end
end
@ -3710,7 +3747,16 @@ function HealingOrb:init(args)
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)
self.weak_magnet_sensor = Circle(self.x, self.y, 16)
self.magnet_sensor = Circle(self.x, self.y, 56)
if main.current.healer_level > 0 and not self.healer_effect_orb then
if random:bool((main.current.healer_level == 1 and 15) or (main.current.healer_level == 2 and 30)) then
SpawnEffect{group = main.current.effects, x = self.x, y = self.y, color = green[0], action = function(x, y)
HealingOrb{group = main.current.main, x = x, y = y, healer_effect_orb = true}
end}
end
end
end
@ -3718,8 +3764,7 @@ 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})
local players = self:get_objects_in_shape(main.current.player.magnetism and self.magnet_sensor or self.weak_magnet_sensor, {Player})
if players and #players > 0 then
local x, y = 0, 0
for _, p in ipairs(players) do
@ -3731,8 +3776,8 @@ function HealingOrb:update(dt)
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
if self.weak_magnet_sensor then self.weak_magnet_sensor:move_to(self.x, self.y) end
end
@ -3757,16 +3802,17 @@ function HealingOrb:on_trigger_enter(other, contact)
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
local units = other:get_all_units()
local lowest_hp = 10000
local lowest_hp = 10
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
local r = unit.hp/unit.max_hp
if r < lowest_hp then
lowest_hp = r
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))
lowest_unit:heal(0.2*lowest_unit.max_hp*(lowest_unit.heal_effect_m or 1))
end
if main.current.player.haste then

View File

@ -29,6 +29,7 @@ function shared_init()
graphics.set_background_color(bg[0])
graphics.set_color(fg[0])
slow_amount = 1
music_slow_amount = 1
sfx = SoundTag()
sfx.volume = state.sfx_volume or 0.5
@ -105,7 +106,7 @@ function Star:init(args)
self.sx, self.sy = 0.35, 0.35
self.vr = 0
self.dvr = random:float(0, math.pi/4)
self.v = random:float(0.5, 0.7)
self.v = random:float(30, 42)
end

49
todo
View File

@ -17,27 +17,26 @@ Loop Update
* Silencing Strike - 8/16/24% chance for attacks to silence for 4 seconds on hit
* Culling Strike - instantly kill elites below 10/20/30% max HP
* Lightning Strike - 5/10/15% chance for projectiles to create chain lightning, dealing 60/80/100% damage
* Psycholeak - Position 1 generates 1 psyker orb every 10 seconds
* Psycholeak - position 1 generates 1 psyker orb every 10 seconds
* Divine Blessing - generate 1 healing orb every 8 seconds
* Hardening - +150% defense for 3 seconds after an ally dies
Psyker
Additional orbs will prefer to be assigned to psykers, if there are no psykers then they will be assigned randomly
Orb speed scales with the unit's attack speed
Increase default orb range
Decrease default and maximum orb speed
Increased orb damage
Psyker class bonus: +2/+4 total orbs
Remove Psychosense
Add "Orbs shoot projectiles"
* Orb speed scales with the unit's attack speed
* Increased default orb range
* Decreased default orb speed
* Additional psyker orbs will prefer to be assigned to psykers, if there are no psykers then they will be assigned to units randomly
* Changed psyker class bonus: +2/4 total orbs
* Removed Psychosense
* Added Psychosink - psyker orbs deal +40/80/120% damage
Healer
Double healing per orb
Fix heal targetting, should always target lowest HP unit
Some solution that:
Increases amount of orbs dropped with only 1 or 2 healers
Decreases amount of orbs dropped on full build
Healing orbs are slightly attracted to the snake
* Double healing per orb
* Fixed heal targetting, now it should always target the lowest HP unit
* Healing orbs and gold coins are now slightly attracted to the snake with a weak magnetism effect
* Changed healer class bonus: +15/30% chance to create an additional healing orb on healing orb creation
* Psykeeper: spawn 3 healing orbs every time the psykeeper takes 25% of max HP in damage
Warriors
Increase sensor range
Set juggernaut and barbarian's attacks on :cooldown calls
* Decreased sensor range for all warriors, this will make them attack only when enemies are closer and consequently make it so that they hit more enemies in general
* Juggernaut and barbarian now only attack when there are enemies nearby
Builders
* Carver (builder, healer) - creates a tree that creates 1 healing orb every 6 seconds, Lv.3 effect: healing orbs are created twice as fast
* Engineer (builder): unchanged
@ -52,18 +51,17 @@ Loop Update
* Snake size goes up by 1 every loop, up to 12
* Don't offer items if at maximum items
QoL
Increase item choice slots to 4
Add option for mouse cursor to always be visible
Show cooldown on elite attack
Add visuals divine intervention, fairy buff
Party + items on death screen
Default to mouse controls
* Show cooldown on elite attack
* Added visuals for divine intervention and fairy buffs
* Increased item choice slots to 4
* Party + items on death screen
* Silenced units are now gray
* Items on end screen
* Items on passive screen
* Selling items
* Decreased sound effect volume for shoot 5
Bug fixes
Fix stars
* Fixed a series of crashes that happened sometimes right before changing from the arena back to the shop
* Fixed merchant not giving interest or free reroll if it died in combat
* Fixed shoot 5 and death 6 not working if a unit placed before it on the snake died
@ -75,6 +73,10 @@ Loop Update
* Fixed a bug where movement speed would become zero if the game was paused while under the effects of decaying haste
* Fixed baneling burst not dealing the correct amount of damage
Weekly maintenance updates:
---
Invoker - casts attacks and spells from other units
@ -123,6 +125,7 @@ Enemy ideas - https://steamcommunity.com/app/915310/discussions/0/30697477836918
Unit ideas - https://i.imgur.com/VNMS2YV.png
Unit ideas - https://steamcommunity.com/app/915310/discussions/0/3069747783693969554/
Unit ideas - https://steamcommunity.com/app/915310/discussions/0/3046104336668792953/
Achievement ideas - https://i.imgur.com/Q7jHWB2.png, https://i.imgur.com/2l5eist.png
Draft system
Ban system