Item update 5/5

master
a327ex 2021-06-18 18:36:00 -03:00
parent 408eaaf54e
commit 0496138d70
9 changed files with 178 additions and 100 deletions

View File

@ -53,6 +53,8 @@ function Arena:on_enter(from, level, units, passives, shop_level, shop_xp, lock)
self.main:enable_trigger_between('projectile', 'enemy')
self.main:enable_trigger_between('enemy_projectile', 'player')
self.main:enable_trigger_between('player', 'enemy_projectile')
self.main:enable_trigger_between('enemy_projectile', 'enemy')
self.main:enable_trigger_between('enemy', 'enemy_projectile')
self.main:enable_trigger_between('player', 'ghost')
self.main:enable_trigger_between('ghost', 'player')
@ -407,7 +409,7 @@ function Arena:update(dt)
main:add(BuyScreen'buy_screen')
locked_state = nil
system.save_run()
main:go_to('buy_screen', 0, {}, passives, 1, 0)
main:go_to('buy_screen', 1, {}, passives, 1, 0)
end, text = Text({{text = '[wavy, ' .. tostring(state.dark_transitions and 'fg' or 'bg') .. ']restarting...', font = pixul_font, alignment = 'center'}}, global_text_tags)}
end}
@ -595,7 +597,7 @@ function Arena:update(dt)
main:add(BuyScreen'buy_screen')
locked_state = nil
system.save_run()
main:go_to('buy_screen', 0, {}, passives, 1, 0)
main:go_to('buy_screen', 1, {}, passives, 1, 0)
end, text = Text({{text = '[wavy, ' .. tostring(state.dark_transitions and 'fg' or 'bg') .. ']restarting...', font = pixul_font, alignment = 'center'}}, global_text_tags)}
end
@ -863,8 +865,16 @@ 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 = 40, y = 40, parent = self, force_update = true}
RerollButton{group = main.current.ui, x = gw - 40, y = 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'}}}
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
else
self:transition()
end
@ -890,15 +900,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, y = gh/2 - 6, 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 - 6 + 10, 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, y = gh/2 - 6, 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 - 6 + 10, 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, y = gh/2 - 6, 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 - 6 + 10, 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, y = gh/2 - 65, 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 - 65 + 10, 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
@ -965,7 +975,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(40, 20) end
if self.shop_text then self.shop_text:draw(gw - 40, 20) 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()
@ -1007,7 +1017,7 @@ function Arena:die()
max_units = 7 + current_new_game_plus
main:add(BuyScreen'buy_screen')
system.save_run()
main:go_to('buy_screen', 0, {}, passives, 1, 0)
main:go_to('buy_screen', 1, {}, passives, 1, 0)
end, text = Text({{text = '[wavy, ' .. tostring(state.dark_transitions and 'fg' or 'bg') .. ']restarting...', font = pixul_font, alignment = 'center'}}, global_text_tags)}
end}
end)
@ -1078,7 +1088,7 @@ end
function Arena:gain_gold()
local merchant = self.player:get_unit'merchant'
self.gold_gained = random:int(level_to_gold_gained[self.level][1], level_to_gold_gained[self.level][2])
self.interest = math.min(math.floor(gold/5), 5) + (merchant and math.floor(gold/10) or 0)
self.interest = math.min(math.floor(gold/5), 5) + math.min((merchant and math.floor(gold/10) or 0), 10)
gold = gold + self.gold_gained + self.gold_picked_up + self.interest
end
@ -1103,8 +1113,8 @@ function Arena:transition()
end
slow_amount = 1
main:add(BuyScreen'buy_screen')
system.save_run(self.level, gold, self.units, self.passives, self.shop_level, self.shop_xp, run_passive_pool, locked_state)
main:go_to('buy_screen', self.level, self.units, self.passives, self.shop_level, self.shop_xp)
system.save_run(self.level+1, 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.units, self.passives, self.shop_level, self.shop_xp)
t.t:after(0.1, function()
t.text:set_text({
{text = '[nudge_down, ' .. tostring(state.dark_transitions and 'fg' or 'bg') .. ']gold gained: ' .. tostring(self.gold_gained or 0) .. ' + ' .. tostring(self.gold_picked_up or 0), font = pixul_font,

Binary file not shown.

View File

@ -48,10 +48,7 @@ function BuyScreen:on_enter(from, level, units, passives, shop_level, shop_xp)
input:set_mouse_visible(true)
if self.level == 0 then
main_song_instance = _G[random:table{'song1', 'song2', 'song3', 'song4', 'song5'}]:play{volume = 0.5}
self.level = 1
self.first_screen = true
if self.level == 1 then
end
steam.friends.setRichPresence('steam_display', '#StatusFull')
@ -79,9 +76,9 @@ function BuyScreen:on_enter(from, level, units, passives, shop_level, shop_xp)
elseif lvl % 3 == 0 then return ' (hard)'
else return '' end
end
self.level_text = Text({{text = '[fg]Lv.' .. tostring(level == 0 and 1 or self.level+1) .. get_elite_str(self.level+1), font = pixul_font, alignment = 'center'}}, global_text_tags)
self.level_text = Text({{text = '[fg]Lv.' .. tostring(self.level) .. get_elite_str(self.level), font = pixul_font, alignment = 'center'}}, global_text_tags)
if not self.first_screen then RerollButton{group = self.main, x = 150, y = 18, parent = self} end
RerollButton{group = self.main, x = 150, y = 18, parent = self}
GoButton{group = self.main, x = gw - 90, y = gh - 20, parent = self}
LevelButton{group = self.main, x = gw/2, y = 18, parent = self}
self.tutorial_button = Button{group = self.main, x = gw/2 + 134, y = 18, button_text = '?', fg_color = 'bg10', bg_color = 'bg', action = function()
@ -152,7 +149,7 @@ function BuyScreen:on_enter(from, level, units, passives, shop_level, shop_xp)
max_units = 7 + current_new_game_plus
main:add(BuyScreen'buy_screen')
system.save_run()
main:go_to('buy_screen', 0, {}, passives, 1, 0)
main:go_to('buy_screen', 1, {}, passives, 1, 0)
end, text = Text({{text = '[wavy, ' .. tostring(state.dark_transitions and 'fg' or 'bg') .. ']restarting...', font = pixul_font, alignment = 'center'}}, global_text_tags)}
end, mouse_enter = function(b)
b.info_text = InfoText{group = main.current.ui, force_update = true}
@ -177,6 +174,9 @@ function BuyScreen:on_enter(from, level, units, passives, shop_level, shop_xp)
self.t:tween(0.2, self.screen_text, {sy = 0}, math.linear, function() self.screen_text.sy = 0 end)
end)
end
locked_state = {locked = self.locked, cards = {self.cards[1] and self.cards[1].unit, self.cards[2] and self.cards[2].unit, self.cards[3] and self.cards[3].unit}}
system.save_run(self.level, gold, self.units, self.passives, self.shop_level, self.shop_xp, run_passive_pool, locked_state)
end
@ -345,7 +345,7 @@ function BuyScreen:set_cards(shop_level, dont_spawn_effect, first_call)
unit_3 = random:table(tier_to_characters[random:weighted_pick(unpack(tier_weights))])
all_units = {unit_1, unit_2, unit_3}
until not table.all(all_units, function(v) return table.any(non_attacking_characters, function(u) return v == u end) end)
if first_call and self.locked then
if first_call and locked_state then
if locked_state.cards[1] then self.cards[1] = ShopCard{group = self.main, x = 60, y = 75, w = 80, h = 90, unit = locked_state.cards[1], parent = self, i = 1} end
if locked_state.cards[2] then self.cards[2] = ShopCard{group = self.main, x = 140, y = 75, w = 80, h = 90, unit = locked_state.cards[2], parent = self, i = 2} end
if locked_state.cards[3] then self.cards[3] = ShopCard{group = self.main, x = 220, y = 75, w = 80, h = 90, unit = locked_state.cards[3], parent = self, i = 3} end
@ -539,7 +539,7 @@ function RestartButton:update(dt)
system.save_state()
main:add(BuyScreen'buy_screen')
system.save_run()
main:go_to('buy_screen', 0, {}, passives, 1, 0)
main:go_to('buy_screen', 1, {}, passives, 1, 0)
end, text = Text({{text = '[wavy, ' .. tostring(state.dark_transitions and 'fg' or 'bg') .. ']restarting...', font = pixul_font, alignment = 'center'}}, global_text_tags)}
end
end
@ -685,11 +685,11 @@ function GoButton:update(dt)
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_transition1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
self.transitioning = true
system.save_run(self.parent.level, gold, self.parent.units, passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool, locked_state)
system.save_run(self.parent.level, gold, self.parent.units, self.parent.passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool, locked_state)
TransitionEffect{group = main.transitions, x = self.x, y = self.y, color = state.dark_transitions and bg[-2] or character_colors[random:table(self.parent.units).character], transition_action = function()
main:add(Arena'arena')
main:go_to('arena', ((self.parent.first_screen and 1) or (self.parent.level + 1)), self.parent.units, self.parent.passives, self.parent.shop_level, self.parent.shop_xp, self.parent.locked)
end, text = Text({{text = '[wavy, ' .. tostring(state.dark_transitions and 'fg' or 'bg') .. ']level ' .. ((self.parent.first_screen and 1) or (self.parent.level + 1)) .. '/25', font = pixul_font, alignment = 'center'}}, global_text_tags)}
main:go_to('arena', self.parent.level, self.parent.units, self.parent.passives, self.parent.shop_level, self.parent.shop_xp, self.parent.locked)
end, text = Text({{text = '[wavy, ' .. tostring(state.dark_transitions and 'fg' or 'bg') .. ']level ' .. tostring(self.parent.level) .. '/25', font = pixul_font, alignment = 'center'}}, global_text_tags)}
end
end
end
@ -739,7 +739,7 @@ function LockButton:update(dt)
if not self.parent.locked then locked_state = nil end
if self.parent.locked then
locked_state = {locked = true, cards = {self.parent.cards[1] and self.parent.cards[1].unit, self.parent.cards[2] and self.parent.cards[2].unit, self.parent.cards[3] and self.parent.cards[3].unit}}
system.save_run(self.parent.level == 1 and 0 or self.parent.level, gold, self.parent.units, passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool, locked_state)
system.save_run(self.parent.level, gold, self.parent.units, self.parent.passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool, locked_state)
end
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
self.selected = true
@ -820,7 +820,7 @@ function LevelButton:update(dt)
gold = gold - 5
self.parent.shop_text:set_text{{text = '[wavy_mid, fg]shop [fg]- [fg, nudge_down]gold: [yellow, nudge_down]' .. gold, font = pixul_font, alignment = 'center'}}
self.text = Text({{text = '[bg10]' .. tostring(self.parent.shop_level), font = pixul_font, alignment = 'center'}}, global_text_tags)
system.save_run(self.parent.level, gold, self.parent.units, passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool, locked_state)
system.save_run(self.parent.level, gold, self.parent.units, self.parent.passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool, locked_state)
end
end
end
@ -950,7 +950,7 @@ function RerollButton:update(dt)
self.spring:pull(0.2, 200, 10)
gold = gold - 2
self.parent.shop_text:set_text{{text = '[wavy_mid, fg]shop [fg]- [fg, nudge_down]gold: [yellow, nudge_down]' .. gold, font = pixul_font, alignment = 'center'}}
system.save_run(self.parent.level, gold, self.parent.units, passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool, locked_state)
system.save_run(self.parent.level, gold, self.parent.units, self.parent.passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool, locked_state)
end
elseif self.parent:is(Arena) then
if gold < 10 and not self.free_reroll then
@ -1154,12 +1154,14 @@ function CharacterPart:update(dt)
self:die()
self.parent:set_party_and_sets()
self.parent:refresh_cards()
system.save_run(self.parent.level, gold, self.parent.units, self.parent.passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool, locked_state)
else
self.parent.parent:gain_gold(self:get_sale_price())
self.parent.parent.units[self.i].reserve[self.level] = self.parent.parent.units[self.i].reserve[self.level] - 1
self:die()
self.parent.parent:set_party_and_sets()
self.parent.parent:refresh_cards()
system.save_run(self.parent.parent.level, gold, self.parent.parent.units, self.parent.parent.passives, self.parent.parent.shop_level, self.parent.parent.shop_xp, run_passive_pool, locked_state)
end
end
@ -1330,7 +1332,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 + 12
self.info_text.x, self.info_text.y = gw/2, gh/2 + gh/4 + 22
end
@ -1399,7 +1401,7 @@ function ItemCard:update(dt)
self.selected = true
self.spring:pull(0.2, 200, 10)
gold = gold - 5
for _, passive in ipairs(passives) do
for _, passive in ipairs(self.parent.passives) do
if passive.passive == self.passive then
passive.level = self.level
passive.xp = self.xp
@ -1407,7 +1409,7 @@ function ItemCard:update(dt)
end
self.parent.shop_text:set_text{{text = '[wavy_mid, fg]shop [fg]- [fg, nudge_down]gold: [yellow, nudge_down]' .. gold, font = pixul_font, alignment = 'center'}}
self.text = Text({{text = '[bg10]' .. tostring(self.parent.shop_level), font = pixul_font, alignment = 'center'}}, global_text_tags)
system.save_run(self.parent.level, gold, self.parent.units, passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool, locked_state)
system.save_run(self.parent.level, gold, self.parent.units, self.parent.passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool, locked_state)
end
end
end
@ -1543,7 +1545,8 @@ function ShopCard:update(dt)
self:die()
self.parent.cards[self.i] = nil
self.parent:refresh_cards()
system.save_run(self.parent.level == 1 and 0 or self.parent.level, gold, self.parent.units, passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool, locked_state)
locked_state = {locked = self.parent.locked, cards = {self.parent.cards[1] and self.parent.cards[1].unit, self.parent.cards[2] and self.parent.cards[2].unit, self.parent.cards[3] and self.parent.cards[3].unit}}
system.save_run(self.parent.level, gold, self.parent.units, self.parent.passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool, locked_state)
else
error1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
self.spring:pull(0.2, 200, 10)

View File

@ -225,7 +225,7 @@ function Seeker:init(args)
local n = math.remap(current_new_game_plus, 0, 5, 1, 0.5)
self.t:after({2*n, 4*n}, function()
self.shooting = true
self.t:every({3, 5}, function()
self.t:every({4, 6}, function()
if self.silenced then return end
for i = 1, 3 do
self.t:after((1 - self.level*0.01)*0.15*(i-1), function()
@ -233,8 +233,8 @@ function Seeker:init(args)
self.hfx:use('hit', 0.25, 200, 10, 0.1)
local r = self.r
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}
EnemyProjectile{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), color = fg[0], r = r, v = 140 + 5*self.level + 4*current_new_game_plus,
dmg = (current_new_game_plus*0.1 + 1)*self.dmg}
EnemyProjectile{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), color = fg[0], r = r, v = 140 + 3.5*self.level + 2*current_new_game_plus,
dmg = (current_new_game_plus*0.1 + 1)*self.dmg, source = 'shooter'}
end)
end
end, nil, nil, 'shooter')
@ -473,7 +473,7 @@ function Seeker:hit(damage, projectile, dot)
_G[random:table{'enemy_die1', 'enemy_die2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.5}
if main.current.mercenary_level > 0 then
if random:bool((main.current.mercenary_level == 2 and 20) or (main.current.mercenary_level == 1 and 10) or 0) then
if random:bool((main.current.mercenary_level == 2 and 16) or (main.current.mercenary_level == 1 and 8) or 0) then
trigger:after(0.01, function()
Gold{group = main.current.main, x = self.x, y = self.y}
end)
@ -500,12 +500,9 @@ function Seeker:hit(damage, projectile, dot)
if self.exploder then
if self.silenced then return end
shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.4}
mine1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
trigger:after(0.01, function()
local n = math.floor(8 + current_new_game_plus*1.5)
for i = 1, n do
EnemyProjectile{group = main.current.main, x = self.x, y = self.y, color = blue[0], r = (i-1)*math.pi/(n/2), v = 120 + 5*self.level, dmg = 1.5*self.dmg}
end
ExploderMine{group = main.current.main, x = self.x, y = self.y, color = blue[0], parent = self}
end)
end
@ -573,8 +570,9 @@ end
function Seeker:push(f, r, push_invulnerable)
local n = 1
if self.tank then n = 0.4 - 0.01*self.level end
if self.boss then n = 0.1 end
if self.tank then n = 0.7 end
if self.boss then n = 0.2 end
if self.level == 25 and self.boss then n = 0.7 end
self.push_invulnerable = push_invulnerable
self.push_force = n*f
self.being_pushed = true
@ -672,6 +670,50 @@ function Seeker:apply_dot(dmg, duration)
end
ExploderMine = Object:extend()
ExploderMine:implement(GameObject)
function ExploderMine:init(args)
self:init_game_object(args)
self.hfx:add('hit', 1)
self.vr = 0
self.dvr = random:float(-math.pi/4, math.pi/4)
self.rs = 0
self.t:tween(0.05, self, {rs = args.rs}, math.cubic_in_out, function()
self.spring:pull(0.15)
self.t:every(0.8 - current_new_game_plus*0.1, function()
mine1:play{pitch = 1 + self.t:get_every_iteration'mine_count'*0.1, volume = 0.5}
self.spring:pull(0.5, 200, 10)
self.hfx:use('hit', 0.5, 200, 10, 0.2)
end, 3, function()
shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.4}
cannoneer1:play{pitch = random:float(0.95, 1.05), volume = 0.4}
for i = 1, 4 do HitParticle{group = main.current.effects, x = self.x, y = self.y, r = random:float(0, 2*math.pi), color = self.color} end
HitCircle{group = main.current.effects, x = self.x, y = self.y}
local n = math.floor(8 + current_new_game_plus*1.5)
for i = 1, n do
EnemyProjectile{group = main.current.main, x = self.x, y = self.y, color = blue[0], r = (i-1)*math.pi/(n/2), v = 120 + 5*self.parent.level, dmg = 1.5*self.parent.dmg}
end
self.dead = true
end, 'mine_count')
end)
--[[
]]--
end
function ExploderMine:update(dt)
self:update_game_object(dt)
self.vr = self.vr + self.dvr*dt
end
function ExploderMine:draw()
graphics.push(self.x, self.y, 0, self.spring.x, self.spring.x)
graphics.circle(self.x, self.y, 2.5, self.hfx.hit.f and fg[0] or self.color)
graphics.pop()
end
EnemyCritter = Object:extend()
@ -930,5 +972,11 @@ function EnemyProjectile:on_trigger_enter(other, contact)
self:die(self.x, self.y, nil, random:int(2, 3))
other:hit(1000)
end
elseif other:is(Seeker) or other:is(EnemyCritter) then
if self.source == 'shooter' then
self:die(self.x, self.y, nil, random:int(2, 3))
other:hit(0.5*self.dmg)
end
end
end

View File

@ -18,6 +18,7 @@ function init()
input:bind('enter', {'space', 'return', 'fleft', 'fdown', 'fright'})
local s = {tags = {sfx}}
mine1 = Sound('Weapon Swap 2.ogg', s)
level_up1 = Sound('Buff 4.ogg', s)
unlock1 = Sound('Unlock 3.ogg', s)
gambler1 = Sound('Collect 5.ogg', s)
@ -565,8 +566,8 @@ function init()
['lich'] = function(lvl) return '[fg]launches a slow projectile that jumps [yellow]7[fg] times, dealing [yellow]' .. 2*get_character_stat('lich', lvl, 'dmg') .. '[fg] damage per hit' end,
['cryomancer'] = function(lvl) return '[fg]nearby enemies take [yellow]' .. get_character_stat('cryomancer', lvl, 'dmg') .. '[fg] damage per second' end,
['pyromancer'] = function(lvl) return '[fg]nearby enemies take [yellow]' .. get_character_stat('pyromancer', lvl, 'dmg') .. '[fg] damage per second' end,
['corruptor'] = function(lvl) return '[fg]spawn [yellow]3[fg] small critters if the corruptor kills an enemy' end,
['beastmaster'] = function(lvl) return '[fg]spawn [yellow]2[fg] small critters if the beastmaster crits' end,
['corruptor'] = function(lvl) return '[fg]shoots an arrow that deals [yellow]' .. get_character_stat('corruptor', lvl, 'dmg') .. '[fg] damage, spawn [yellow]3[fg] critters if it kills' end,
['beastmaster'] = function(lvl) return '[fg]throws a knife that deals [yellow]' .. get_character_stat('beastmaster', lvl, 'dmg') .. '[fg] damage, spawn [yellow]2[fg] critters if it crits' end,
['launcher'] = function(lvl) return '[fg]all nearby enemies are pushed after [yellow]4[fg] seconds, taking [yellow]' .. 2*get_character_stat('launcher', lvl, 'dmg') .. '[fg] damage on wall hit' end,
['jester'] = function(lvl) return "[fg]curses [yellow]6[fg] nearby enemies for [yellow]6[fg] seconds, they will explode into [yellow]4[fg] knives on death" end,
['assassin'] = function(lvl) return '[fg]throws a piercing knife that deals [yellow]' .. get_character_stat('assassin', lvl, 'dmg') .. '[fg] damage + [yellow]' ..
@ -589,7 +590,7 @@ function init()
['warden'] = function(lvl) return '[fg]creates a force field around a random unit that prevents enemies from entering' end,
['psychic'] = function(lvl) return '[fg]creates a small area that deals [yellow]' .. get_character_stat('psychic', lvl, 'dmg') .. ' AoE[fg] damage' end,
['miner'] = function(lvl) return '[fg]picking up gold releases [yellow]4[fg] homing projectiles that each deal [yellow]' .. get_character_stat('miner', lvl, 'dmg') .. ' [fg]damage' end,
['merchant'] = function(lvl) return '[fg]gain [yellow]+1[fg] interest for every [yellow]10[fg] gold' end,
['merchant'] = function(lvl) return '[fg]gain [yellow]+1[fg] interest for every [yellow]10[fg] gold, up to a max of [yellow]+10[fg] from the merchant' end,
['usurer'] = function(lvl) return '[fg]curses [yellow]3[fg] nearby enemies indefinitely with debt, dealing [yellow]' .. get_character_stat('usurer', lvl, 'dmg') .. '[fg] damage per second' end,
['gambler'] = function(lvl) return '[fg]deal [yellow]2X[fg] damage to a single random enemy where X is how much gold you have' end,
['thief'] = function(lvl) return '[fg]throws a knife that deals [yellow]' .. 2*get_character_stat('thief', lvl, 'dmg') .. '[fg] damage and chains [yellow]5[fg] times' end,
@ -737,8 +738,8 @@ function init()
['lich'] = function() return '[fg]chain frost slows enemies hit by [yellow]80%[fg] for [yellow]2[fg] seconds and chains [yellow]+7[fg] times' end,
['cryomancer'] = function() return '[fg]enemies are also slowed by [yellow]60%[fg] while in the area' end,
['pyromancer'] = function() return '[fg]enemies killed by the pyromancer explode, dealing [yellow]' .. get_character_stat('pyromancer', 3, 'dmg') .. '[fg] AoE damage' end,
['corruptor'] = function() return '[fg]spawn [yellow]3[fg] small critters if the corruptor hits an enemy' end,
['beastmaster'] = function() return '[fg]spawn [yellow]2[fg] small critters if the beastmaster gets hit' end,
['corruptor'] = function() return '[fg]spawn [yellow]2[fg] small critters if the corruptor hits an enemy' end,
['beastmaster'] = function() return '[fg]spawn [yellow]4[fg] small critters if the beastmaster gets hit' end,
['launcher'] = function() return '[fg]enemies launched take [yellow]300%[fg] more damage when they hit walls' end,
['jester'] = function() return '[fg]all knives seek enemies and pierce [yellow]2[fg] times' end,
['assassin'] = function() return '[fg]poison inflicted from crits deals [yellow]8x[fg] damage' end,
@ -794,8 +795,8 @@ function init()
['lich'] = function() return '[light_bg]chain frost slows enemies hit by 80% for 2 seconds and chains +7 times' end,
['cryomancer'] = function() return '[light_bg]enemies are also slowed by 60% while in the area' end,
['pyromancer'] = function() return '[light_bg]enemies killed by the pyromancer explode, dealing ' .. get_character_stat('pyromancer', 3, 'dmg') .. ' AoE damage' end,
['corruptor'] = function() return '[light_bg]spawn 3 small critters if the corruptor hits an enemy' end,
['beastmaster'] = function() return '[light_bg]spawn 2 small critters if the beastmaster gets hit' end,
['corruptor'] = function() return '[light_bg]spawn 2 small critters if the corruptor hits an enemy' end,
['beastmaster'] = function() return '[light_bg]spawn 4 small critters if the beastmaster gets hit' end,
['launcher'] = function() return '[light_bg]enemies launched take 300% more damage when they hit walls' end,
['jester'] = function() return '[light_bg]curses 6 enemies and all knives seek enemies and pierce 2 times' end,
['assassin'] = function() return '[light_bg]poison inflicted from crits deals 8x damage' end,
@ -935,12 +936,12 @@ function init()
return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4[light_bg]/[' .. ylb3(lvl) .. ']6 [fg]- sorcerers repeat their attacks once every [' ..
ylb1(lvl) .. ']4[light_bg]/[' .. ylb2(lvl) .. ']3[light_bg]/[' .. ylb3(lvl) .. ']2[fg] attacks'
end,
['mercenary'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+10%[light_bg]/[' .. ylb2(lvl) .. ']+20% [fg]chance for enemies to drop gold on death' end,
['mercenary'] = 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 gold on death' end,
}
tier_to_characters = {
[1] = {'vagrant', 'swordsman', 'magician', 'archer', 'scout', 'cleric', 'arcanist', 'miner'},
[2] = {'wizard', 'saboteur', 'sage', 'squire', 'dual_gunner', 'hunter', 'chronomancer', 'barbarian', 'cryomancer', 'beastmaster', 'jester', 'carver', 'psychic', 'witch', 'silencer', 'outlaw', 'merchant'},
[1] = {'vagrant', 'swordsman', 'magician', 'archer', 'scout', 'cleric', 'arcanist', 'merchant'},
[2] = {'wizard', 'saboteur', 'sage', 'squire', 'dual_gunner', 'hunter', 'chronomancer', 'barbarian', 'cryomancer', 'beastmaster', 'jester', 'carver', 'psychic', 'witch', 'silencer', 'outlaw', 'miner'},
[3] = {'elementor', 'stormweaver', 'spellblade', 'psykeeper', 'engineer', 'juggernaut', 'pyromancer', 'host', 'assassin', 'bane', 'barrager', 'infestor', 'flagellant', 'illusionist', 'usurer', 'gambler'},
[4] = {'priest', 'highlander', 'psykino', 'fairy', 'blade', 'plague_doctor', 'cannoneer', 'vulcanist', 'warden', 'corruptor', 'thief'},
}
@ -998,8 +999,8 @@ function init()
['vulcanist'] = 4,
['warden'] = 4,
['psychic'] = 2,
['miner'] = 1,
['merchant'] = 2,
['miner'] = 2,
['merchant'] = 1,
['usurer'] = 3,
['gambler'] = 3,
['thief'] = 4,
@ -1493,22 +1494,27 @@ function init()
main = Main()
if run.level and run.level > 0 then
main_song_instance = _G[random:table{'song1', 'song2', 'song3', 'song4', 'song5'}]:play{volume = 0.5}
end
-- main_song_instance = _G[random:table{'song1', 'song2', 'song3', 'song4', 'song5'}]:play{volume = 0.5}
main_song_instance = _G[random:table{'song1', 'song2', 'song3', 'song4', 'song5'}]:play{volume = 0.5}
main:add(BuyScreen'buy_screen')
main:go_to('buy_screen', run.level or 0, run.units or {}, passives, run.shop_level or 1, run.shop_xp or 0)
main:go_to('buy_screen', run.level or 1, run.units or {}, passives, run.shop_level or 1, run.shop_xp or 0)
-- main:go_to('buy_screen', 7, run.units or {}, {'unleash'})
--[[
main:add(Arena'arena')
main:go_to('arena', 3, {
{character = 'merchant', level = 1},
{character = 'miner', level = 1},
{character = 'thief', level = 1},
{character = 'gambler', level = 1},
{character = 'vulcanist', level = 3},
{character = 'vulcanist', level = 3},
{character = 'vulcanist', level = 3},
{character = 'vulcanist', level = 3},
{character = 'vulcanist', level = 3},
{character = 'vulcanist', level = 3},
{character = 'vulcanist', level = 3},
{character = 'vulcanist', level = 3},
{character = 'vulcanist', level = 3},
{character = 'vulcanist', level = 3},
{character = 'vulcanist', level = 3},
{character = 'vulcanist', level = 3},
}, passives)
]]--

View File

@ -11,10 +11,10 @@ function Media:on_enter(from)
self.effects = Group()
self.ui = Group()
graphics.set_background_color(yellow2[0])
graphics.set_background_color(blue[0])
Text2{group = self.ui, x = gw/2, y = gh/2, lines = {
{text = '[fg]SNKRX', font = fat_font, alignment = 'center', height_offset = -15},
{text = '[fg]mercenary update', font = pixul_font, alignment = 'center'},
{text = '[fg]item update', font = pixul_font, alignment = 'center'},
}}
end

View File

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

View File

@ -158,14 +158,14 @@ function Player:init(args)
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()
local closest_enemy = self:get_closest_object_in_shape(self.attack_sensor, main.current.enemies)
if closest_enemy then
self:shoot(self:angle_to_object(closest_enemy), {pierce = 1000, v = 40})
self:shoot(self:angle_to_object(closest_enemy), {pierce = 10000, v = 40})
if main.current.sorcerer_level > 0 then
self.sorcerer_count = self.sorcerer_count + 1
if self.sorcerer_count >= ((main.current.sorcerer_level == 3 and 2) or (main.current.sorcerer_level == 2 and 3) or (main.current.sorcerer_level == 1 and 4)) then
self:sorcerer_repeat()
self.sorcerer_count = 0
self.t:after(0.25, function()
self:shoot(self:angle_to_object(closest_enemy), {pierce = 1000, v = 40})
self:shoot(self:angle_to_object(closest_enemy), {pierce = 10000, v = 40})
end)
end
end
@ -469,7 +469,7 @@ function Player:init(args)
self.t:cooldown(2, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
local closest_enemy = self:get_closest_object_in_shape(self.attack_sensor, main.current.enemies)
if closest_enemy then
self:shoot(self:angle_to_object(closest_enemy), {spawn_critters_on_kill = 3, spawn_critters_on_hit = (self.level == 3 and 3 or nil)})
self:shoot(self:angle_to_object(closest_enemy), {spawn_critters_on_kill = 3, spawn_critters_on_hit = (self.level == 3 and 2 or nil)})
end
end, nil, nil, 'shoot')
@ -1404,7 +1404,7 @@ function Player:hit(damage, from_undead)
if self.character == 'beastmaster' and self.level == 3 then
critter1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
trigger:after(0.01, function()
for i = 1, 2 do
for i = 1, 4 do
Critter{group = main.current.main, x = self.x, y = self.y, color = orange[0], r = random:float(0, 2*math.pi), v = 20, dmg = self.dmg, parent = self}
end
end)
@ -1508,7 +1508,7 @@ function Player:hit(damage, from_undead)
end
if self.insurance then
if random:bool(4*((main.current.mercenary_level == 2 and 20) or (main.current.mercenary_level == 1 and 10) or 0)) then
if random:bool(4*((main.current.mercenary_level == 2 and 16) or (main.current.mercenary_level == 1 and 8) or 0)) then
main.current.t:after(0.01, function()
Gold{group = main.current.main, x = self.x, y = self.y}
Gold{group = main.current.main, x = self.x, y = self.y}
@ -1879,7 +1879,7 @@ function Projectile:init(args)
arcane2:play{pitch = random:float(0.7, 1.3), volume = 0.15}
self.hfx:use('hit', 0.5)
local r = self:angle_to_object(enemy)
local t = {group = main.current.main, x = self.x + 8*math.cos(r), y = self.y + 8*math.sin(r), v = 250, r = r, color = self.parent.color, dmg = self.parent.dmg, pierce = 1000, character = 'arcanist_projectile',
local t = {group = main.current.main, x = self.x + 8*math.cos(r), y = self.y + 8*math.sin(r), v = 250, r = r, color = self.parent.color, dmg = self.parent.dmg, pierce = 2, character = 'arcanist_projectile',
parent = self.parent, level = self.parent.level}
local check_circle = Circle(t.x, t.y, 2)
local objects = main.current.main:get_objects_in_shape(check_circle, {Player, Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
@ -2778,9 +2778,8 @@ function Volcano:draw()
if self.hidden then return end
if not self.hfx.hit then return end
graphics.push(self.x, self.y, math.pi/4, self.spring.x, self.spring.x)
graphics.rectangle(self.x, self.y, 1.5*self.shape.w, 4, 2, 2, self.hfx.hit.f and fg[0] or self.color)
graphics.rectangle(self.x, self.y, 4, 1.5*self.shape.h, 2, 2, self.hfx.hit.f and fg[0] or self.color)
graphics.push(self.x, self.y, -math.pi/2, self.spring.x, self.spring.x)
graphics.triangle_equilateral(self.x, self.y, 1.5*self.shape.w, self.hfx.hit.f and fg[0] or self.color, 3)
graphics.pop()
graphics.push(self.x, self.y, self.r + self.vr, self.spring.x, self.spring.x)

62
todo
View File

@ -1,7 +1,7 @@
Item Update
New mechanics
* Spend gold to level items up
Block levelling for unlevellable items
* Block levelling for unlevellable items
Items
General:
* Centipede - +10/20/30% movement speed
@ -84,37 +84,29 @@ Item Update
* Blessing
* Immolation
Balance
* Changed voider DoT damage bonus to 20/40% (from 15/25%)
* Increased voider DoT damage bonus to 20/40% (from 15/25%)
* Decreased shop reroll cost to 10
Decrease mercenary gold drop chance to 8/16% (from 10/20%)
* Decreased mercenary gold drop chance to 8/16% (from 10/20%)
* Changed Merchant to tier 1
* Changed Merchant interest to cap at 10 (having more than 100 gold won't generate more interest from the merchant)
* Changed Miner to tier 2
* Changed Arcanist projectiles to pierce once (from infinite)
* Changed Exploder to create a mine on death, it will explode into projectiles after a delay (this delay is smaller on higher NG+ difficulties)
* Decreased Shooter projectile fire rate, speed, and now the projectiles can also be blocked by enemies
* Decreased Tank knockback resistance
* Decreased level 25 elite knockback resistance
* Changed Beastmaster's Lv.3 effect to spawn 4 small critters when it gets hit (from 2)
* Changed Corruptor's Lv.3 effect to spawn 2 small critters on hit (from 3)
QoL
Current snake/items visible on item selection screen
Volume slider
Add visuals for defensive ouroboros, divine intervention, fairy buff
Options menu from buy screen
https://i.imgur.com/JJUddT3.png
https://i.imgur.com/R3YgUqk.png
Improve volcano to not look like spawn marker - https://i.imgur.com/HuS15HG.png
Add option for mouse cursor to always be visible
Add main menu
Soundtrack button
Arena run button
Options button
Quit button
* Added snake to the passive selection screen
* Changed Volcano's icon to be a triangle instead of X so it isn't confused with a spawn marker
* Improved Beastmaster and Corruptor description with text describing their attack and how much damage it deals
* Added visual effect for when defensive ouroboros is active
* Added an option to force all screen transitions to be dark
* Added tier text to characters on the shop screen
* Added shop unit highlights/markers to make it easier to tell when you already own something
* Added unit names to the "your build" section of the end game screen
Bug fixes
Fix fullscreen with different resolutions that don't scale properly - https://steamcommunity.com/app/915310/discussions/0/3106901665841020282/
Fix enemies still spawning after arena clear (this happens with the extra enemy spawns that were blocked earlier)
Kill enemies that go outside play area - https://i.imgur.com/QPgZbve.png
https://i.imgur.com/lCdPFZx.png
https://i.imgur.com/1CwmFYX.png
https://i.imgur.com/qrExpq5.png
https://i.imgur.com/DNHUST1.png
Fixed multiple bugs related to locking the shop and quitting
* Fixed ouroboros technique passives not working with mouse controls
* Fixed mouse not showing up on death
* Fixed NG+5 achievement not triggering (this happened only between last Sunday night and Monday morning due to a small update I pushed breaking it)
@ -124,6 +116,7 @@ Item Update
* Fixed a bug where the shop would be rerolled after quitting in the arena
* Fixed a bug where units could be duplicated in the shop by locking and quitting the game at certain steps
* Fixed a bug where quitting on level 2 would go back to level 1 shop (again)
* Fixed multiple bugs related to locking the shop and quitting
* Fixed a bug where mouse cursor wasn't visible on death
* Fixed a bug where NG+ level wasn't increased when the game is beaten but only when the NG+ button was clicked
* Fixed a bug where level 2 and level 3 achievements (win with only level 2/3 units) were not triggering correctly sometimes
@ -145,6 +138,23 @@ Endless Update
Units die permanently when they die
Slower scaling with less individually threatening units
Max snake size goes up every 10 levels
QoL
Volume slider
Add visuals divine intervention, fairy buff
Options menu from buy screen
https://i.imgur.com/JJUddT3.png
Add option for mouse cursor to always be visible
Add main menu
Soundtrack button
Arena run button
Options button
Quit button
Bug fixes
Fix fullscreen with different resolutions that don't scale properly - https://steamcommunity.com/app/915310/discussions/0/3106901665841020282/
Fix enemies still spawning after arena clear (this happens with the extra enemy spawns that were blocked earlier)
Kill enemies that go outside play area - https://i.imgur.com/QPgZbve.png
https://i.imgur.com/lCdPFZx.png
https://i.imgur.com/qrExpq5.png
---
@ -152,6 +162,8 @@ Future updates:
Chaos related classes
Invoker - shoots a projectile with random properties, Lv.3 effect - ???
Trappers:
Traps - map modifier
turrets attached to walls shoot single, slow moving projectiles in a predictable pattern that deal lots of damage
Triangler - drops a trap and the 3rd trap will trigger the area, dealing X AoE damage 2-3 times
Brawlers: units focused on crashing on enemies
https://i.imgur.com/5YubukS.png - unit idea