Day 73-75
parent
e60c843848
commit
9ad62548e3
205
arena.lua
205
arena.lua
|
@ -40,6 +40,9 @@ function Arena:on_enter(from, level, units, passives)
|
|||
self.enemies = {Seeker, EnemyCritter}
|
||||
self.color = self.color or fg[0]
|
||||
|
||||
self.level = 25
|
||||
self.can_quit = true
|
||||
|
||||
-- Spawn solids and player
|
||||
self.x1, self.y1 = gw/2 - 0.8*gw/2, gh/2 - 0.8*gh/2
|
||||
self.x2, self.y2 = gw/2 + 0.8*gw/2, gh/2 + 0.8*gh/2
|
||||
|
@ -98,7 +101,7 @@ function Arena:on_enter(from, level, units, passives)
|
|||
spawn1:play{pitch = random:float(0.8, 1.2), volume = 0.15}
|
||||
self.boss = Seeker{group = self.main, x = x, y = y, character = 'seeker', level = self.level, boss = level_to_boss[self.level]}
|
||||
end}
|
||||
self.t:every(function() return #self.main:get_objects_by_classes(self.enemies) <= 1 end, function()
|
||||
self.t:every(function() return #self.main:get_objects_by_classes(self.enemies) <= 0 end, function()
|
||||
self.hfx:use('condition1', 0.25, 200, 10)
|
||||
self.hfx:pull('condition2', 0.0625)
|
||||
self.t:after(0.5, function()
|
||||
|
@ -110,7 +113,7 @@ function Arena:on_enter(from, level, units, passives)
|
|||
end)
|
||||
end)
|
||||
end)
|
||||
self.t:every(function() return self.start_time <= 0 and (self.boss and self.boss.dead) and #self.main:get_objects_by_classes(self.enemies) <= 0 end, function()
|
||||
self.t:every(function() return self.start_time <= 0 and (self.boss and self.boss.dead) and #self.main:get_objects_by_classes(self.enemies) <= 0 and not self.spawning_enemies and not self.quitting end, function()
|
||||
self.can_quit = true
|
||||
if self.level == 6 then
|
||||
state.achievement_speed_booster = true
|
||||
|
@ -142,16 +145,20 @@ function Arena:on_enter(from, level, units, passives)
|
|||
end)
|
||||
else
|
||||
-- Set win condition and enemy spawns
|
||||
self.win_condition = random:table{'time', 'wave'}
|
||||
if self.level % 3 == 0 then self.win_condition = 'wave' end
|
||||
if self.level == 18 and self.trailer then self.win_condition = 'wave' end
|
||||
if self.win_condition == 'wave' then
|
||||
self.win_condition = 'wave'
|
||||
self.level_to_max_waves = {
|
||||
1, 2, random:int(2, 3),
|
||||
3, 3, 3, random:int(3, 4),
|
||||
4, 4, 4, 4, random:int(4, 5),
|
||||
5, 5, 5, 5, 5, random:int(5, 6),
|
||||
6, 7, 8, 9, 9, 10, 12
|
||||
2, 3, 4,
|
||||
3, 4, 4, 5,
|
||||
5, 5, 5, 5, 7,
|
||||
6, 6, 7, 7, 7, 10,
|
||||
6, 8, 10, 12, 14, 16, 25,
|
||||
}
|
||||
self.level_to_distributed_enemies_chance = {
|
||||
0, 5, 10,
|
||||
10, 15, 15, 20,
|
||||
20, 20, 20, 20, 25,
|
||||
25, 25, 25, 25, 25, 30,
|
||||
20, 25, 30, 35, 40, 45, 50,
|
||||
}
|
||||
self.max_waves = self.level_to_max_waves[self.level]
|
||||
self.wave = 0
|
||||
|
@ -171,52 +178,26 @@ function Arena:on_enter(from, level, units, passives)
|
|||
self.hfx:use('condition1', 0.25, 200, 10)
|
||||
self.hfx:pull('condition2', 0.0625)
|
||||
self.t:after(0.5, function()
|
||||
if random:bool(self.level_to_distributed_enemies_chance[self.level]) then
|
||||
local n = math.ceil((8 + (self.wave-1)*2)/7)
|
||||
for i = 1, n do
|
||||
self.t:after((i-1)*2, function()
|
||||
self:spawn_distributed_enemies()
|
||||
end)
|
||||
end
|
||||
else
|
||||
local spawn_type = random:table{'left', 'middle', 'right'}
|
||||
local spawn_points = {left = {x = self.x1 + 32, y = gh/2}, middle = {x = gw/2, y = gh/2}, right = {x = self.x2 - 32, y = gh/2}}
|
||||
local p = spawn_points[spawn_type]
|
||||
SpawnMarker{group = self.effects, x = p.x, y = p.y}
|
||||
self.t:after(0.75, function() self:spawn_n_enemies(p, nil, 8 + (self.wave-1)*2) end)
|
||||
end
|
||||
end)
|
||||
end, self.max_waves+1)
|
||||
end)
|
||||
self.t:every(function() return #self.main:get_objects_by_classes(self.enemies) <= 0 and self.wave > self.max_waves end, function() self.can_quit = true end)
|
||||
end)
|
||||
|
||||
elseif self.win_condition == 'time' then
|
||||
self.level_to_time_left = {
|
||||
20, 20, random:int(20, 25),
|
||||
25, 25, 25, random:int(25, 30),
|
||||
30, 30, 30, 30, random:int(30, 35),
|
||||
35, 35, 35, 35, 35, random:int(35, 40),
|
||||
40, 45, 50, 55, 55, 60, 80
|
||||
}
|
||||
self.time_left = self.level_to_time_left[self.level]
|
||||
self.start_time = 3
|
||||
self.t:after(1, function()
|
||||
self.t:every(1, function()
|
||||
if self.start_time > 1 then alert1:play{volume = 0.5} end
|
||||
self.start_time = self.start_time - 1
|
||||
self.hfx:use('condition1', 0.25, 200, 10)
|
||||
end, 3, function()
|
||||
alert1:play{pitch = 1.2, volume = 0.5}
|
||||
camera:shake(4, 0.25)
|
||||
SpawnEffect{group = self.effects, x = gw/2, y = gh/2 - 48}
|
||||
self.t:every(1, function()
|
||||
self.time_left = self.time_left - 1
|
||||
self.hfx:use('condition1', 0.25, 200, 10)
|
||||
self.hfx:pull('condition2', 0.0625)
|
||||
end, self.time_left)
|
||||
|
||||
self.t:every_immediate(2, function()
|
||||
if #self.main:get_objects_by_classes(self.enemies) <= 0 or love.timer.getTime() - self.last_spawn_enemy_time >= 8 and not self.transitioning and not self.can_quit then
|
||||
self:spawn_distributed_enemies()
|
||||
end
|
||||
end, self.time_left/2)
|
||||
end)
|
||||
end)
|
||||
self.t:every(function() return #self.main:get_objects_by_classes(self.enemies) <= 0 and self.time_left <= 0 and not self.can_quit end, function() self.can_quit = true end)
|
||||
end
|
||||
|
||||
if self.level == 18 and self.trailer then
|
||||
Text2{group = self.ui, x = gw/2, y = gh/2 - 24, lines = {{text = '[fg, wavy]SNKRX', font = fat_font, alignment = 'center'}}}
|
||||
Text2{group = self.ui, x = gw/2, y = gh/2, sx = 0.5, sy = 0.5, lines = {{text = '[fg, wavy_mid]wishlist now!', font = fat_font, alignment = 'center'}}}
|
||||
|
@ -254,6 +235,7 @@ function Arena:on_enter(from, level, units, passives)
|
|||
self.healer_level = class_levels.healer
|
||||
self.psyker_level = class_levels.psyker
|
||||
self.conjurer_level = class_levels.conjurer
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
@ -308,27 +290,18 @@ function Arena:update(dt)
|
|||
gold = 2
|
||||
passives = {}
|
||||
cascade_instance:stop()
|
||||
run_passive_pool_by_tiers = {
|
||||
[1] = { 'wall_echo', 'wall_rider', 'centipede', 'temporal_chains', 'amplify', 'amplify_x', 'ballista', 'ballista_x', 'blunt_arrow', 'berserking', 'unwavering_stance', 'assassination', 'unleash', 'blessing',
|
||||
'hex_master', 'force_push', 'spawning_pool'},
|
||||
[2] = {'ouroboros_technique_r', 'ouroboros_technique_l', 'intimidation', 'vulnerability', 'resonance', 'point_blank', 'longshot', 'explosive_arrow', 'chronomancy', 'awakening', 'ultimatum', 'concentrated_fire',
|
||||
'reinforce', 'payback', 'whispers_of_doom', 'heavy_impact', 'immolation', 'call_of_the_void'},
|
||||
[3] = {'divine_machine_arrow', 'divine_punishment', 'flying_daggers', 'crucio', 'hive', 'void_rift'},
|
||||
}
|
||||
main:add(BuyScreen'buy_screen')
|
||||
main:go_to('buy_screen', 0, {}, passives)
|
||||
end, text = Text({{text = '[wavy, bg]restarting...', font = pixul_font, alignment = 'center'}}, global_text_tags)}
|
||||
end
|
||||
|
||||
--[[
|
||||
if input.w.pressed then
|
||||
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
system.open_url'https://store.steampowered.com/app/915310/SNKRX/'
|
||||
end
|
||||
]]--
|
||||
end
|
||||
|
||||
--[[
|
||||
if input.w.pressed and self.won then
|
||||
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
system.open_url'https://store.steampowered.com/app/915310/SNKRX/'
|
||||
end
|
||||
]]--
|
||||
|
||||
self:update_game_object(dt*slow_amount)
|
||||
cascade_instance.pitch = math.clamp(slow_amount*self.main_slow_amount, 0.05, 1)
|
||||
|
@ -341,26 +314,33 @@ function Arena:update(dt)
|
|||
|
||||
if self.can_quit and #self.main:get_objects_by_classes(self.enemies) <= 0 and not self.transitioning then
|
||||
self.can_quit = false
|
||||
self.quitting = true
|
||||
|
||||
if self.level == 25 then
|
||||
if not self.win_text and not self.win_text2 then
|
||||
self.won = true
|
||||
camera.x, camera.y = gw/2, gh/2
|
||||
self.win_text = Text2{group = self.ui, x = gw/2, y = gh/2 - 66, lines = {{text = '[wavy_mid, cbyc2]congratulations!', font = fat_font, alignment = 'center'}}}
|
||||
self.t:after(2.5, function()
|
||||
trigger:tween(1, _G, {slow_amount = 0}, math.linear, function() slow_amount = 0 end)
|
||||
trigger:tween(4, camera, {x = gw/2, y = gh/2, r = 0}, math.linear, function() camera.x, camera.y, camera.r = gw/2, gh/2, 0 end)
|
||||
self.win_text = Text2{group = self.ui, x = gw/2, y = gh/2 - 66, force_update = true, lines = {{text = '[wavy_mid, cbyc2]congratulations!', font = fat_font, alignment = 'center'}}}
|
||||
trigger:after(2.5, function()
|
||||
if new_game_plus == 10 then
|
||||
|
||||
else
|
||||
self.win_text2 = Text2{group = self.ui, x = gw/2, y = gh/2 + 20, lines = {
|
||||
{text = "[fg]you've beaten the game!", font = pixul_font, alignment = 'center', height_multiplier = 1.2},
|
||||
{text = "[fg]i made this game in 3 months as a dev challenge", font = pixul_font, alignment = 'center', height_multiplier = 1.2},
|
||||
{text = "[fg]and i'm happy with how it turned out!", font = pixul_font, alignment = 'center', height_multiplier = 1.2},
|
||||
{text = "[fg]if you liked it too and want to play more games like this:", font = pixul_font, alignment = 'center', height_multiplier = 5},
|
||||
self.win_text2 = Text2{group = self.ui, x = gw/2, y = gh/2 + 20, force_update = true, lines = {
|
||||
{text = "[fg]you've beaten the game!", font = pixul_font, alignment = 'center', height_multiplier = 1.24},
|
||||
{text = "[fg]i made this game in 3 months as a dev challenge", font = pixul_font, alignment = 'center', height_multiplier = 1.24},
|
||||
{text = "[fg]and i'm happy with how it turned out!", font = pixul_font, alignment = 'center', height_multiplier = 1.24},
|
||||
{text = "[fg]if you liked it too and want to play more games like this:", font = pixul_font, alignment = 'center', height_multiplier = 4},
|
||||
{text = "[fg]i will release more games this year, so stay tuned!", font = pixul_font, alignment = 'center', height_multiplier = 1.4},
|
||||
{text = "[wavy_mid, yellow]thanks for playing!", font = pixul_font, alignment = 'center'},
|
||||
}}
|
||||
SteamFollowButton{group = self.ui, x = gw/2, y = gh/2 + 37}
|
||||
RestartButton{group = self.ui, x = gw - 40, y = gh - 20}
|
||||
SteamFollowButton{group = self.ui, x = gw/2, y = gh/2 + 34, force_update = true}
|
||||
RestartButton{group = self.ui, x = gw - 40, y = gh - 20, force_update = true}
|
||||
trigger:after(12, function()
|
||||
self.try_ng_text = Text2{group = self.ui, x = gw - 140, y = gh - 20, force_update = true, lines = {
|
||||
{text = '[cbyc3, wavy_mid]try a harder difficulty:', font = pixul_font},
|
||||
}}
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
|
@ -475,13 +455,6 @@ function Arena:update(dt)
|
|||
steam.userStats.setAchievement('VOIDERS_WIN')
|
||||
steam.userStats.storeStats()
|
||||
end
|
||||
|
||||
--[[
|
||||
state.achievement_speed_booster = true
|
||||
system.save_state()
|
||||
steam.userStats.setAchievement('SPEED_BOOSTER')
|
||||
steam.userStats.storeStats()
|
||||
]]--
|
||||
end
|
||||
|
||||
else
|
||||
|
@ -495,9 +468,13 @@ function Arena:update(dt)
|
|||
local w = 3*card_w + 2*20
|
||||
self.choosing_passives = true
|
||||
self.cards = {}
|
||||
local passive_1 = random:table(tier_to_passives[random:weighted_pick(unpack(level_to_passive_tier_weights[level or self.level]))])
|
||||
local passive_2 = random:table(tier_to_passives[random:weighted_pick(unpack(level_to_passive_tier_weights[level or self.level]))])
|
||||
local passive_3 = random:table(tier_to_passives[random:weighted_pick(unpack(level_to_passive_tier_weights[level or self.level]))])
|
||||
local tier_1 = random:weighted_pick(unpack(level_to_passive_tier_weights[level or self.level]))
|
||||
local tier_2 = random:weighted_pick(unpack(level_to_passive_tier_weights[level or self.level]))
|
||||
local tier_3 = random:weighted_pick(unpack(level_to_passive_tier_weights[level or self.level]))
|
||||
local passive_pool_copy = table.copy(run_passive_pool_by_tiers)
|
||||
local passive_1 = random:table_remove(passive_pool_copy[tier_1])
|
||||
local passive_2 = random:table_remove(passive_pool_copy[tier_2])
|
||||
local passive_3 = random:table_remove(passive_pool_copy[tier_3])
|
||||
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, arena = self, passive = passive_1, force_update = true})
|
||||
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, arena = self, passive = passive_2, force_update = true})
|
||||
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, arena = self, passive = passive_3, force_update = true})
|
||||
|
@ -540,22 +517,15 @@ function Arena:draw()
|
|||
end
|
||||
else
|
||||
if self.win_condition then
|
||||
if self.win_condition == 'time' then
|
||||
if self.start_time <= 0 then
|
||||
graphics.push(self.x2 - 66, self.y1 - 9, 0, self.hfx.condition2.x, self.hfx.condition2.x)
|
||||
graphics.print_centered('time left:', fat_font, self.x2 - 66, self.y1 - 9, 0, 0.6, 0.6, nil, nil, fg[0])
|
||||
graphics.pop()
|
||||
graphics.push(self.x2 - 18 + fat_font:get_text_width(tostring(self.time_left))/2, self.y1 - 8, 0, self.hfx.condition1.x, self.hfx.condition1.x)
|
||||
graphics.print(tostring(self.time_left), fat_font, self.x2 - 18, self.y1 - 8, 0, 0.75, 0.75, nil, fat_font.h/2, self.hfx.condition1.f and fg[0] or yellow[0])
|
||||
graphics.pop()
|
||||
end
|
||||
elseif self.win_condition == 'wave' then
|
||||
if self.win_condition == 'wave' then
|
||||
if self.start_time <= 0 then
|
||||
graphics.push(self.x2 - 50, self.y1 - 10, 0, self.hfx.condition2.x, self.hfx.condition2.x)
|
||||
graphics.print_centered('wave:', fat_font, self.x2 - 50, self.y1 - 10, 0, 0.6, 0.6, nil, nil, fg[0])
|
||||
graphics.pop()
|
||||
graphics.push(self.x2 - 25 + fat_font:get_text_width(self.wave .. '/' .. self.max_waves)/2, self.y1 - 8, 0, self.hfx.condition1.x, self.hfx.condition1.x)
|
||||
graphics.print(self.wave .. '/' .. self.max_waves, fat_font, self.x2 - 25, self.y1 - 8, 0, 0.75, 0.75, nil, fat_font.h/2, self.hfx.condition1.f and fg[0] or yellow[0])
|
||||
local wave = self.wave
|
||||
if wave > self.max_waves then wave = self.max_waves end
|
||||
graphics.push(self.x2 - 25 + fat_font:get_text_width(wave .. '/' .. self.max_waves)/2, self.y1 - 8, 0, self.hfx.condition1.x, self.hfx.condition1.x)
|
||||
graphics.print(wave .. '/' .. self.max_waves, fat_font, self.x2 - 25, self.y1 - 8, 0, 0.75, 0.75, nil, fat_font.h/2, self.hfx.condition1.f and fg[0] or yellow[0])
|
||||
graphics.pop()
|
||||
end
|
||||
end
|
||||
|
@ -590,7 +560,8 @@ end
|
|||
function Arena:transition()
|
||||
self.transitioning = true
|
||||
local gold_gained = random:int(level_to_gold_gained[self.level][1], level_to_gold_gained[self.level][2])
|
||||
gold = gold + gold_gained
|
||||
local interest = math.floor(gold/5)
|
||||
gold = gold + gold_gained + interest
|
||||
ui_transition2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
TransitionEffect{group = main.transitions, x = self.player.x, y = self.player.y, color = self.color, transition_action = function(t)
|
||||
main:add(BuyScreen'buy_screen')
|
||||
|
@ -598,22 +569,22 @@ function Arena:transition()
|
|||
t.t:after(0.1, function()
|
||||
t.text:set_text({
|
||||
{text = '[nudge_down, bg]gold gained: ' .. tostring(gold_gained), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||
{text = '[wavy_lower, bg]damage taken: 0', font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||
{text = '[wavy_lower, bg]damage dealt: 0', font = pixul_font, alignment = 'center'}
|
||||
{text = '[wavy_lower, bg]interest: 0', font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||
{text = '[wavy_lower, bg]total: 0', font = pixul_font, alignment = 'center'}
|
||||
})
|
||||
_G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
t.t:after(0.2, function()
|
||||
t.text:set_text({
|
||||
{text = '[wavy_lower, bg]gold gained: ' .. tostring(gold_gained), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||
{text = '[nudge_down, bg]damage taken: ' .. tostring(math.round(self.damage_taken, 0)), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||
{text = '[wavy_lower, bg]damage dealt: 0', font = pixul_font, alignment = 'center'}
|
||||
{text = '[nudge_down, bg]interest: ' .. tostring(interest), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||
{text = '[wavy_lower, bg]total: 0', font = pixul_font, alignment = 'center'}
|
||||
})
|
||||
_G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
t.t:after(0.2, function()
|
||||
t.text:set_text({
|
||||
{text = '[wavy_lower, bg]gold gained: ' .. tostring(gold_gained), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||
{text = '[wavy_lower, bg]damage taken: ' .. tostring(math.round(self.damage_taken, 0)), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||
{text = '[nudge_down, bg]damage dealt: ' .. tostring(math.round(self.damage_dealt, 0)), font = pixul_font, alignment = 'center'}
|
||||
{text = '[wavy_lower, bg]interest: ' .. tostring(interest), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||
{text = '[nudge_down, bg]total: ' .. tostring(gold_gained + interest), font = pixul_font, alignment = 'center'}
|
||||
})
|
||||
_G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
end)
|
||||
|
@ -621,15 +592,17 @@ function Arena:transition()
|
|||
end)
|
||||
end, text = Text({
|
||||
{text = '[wavy_lower, bg]gold gained: 0', font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||
{text = '[wavy_lower, bg]damage taken: 0', font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||
{text = '[wavy_lower, bg]damage dealt: 0', font = pixul_font, alignment = 'center'}
|
||||
{text = '[wavy_lower, bg]interest: 0', font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||
{text = '[wavy_lower, bg]total: 0', font = pixul_font, alignment = 'center'}
|
||||
}, global_text_tags)}
|
||||
end
|
||||
|
||||
|
||||
function Arena:spawn_distributed_enemies()
|
||||
self.spawning_enemies = true
|
||||
|
||||
local t = {'4', '4+4', '4+4+4', '2x4', '3x4', '4x2'}
|
||||
local spawn_type = t[random:weighted_pick(40, 20, 5, 15, 5, 15)]
|
||||
local spawn_type = t[random:weighted_pick(20, 20, 10, 15, 10, 15)]
|
||||
local spawn_points = table.copy(self.spawn_points)
|
||||
if spawn_type == '4' then
|
||||
local p = random:table_remove(spawn_points)
|
||||
|
@ -637,6 +610,7 @@ function Arena:spawn_distributed_enemies()
|
|||
self.t:after(0.75, function()
|
||||
self:spawn_n_enemies(p)
|
||||
end)
|
||||
self.t:after(1.5, function() self.spawning_enemies = false end, 'spawning_enemies')
|
||||
elseif spawn_type == '4+4' then
|
||||
local p = random:table_remove(spawn_points)
|
||||
SpawnMarker{group = self.effects, x = p.x, y = p.y}
|
||||
|
@ -644,6 +618,7 @@ function Arena:spawn_distributed_enemies()
|
|||
self:spawn_n_enemies(p)
|
||||
self.t:after(2, function() self:spawn_n_enemies(p) end)
|
||||
end)
|
||||
self.t:after(3.5, function() self.spawning_enemies = false end, 'spawning_enemies')
|
||||
elseif spawn_type == '4+4+4' then
|
||||
local p = random:table_remove(spawn_points)
|
||||
SpawnMarker{group = self.effects, x = p.x, y = p.y}
|
||||
|
@ -656,36 +631,58 @@ function Arena:spawn_distributed_enemies()
|
|||
end)
|
||||
end)
|
||||
end)
|
||||
self.t:after(3.5, function() self.spawning_enemies = false end, 'spawning_enemies')
|
||||
elseif spawn_type == '2x4' then
|
||||
self.t:after({0, 0.2}, function()
|
||||
local p = random:table_remove(spawn_points)
|
||||
SpawnMarker{group = self.effects, x = p.x, y = p.y}
|
||||
self.t:after(0.75, function() self:spawn_n_enemies(p, 1) end)
|
||||
end)
|
||||
self.t:after({0, 0.2}, function()
|
||||
local p = random:table_remove(spawn_points)
|
||||
SpawnMarker{group = self.effects, x = p.x, y = p.y}
|
||||
self.t:after(0.75, function() self:spawn_n_enemies(p, 2) end)
|
||||
end)
|
||||
self.t:after(1.5, function() self.spawning_enemies = false end, 'spawning_enemies')
|
||||
elseif spawn_type == '3x4' then
|
||||
self.t:after({0, 0.2}, function()
|
||||
local p = random:table_remove(spawn_points)
|
||||
SpawnMarker{group = self.effects, x = p.x, y = p.y}
|
||||
self.t:after(0.75, function() self:spawn_n_enemies(p, 1) end)
|
||||
end)
|
||||
self.t:after({0, 0.2}, function()
|
||||
local p = random:table_remove(spawn_points)
|
||||
SpawnMarker{group = self.effects, x = p.x, y = p.y}
|
||||
self.t:after(0.75, function() self:spawn_n_enemies(p, 2) end)
|
||||
end)
|
||||
self.t:after({0, 0.2}, function()
|
||||
local p = random:table_remove(spawn_points)
|
||||
SpawnMarker{group = self.effects, x = p.x, y = p.y}
|
||||
self.t:after(0.75, function() self:spawn_n_enemies(p, 3) end)
|
||||
end)
|
||||
self.t:after(1.5, function() self.spawning_enemies = false end, 'spawning_enemies')
|
||||
elseif spawn_type == '4x2' then
|
||||
self.t:after({0, 0.2}, function()
|
||||
local p = random:table_remove(spawn_points)
|
||||
SpawnMarker{group = self.effects, x = p.x, y = p.y}
|
||||
self.t:after(0.75, function() self:spawn_n_enemies(p, 1, 2) end)
|
||||
end)
|
||||
self.t:after({0, 0.2}, function()
|
||||
local p = random:table_remove(spawn_points)
|
||||
SpawnMarker{group = self.effects, x = p.x, y = p.y}
|
||||
self.t:after(0.75, function() self:spawn_n_enemies(p, 2, 2) end)
|
||||
end)
|
||||
self.t:after({0, 0.2}, function()
|
||||
local p = random:table_remove(spawn_points)
|
||||
SpawnMarker{group = self.effects, x = p.x, y = p.y}
|
||||
self.t:after(0.75, function() self:spawn_n_enemies(p, 3, 2) end)
|
||||
end)
|
||||
self.t:after({0, 0.2}, function()
|
||||
local p = random:table_remove(spawn_points)
|
||||
SpawnMarker{group = self.effects, x = p.x, y = p.y}
|
||||
self.t:after(0.75, function() self:spawn_n_enemies(p, 4, 2) end)
|
||||
end)
|
||||
self.t:after(1.5, function() self.spawning_enemies = false end, 'spawning_enemies')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -52,9 +52,10 @@ function BuyScreen:on_enter(from, level, units, passives)
|
|||
self.party_text = Text({{text = '[wavy_mid, fg]party', font = pixul_font, alignment = 'center'}}, global_text_tags)
|
||||
self.sets_text = Text({{text = '[wavy_mid, fg]classes', font = pixul_font, alignment = 'center'}}, global_text_tags)
|
||||
self.items_text = Text({{text = '[wavy_mid, fg]items', font = pixul_font, alignment = 'center'}}, global_text_tags)
|
||||
self.ng_text = Text({{text = '[fg]NG+' .. new_game_plus, 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
|
||||
GoButton{group = self.main, x = gw - 135, y = gh - 20, parent = self}
|
||||
GoButton{group = self.main, x = gw - 100, y = gh - 20, parent = self}
|
||||
-- WishlistButton{group = self.main, x = gw - 147, y = gh - 20, parent = self}
|
||||
end
|
||||
|
||||
|
@ -71,18 +72,22 @@ function BuyScreen:update(dt)
|
|||
if self.sets_text then self.sets_text:update(dt) end
|
||||
if self.party_text then self.party_text:update(dt) end
|
||||
if self.items_text then self.items_text:update(dt) end
|
||||
if self.ng_text then self.ng_text:update(dt) end
|
||||
end
|
||||
|
||||
|
||||
function BuyScreen:draw()
|
||||
self.main:draw()
|
||||
self.effects:draw()
|
||||
if self.items_text then self.items_text:draw(32, 150) end
|
||||
if self.items_text then self.items_text:draw(32, 145) end
|
||||
self.ui:draw()
|
||||
|
||||
if self.shop_text then self.shop_text:draw(64, 20) end
|
||||
if self.sets_text then self.sets_text:draw(328, 20) end
|
||||
if self.party_text then self.party_text:draw(440, 20) end
|
||||
if new_game_plus > 0 then
|
||||
self.ng_text:draw(240, 20)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
@ -118,11 +123,11 @@ function BuyScreen:buy(character, i)
|
|||
end
|
||||
bought = true
|
||||
else
|
||||
if #self.units >= 10 then
|
||||
if #self.units >= max_units then
|
||||
if not self.info_text then
|
||||
self.info_text = InfoText{group = main.current.ui}
|
||||
self.info_text:activate({
|
||||
{text = '[fg]maximum number of units [yellow](10) [fg]reached', font = pixul_font, alignment = 'center'},
|
||||
{text = '[fg]maximum number of units [yellow](' .. max_units .. ') [fg]reached', font = pixul_font, alignment = 'center'},
|
||||
}, nil, nil, nil, nil, 16, 4, nil, 2)
|
||||
self.info_text.x, self.info_text.y = gw - 140, gh - 20
|
||||
end
|
||||
|
@ -205,8 +210,8 @@ SteamFollowButton:implement(GameObject)
|
|||
function SteamFollowButton:init(args)
|
||||
self:init_game_object(args)
|
||||
self.interact_with_mouse = true
|
||||
self.shape = Rectangle(self.x, self.y, fat_font:get_text_width('follow me on steam!'), fat_font.h)
|
||||
self.text = Text({{text = '[blue]follow me on steam!', font = fat_font, alignment = 'center'}}, global_text_tags)
|
||||
self.shape = Rectangle(self.x, self.y, pixul_font:get_text_width('follow me on steam!') + 12, pixul_font.h + 4)
|
||||
self.text = Text({{text = '[greenm5]follow me on steam!', font = pixul_font, alignment = 'center'}}, global_text_tags)
|
||||
end
|
||||
|
||||
|
||||
|
@ -225,8 +230,8 @@ end
|
|||
|
||||
function SteamFollowButton:draw()
|
||||
graphics.push(self.x, self.y, 0, self.spring.x, self.spring.y)
|
||||
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 4, 4, self.selected and fg[0] or green[0])
|
||||
self.text:draw(self.x, self.y)
|
||||
graphics.rectangle(self.x, self.y + self.text.h/5, self.text.w, 2, 2, 2, self.selected and blue[5] or blue[0])
|
||||
graphics.pop()
|
||||
end
|
||||
|
||||
|
@ -236,14 +241,14 @@ function SteamFollowButton:on_mouse_enter()
|
|||
ui_hover1:play{pitch = random:float(1.3, 1.5), volume = 0.5}
|
||||
pop2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
self.selected = true
|
||||
self.text:set_text{{text = '[blue5]follow me on steam!', font = fat_font, alignment = 'center'}}
|
||||
self.text:set_text{{text = '[fgm5]follow me on steam!', font = pixul_font, alignment = 'center'}}
|
||||
self.spring:pull(0.05, 200, 10)
|
||||
end
|
||||
|
||||
|
||||
function SteamFollowButton:on_mouse_exit()
|
||||
love.mouse.setCursor()
|
||||
self.text:set_text{{text = '[blue]follow me on steam!', font = fat_font, alignment = 'center'}}
|
||||
self.text:set_text{{text = '[greenm5]follow me on steam!', font = pixul_font, alignment = 'center'}}
|
||||
self.selected = false
|
||||
end
|
||||
|
||||
|
@ -616,7 +621,7 @@ function CharacterPart:die()
|
|||
|
||||
if self.selected and self.parent:is(BuyScreen) then
|
||||
for _, set in ipairs(self.parent.sets) do
|
||||
if table.any(character_classes[self.character], set.class) then
|
||||
if table.any(character_classes[self.character], function(v) return v == set.class end) then
|
||||
set:unhighlight()
|
||||
end
|
||||
end
|
||||
|
@ -656,6 +661,7 @@ function PassiveCard:update(dt)
|
|||
if self.selected and input.m1.pressed and self.arena.choosing_passives then
|
||||
self.arena.choosing_passives = false
|
||||
table.insert(passives, self.passive)
|
||||
table.delete(run_passive_pool_by_tiers[passive_tiers[self.passive]], self.passive)
|
||||
trigger:tween(0.25, _G, {slow_amount = 1}, math.linear, function()
|
||||
slow_amount = 1
|
||||
self.arena:transition()
|
||||
|
|
|
@ -1077,3 +1077,8 @@ Everything is done except these:
|
|||
|
||||
Tomorrow I'll start balancing the game out, which should lead to a bunch of bug fixes and small changes, and after that's done I'll get NG+1-10 working.
|
||||
Once that's done I'll do credits screen, NG+10 (game complete) screen, and find new music for the game. I want something more ambient generally and less upbeat.
|
||||
|
||||
# Day 73-75 - 30/04/21 - 02/05/21
|
||||
|
||||
Spending a lot of time balancing the game. The end game is pretty hectic and I need to make sure that it's reachable at NG+~7+.
|
||||
Basically just playing the game a lot, changing things that are too strong weak, then playing more and seeing if it's better.
|
||||
|
|
34
enemies.lua
34
enemies.lua
|
@ -22,7 +22,7 @@ function Seeker:init(args)
|
|||
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = green[0], duration = 0.1}
|
||||
for _, enemy in ipairs(enemies) do
|
||||
LightningLine{group = main.current.effects, src = self, dst = enemy, color = green[0]}
|
||||
enemy:speed_boost(3 + self.level*0.1)
|
||||
enemy:speed_boost(3 + self.level*0.1 + new_game_plus*0.1)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
@ -96,7 +96,8 @@ function Seeker:init(args)
|
|||
LightningLine{group = main.current.effects, src = self, dst = enemy, color = blue[0]}
|
||||
enemy:hit(10000)
|
||||
shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.4}
|
||||
for i = 1, 16 do EnemyProjectile{group = main.current.main, x = enemy.x, y = enemy.y, color = blue[0], r = (i-1)*math.pi/8, v = 150 + 5*enemy.level, dmg = 2*enemy.dmg} end
|
||||
local n = 8 + new_game_plus
|
||||
for i = 1, n do EnemyProjectile{group = main.current.main, x = enemy.x, y = enemy.y, color = blue[0], r = (i-1)*math.pi/(n/2), v = 150 + 5*enemy.level, dmg = 2*enemy.dmg} end
|
||||
end
|
||||
end)
|
||||
|
||||
|
@ -112,7 +113,8 @@ function Seeker:init(args)
|
|||
LightningLine{group = main.current.effects, src = self, dst = enemy, color = blue[0]}
|
||||
enemy:hit(10000)
|
||||
shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.4}
|
||||
for i = 1, 16 do EnemyProjectile{group = main.current.main, x = enemy.x, y = enemy.y, color = blue[0], r = (i-1)*math.pi/8, v = 150 + 5*enemy.level, dmg = 2*enemy.dmg} end
|
||||
local n = 8 + new_game_plus
|
||||
for i = 1, n do EnemyProjectile{group = main.current.main, x = enemy.x, y = enemy.y, color = blue[0], r = (i-1)*math.pi/(n/2), v = 150 + 5*enemy.level, dmg = 2*enemy.dmg} end
|
||||
end
|
||||
elseif attack == 'swarm' then
|
||||
local enemies = self:get_objects_in_shape(Circle(self.x, self.y, 128), {Seeker})
|
||||
|
@ -143,7 +145,7 @@ function Seeker:init(args)
|
|||
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = green[0], duration = 0.1}
|
||||
for _, enemy in ipairs(enemies) do
|
||||
LightningLine{group = main.current.effects, src = self, dst = enemy, color = green[0]}
|
||||
enemy:speed_boost(3 + self.level*0.1)
|
||||
enemy:speed_boost(3 + self.level*0.1 + new_game_plus*0.1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -171,10 +173,10 @@ function Seeker:init(args)
|
|||
if self.speed_booster then
|
||||
self.color = green[0]:clone()
|
||||
self.area_sensor = Circle(self.x, self.y, 128)
|
||||
self.t:after({16, 32}, function() self:hit(10000) end)
|
||||
self.t:after({16, 24}, function() self:hit(10000) end)
|
||||
elseif self.exploder then
|
||||
self.color = blue[0]:clone()
|
||||
self.t:after({16, 32}, function() self:hit(10000) end)
|
||||
self.t:after({16, 24}, function() self:hit(10000) end)
|
||||
elseif self.headbutter then
|
||||
self.color = orange[0]:clone()
|
||||
self.last_headbutt_time = 0
|
||||
|
@ -210,7 +212,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 = 150 + 5*self.level, dmg = 2*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 = 150 + 5*self.level + 5*new_game_plus,
|
||||
dmg = (new_game_plus*0.1 + 1.5)*self.dmg}
|
||||
end)
|
||||
end
|
||||
end, nil, nil, 'shooter')
|
||||
|
@ -242,10 +245,11 @@ function Seeker:update(dt)
|
|||
if main.current.mage_level == 2 then self.buff_def_a = -30
|
||||
elseif main.current.mage_level == 1 then self.buff_def_a = -15
|
||||
else self.buff_def_a = 0 end
|
||||
if self.headbutt_charging or self.headbutting then self.buff_def_m = 3 end
|
||||
|
||||
if self.speed_boosting then
|
||||
local n = math.remap(love.timer.getTime() - self.speed_boosting, 0, 3, 1, 0.5)
|
||||
self.speed_boosting_mvspd_m = (3 + 0.1*self.level)*n
|
||||
local n = math.remap(love.timer.getTime() - self.speed_boosting, 0, (3 + 0.1*self.level + new_game_plus*0.1), 1, 0.5)
|
||||
self.speed_boosting_mvspd_m = (3 + 0.1*self.level + 0.1*new_game_plus)*n
|
||||
if not self.speed_booster and not self.exploder and not self.headbutter and not self.tank and not self.shooter and not self.spawner then
|
||||
self.color.r = math.remap(n, 1, 0.5, green[0].r, red[0].r)
|
||||
self.color.g = math.remap(n, 1, 0.5, green[0].g, red[0].g)
|
||||
|
@ -388,7 +392,7 @@ function Seeker:hit(damage, projectile)
|
|||
if self.push_invulnerable then return end
|
||||
self:show_hp()
|
||||
|
||||
local actual_damage = self:calculate_damage(damage)*self.stun_dmg_m*self.bane_dmg_m
|
||||
local actual_damage = self:calculate_damage(damage)*(self.stun_dmg_m or 1)*(self.bane_dmg_m or 1)
|
||||
if self.vulnerable then actual_damage = actual_damage*1.2 end
|
||||
self.hp = self.hp - actual_damage
|
||||
main.current.damage_dealt = main.current.damage_dealt + actual_damage
|
||||
|
@ -408,6 +412,11 @@ function Seeker:hit(damage, projectile)
|
|||
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 12}:scale_down(0.3):change_color(0.5, self.color)
|
||||
_G[random:table{'enemy_die1', 'enemy_die2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
||||
|
||||
if self.boss then
|
||||
slow(0.25, 1)
|
||||
magic_die1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
end
|
||||
|
||||
if self.speed_booster then
|
||||
local enemies = self:get_objects_in_shape(self.area_sensor, main.current.enemies)
|
||||
if #enemies > 0 then
|
||||
|
@ -423,8 +432,9 @@ function Seeker:hit(damage, projectile)
|
|||
if self.exploder then
|
||||
shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.4}
|
||||
trigger:after(0.01, function()
|
||||
for i = 1, 16 do
|
||||
EnemyProjectile{group = main.current.main, x = self.x, y = self.y, color = blue[0], r = (i-1)*math.pi/8, v = 150 + 5*self.level, dmg = 2*self.dmg}
|
||||
local n = 8 + new_game_plus
|
||||
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 = 150 + 5*self.level, dmg = 2*self.dmg}
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
|
54
main.lua
54
main.lua
|
@ -468,7 +468,7 @@ function init()
|
|||
['carver'] = function(lvl) return '[fg]carves a statue that periodically heals [yellow]1[fg] unit for [yellow]20%[fg] max HP if in range' end,
|
||||
['bane'] = function(lvl) return '[fg]creates a large area that curses enemies to take [yellow]+50%[fg] damage' end,
|
||||
['psykino'] = function(lvl) return '[fg]pulls enemies together for [yellow]2[fg] seconds' end,
|
||||
['barrager'] = function(lvl) return '[fg]shoots a barrage of [yellow]5[fg] arrows, each dealing [yellow]' .. get_character_stat('barrager', lvl, 'dmg') .. '[fg] damage and pushing enemies' end,
|
||||
['barrager'] = function(lvl) return '[fg]shoots a barrage of [yellow]3[fg] arrows, each dealing [yellow]' .. get_character_stat('barrager', lvl, 'dmg') .. '[fg] damage and pushing enemies' end,
|
||||
['highlander'] = function(lvl) return '[fg]deals [yellow]' .. 5*get_character_stat('highlander', lvl, 'dmg') .. '[fg] AoE damage' end,
|
||||
['fairy'] = function(lvl) return '[fg]periodically heals [yellow]1[fg] unit at random and grants it [yellow]+100%[fg] attack speed for [yellow]6[fg] seconds' end,
|
||||
['priest'] = function(lvl) return '[fg]heals all allies for [yellow]20%[fg] their max HP' end,
|
||||
|
@ -719,7 +719,7 @@ function init()
|
|||
local ylb1 = function(lvl) return lvl >= 2 and 'fg' or (lvl >= 1 and 'yellow' or 'light_bg') end
|
||||
local ylb2 = function(lvl) return (lvl >= 2 and 'yellow' or 'light_bg') end
|
||||
class_descriptions = {
|
||||
['ranger'] = function(lvl) return '[' .. ylb1(lvl) .. ']3[' .. ylb2(lvl) .. ']/6 [fg]- [' .. ylb1(lvl) .. ']10%[' .. ylb2(lvl) .. ']/20% [fg]chance to release a barrage on attack to allied rangers' end,
|
||||
['ranger'] = function(lvl) return '[' .. ylb1(lvl) .. ']3[' .. ylb2(lvl) .. ']/6 [fg]- [' .. ylb1(lvl) .. ']8%[' .. ylb2(lvl) .. ']/16% [fg]chance to release a barrage on attack to allied rangers' end,
|
||||
['warrior'] = function(lvl) return '[' .. ylb1(lvl) .. ']3[' .. ylb2(lvl) .. ']/6 [fg]- [' .. ylb1(lvl) .. ']+25[' .. ylb2(lvl) .. ']/+50 [fg]defense to allied warriors' end,
|
||||
['mage'] = function(lvl) return '[' .. ylb1(lvl) .. ']3[' .. ylb2(lvl) .. ']/6 [fg]- [' .. ylb1(lvl) .. ']-15[' .. ylb2(lvl) .. ']/-30 [fg]enemy defense' end,
|
||||
['rogue'] = function(lvl) return '[' .. ylb1(lvl) .. ']3[' .. ylb2(lvl) .. ']/6 [fg]- [' .. ylb1(lvl) .. ']10%[' .. ylb2(lvl) .. ']/20% [fg]chance to crit to allied rogues, dealing [yellow]4x[] damage' end,
|
||||
|
@ -949,7 +949,7 @@ function init()
|
|||
['flying_daggers'] = '[fg]all knives thrown by rogues chain [yellow]+2[fg] times',
|
||||
['assassination'] = '[fg]crits from rogues deal [yellow]8x[fg] damage but normal attacks deal [yellow]half[fg] damage',
|
||||
['magnify'] = '[yellow]+25%[fg] area size',
|
||||
['concentrated_fire'] = '[yellow]-50%[fg] area size and [yellow]+50%[fg] area damage',
|
||||
['concentrated_fire'] = '[yellow]-50%[fg] area size and [yellow]+100%[fg] area damage',
|
||||
['unleash'] = '[yellow]+2%[fg] area size and damage per second',
|
||||
['reinforce'] = '[yellow]+10%[fg] damage, defense and attack speed to all allies if you have at least one enchanter',
|
||||
['payback'] = '[yellow]+5%[fg] damage to all allies whenever an enchanter is hit',
|
||||
|
@ -958,7 +958,7 @@ function init()
|
|||
['whispers_of_doom'] = '[fg]curses apply doom, when [yellow]4[fg] doom instances are reached they deal [yellow]200[fg] damage',
|
||||
['force_push'] = '[yellow]+25%[fg] knockback force',
|
||||
['heavy_impact'] = '[fg]when enemies hit walls they take damage according to the knockback force',
|
||||
['crucio'] = '[fg]taking damage also shares that amount across all enemies',
|
||||
['crucio'] = '[fg]taking damage also shares that across all enemies at [yellow]25%[fg] its value',
|
||||
['immolation'] = '[yellow]3[fg] units will periodically take damage, all your allies gain [yellow]+8%[fg] damage per tick',
|
||||
['call_of_the_void'] = '[yellow]+25%[fg] damage over time',
|
||||
['spawning_pool'] = '[yellow]+1[fg] critter health',
|
||||
|
@ -1051,27 +1051,27 @@ function init()
|
|||
[1] = {2, 2},
|
||||
[2] = {2, 2},
|
||||
[3] = {4, 6},
|
||||
[4] = {2, 3},
|
||||
[5] = {3, 5},
|
||||
[4] = {3, 5},
|
||||
[5] = {4, 7},
|
||||
[6] = {6, 10},
|
||||
[7] = {4, 7},
|
||||
[8] = {4, 7},
|
||||
[7] = {6, 7},
|
||||
[8] = {7, 8},
|
||||
[9] = {10, 16},
|
||||
[10] = {5, 8},
|
||||
[11] = {5, 8},
|
||||
[12] = {12, 20},
|
||||
[13] = {6, 10},
|
||||
[14] = {6, 10},
|
||||
[15] = {14, 22},
|
||||
[16] = {8, 12},
|
||||
[17] = {8, 12},
|
||||
[18] = {16, 24},
|
||||
[10] = {10, 12},
|
||||
[11] = {12, 14},
|
||||
[12] = {18, 20},
|
||||
[13] = {12, 16},
|
||||
[14] = {14, 18},
|
||||
[15] = {16, 20},
|
||||
[16] = {12, 12},
|
||||
[17] = {12, 12},
|
||||
[18] = {20, 24},
|
||||
[19] = {8, 12},
|
||||
[20] = {10, 14},
|
||||
[21] = {20, 28},
|
||||
[22] = {11, 15},
|
||||
[23] = {11, 15},
|
||||
[24] = {24, 36},
|
||||
[22] = {32, 32},
|
||||
[23] = {36, 36},
|
||||
[24] = {48, 48},
|
||||
[25] = {100, 100},
|
||||
}
|
||||
|
||||
|
@ -1150,18 +1150,28 @@ function init()
|
|||
[25] = {'speed_booster', 'exploder', 'headbutter', 'tank', 'shooter', 'spawner'},
|
||||
}
|
||||
|
||||
run_passive_pool_by_tiers = {
|
||||
[1] = { 'wall_echo', 'wall_rider', 'centipede', 'temporal_chains', 'amplify', 'amplify_x', 'ballista', 'ballista_x', 'blunt_arrow', 'berserking', 'unwavering_stance', 'assassination', 'unleash', 'blessing',
|
||||
'hex_master', 'force_push', 'spawning_pool'},
|
||||
[2] = {'ouroboros_technique_r', 'ouroboros_technique_l', 'intimidation', 'vulnerability', 'resonance', 'point_blank', 'longshot', 'explosive_arrow', 'chronomancy', 'awakening', 'ultimatum', 'concentrated_fire',
|
||||
'reinforce', 'payback', 'whispers_of_doom', 'heavy_impact', 'immolation', 'call_of_the_void'},
|
||||
[3] = {'divine_machine_arrow', 'divine_punishment', 'flying_daggers', 'crucio', 'hive', 'void_rift'},
|
||||
}
|
||||
gold = 2
|
||||
passives = {}
|
||||
system.load_state()
|
||||
new_game_plus = state.new_game_plus or 0
|
||||
steam.userStats.requestCurrentStats()
|
||||
max_units = 7 + math.floor(new_game_plus/2)
|
||||
|
||||
main = Main()
|
||||
--main:add(BuyScreen'buy_screen')
|
||||
--main:go_to('buy_screen', 0, {}, passives)
|
||||
main:add(BuyScreen'buy_screen')
|
||||
main:go_to('buy_screen', 0, {}, passives)
|
||||
|
||||
--[[
|
||||
main:add(Media'media')
|
||||
main:go_to('media')
|
||||
]]--
|
||||
end
|
||||
|
||||
|
||||
|
|
12
objects.lua
12
objects.lua
|
@ -9,7 +9,7 @@ function SpawnMarker:init(args)
|
|||
self.m = 1
|
||||
self.n = 0
|
||||
pop3:play{pitch = 1, volume = 0.15}
|
||||
self.t:every({0.11, 0.14}, function()
|
||||
self.t:every({0.13, 0.16}, function()
|
||||
self.hidden = not self.hidden
|
||||
self.m = self.m*random:float(0.84, 0.87)
|
||||
end, nil, nil, 'blink')
|
||||
|
@ -229,14 +229,14 @@ function Unit:calculate_stats(first_run)
|
|||
elseif self:is(Seeker) then
|
||||
if self.boss then
|
||||
local x = self.level
|
||||
local y = {0, 1, 4, 2, 3, 6, 3, 5, 9, 4, 6, 11, 7, 9, 15, 8, 10, 18, 9, 11, 21, 14, 15, 24, 25}
|
||||
self.base_hp = 150 + 175*y[x]
|
||||
local y = {0, 0, 3, 0, 0, 6, 0, 0, 9, 0, 0, 12, 0, 0, 15, 0, 0, 18, 0, 0, 21, 0, 0, 24, 25}
|
||||
self.base_hp = 100 + (new_game_plus*5) + (100 + new_game_plus*5)*y[x]
|
||||
self.base_dmg = 50 + 15*y[x]
|
||||
self.base_mvspd = 35 + 1.5*y[x]
|
||||
else
|
||||
local x = self.level
|
||||
local y = {0, 1, 4, 2, 3, 6, 3, 5, 9, 4, 6, 11, 7, 9, 15, 8, 10, 18, 9, 11, 21, 14, 15, 24, 25}
|
||||
self.base_hp = 50 + 55*y[x]
|
||||
local y = {0, 1, 3, 3, 4, 6, 5, 6, 9, 7, 8, 12, 10, 11, 15, 12, 13, 18, 16, 17, 21, 17, 20, 24, 25}
|
||||
self.base_hp = 25 + (new_game_plus*2) + (25 + new_game_plus*2)*y[x]
|
||||
self.base_dmg = 10 + 3*y[x]
|
||||
self.base_mvspd = 70 + 3*y[x]
|
||||
end
|
||||
|
@ -246,7 +246,7 @@ function Unit:calculate_stats(first_run)
|
|||
self.base_mvspd = 75
|
||||
elseif self:is(EnemyCritter) or self:is(Critter) then
|
||||
local x = self.level
|
||||
local y = {0, 1, 4, 2, 3, 6, 3, 5, 9, 4, 6, 11, 7, 9, 15, 8, 10, 18, 9, 11, 21, 14, 15, 24, 25}
|
||||
local y = {0, 1, 3, 3, 4, 6, 5, 6, 9, 7, 8, 12, 10, 11, 15, 12, 13, 18, 16, 17, 21, 17, 20, 24, 25}
|
||||
self.base_hp = 25 + 30*y[x]
|
||||
self.base_dmg = 10 + 3*y[x]
|
||||
self.base_mvspd = 60 + 3*y[x]
|
||||
|
|
26
player.lua
26
player.lua
|
@ -317,7 +317,7 @@ function Player:init(args)
|
|||
end)
|
||||
end
|
||||
else
|
||||
for i = 1, 5 do
|
||||
for i = 1, 3 do
|
||||
self.t:after((i-1)*0.075, function()
|
||||
self:shoot(r + random:float(-math.pi/32, math.pi/32), {knockback = (self.level == 3 and 14 or 7)})
|
||||
end)
|
||||
|
@ -438,7 +438,8 @@ function Player:init(args)
|
|||
end
|
||||
|
||||
if self.ouroboros_technique_r then
|
||||
self.t:every(0.1, function()
|
||||
self.t:after(0.01, function()
|
||||
self.t:every(0.4 - (0.02*#self:get_all_units()), function()
|
||||
if self.move_right_pressed and love.timer.getTime() - self.move_right_pressed > 1 then
|
||||
local target = self:get_closest_object_in_shape(Circle(self.x, self.y, 96), main.current.enemies)
|
||||
if target then
|
||||
|
@ -459,6 +460,7 @@ function Player:init(args)
|
|||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
if self.centipede then self.centipede_mvspd_m = 1.2 end
|
||||
|
@ -534,7 +536,7 @@ function Player:init(args)
|
|||
|
||||
if self.concentrated_fire then
|
||||
self.concentrated_fire_area_size_m = 0.66
|
||||
self.concentrated_fire_area_dmg_m = 1.5
|
||||
self.concentrated_fire_area_dmg_m = 2
|
||||
end
|
||||
|
||||
if self.unleash then
|
||||
|
@ -638,8 +640,8 @@ function Player:update(dt)
|
|||
end
|
||||
|
||||
if table.any(self.classes, function(v) return v == 'ranger' end) then
|
||||
if main.current.ranger_level == 2 then self.chance_to_barrage = 20
|
||||
elseif main.current.ranger_level == 1 then self.chance_to_barrage = 10
|
||||
if main.current.ranger_level == 2 then self.chance_to_barrage = 16
|
||||
elseif main.current.ranger_level == 1 then self.chance_to_barrage = 8
|
||||
elseif main.current.ranger_level == 0 then self.chance_to_barrage = 0 end
|
||||
end
|
||||
|
||||
|
@ -901,7 +903,7 @@ function Player:hit(damage)
|
|||
if self.crucio then
|
||||
local enemies = main.current.main:get_objects_by_classes(main.current.enemies)
|
||||
for _, enemy in ipairs(enemies) do
|
||||
enemy:hit(actual_damage)
|
||||
enemy:hit(0.25*actual_damage)
|
||||
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = fg[0], duration = 0.1}
|
||||
end
|
||||
end
|
||||
|
@ -909,8 +911,8 @@ function Player:hit(damage)
|
|||
local psykeeper = self:get_unit'psykeeper'
|
||||
if psykeeper then
|
||||
psykeeper.stored_heal = psykeeper.stored_heal + actual_damage
|
||||
if psykeeper.stored_heal > (0.5*psykeeper.max_hp) and love.timer.getTime() - self.last_heal_time > 6 then
|
||||
self.last_heal_time = love.timer.getTime()
|
||||
if psykeeper.stored_heal > (0.5*psykeeper.max_hp) and love.timer.getTime() - psykeeper.last_heal_time > 6 then
|
||||
psykeeper.last_heal_time = love.timer.getTime()
|
||||
local all_units = self:get_all_units()
|
||||
for _, unit in ipairs(all_units) do
|
||||
unit:heal(psykeeper.stored_heal*(self.heal_effect_m or 1)/#all_units)
|
||||
|
@ -1140,11 +1142,11 @@ function Player:shoot(r, mods)
|
|||
elseif self.character == 'dual_gunner' then
|
||||
dual_gunner1:play{pitch = random:float(0.95, 1.05), volume = 0.3}
|
||||
dual_gunner2:play{pitch = random:float(0.95, 1.05), volume = 0.3}
|
||||
elseif self.character == 'archer' or self.character == 'hunter' or self.character == 'barrager' then
|
||||
elseif self.character == 'archer' or self.character == 'hunter' or self.character == 'barrager' or self.character == 'corruptor' then
|
||||
archer1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
elseif self.character == 'wizard' or self.character == 'lich' then
|
||||
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
|
||||
elseif self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' or self.character == 'spellblade' or self.character == 'bard' or self.character == 'assassin' then
|
||||
elseif self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' or self.character == 'spellblade' or self.character == 'bard' or self.character == 'assassin' or self.character == 'beastmaster' then
|
||||
_G[random:table{'scout1', 'scout2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
if self.character == 'spellblade' then
|
||||
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
|
||||
|
@ -1158,7 +1160,7 @@ function Player:shoot(r, mods)
|
|||
end
|
||||
|
||||
if self.chance_to_barrage and random:bool(self.chance_to_barrage) then
|
||||
self:barrage(r, 4)
|
||||
self:barrage(r, 3)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -2280,6 +2282,6 @@ end
|
|||
function Critter:on_trigger_enter(other, contact)
|
||||
if other:is(Seeker) then
|
||||
self:hit(1)
|
||||
other:hit(self.dmg)
|
||||
other:hit(self.dmg, self)
|
||||
end
|
||||
end
|
||||
|
|
14
shared.lua
14
shared.lua
|
@ -20,7 +20,7 @@ function shared_init()
|
|||
end
|
||||
modal_transparent = Color(0.1, 0.1, 0.1, 0.6)
|
||||
|
||||
bg_off = Color(47, 47, 47)
|
||||
bg_off = Color(46, 46, 46)
|
||||
bg_gradient = GradientImage('vertical', Color(128, 128, 128, 0), Color(0, 0, 0, 0.3))
|
||||
|
||||
graphics.set_background_color(bg[0])
|
||||
|
@ -51,7 +51,6 @@ end
|
|||
|
||||
|
||||
function shared_draw(draw_action)
|
||||
--[[
|
||||
star_canvas:draw_to(function()
|
||||
star_group:draw()
|
||||
end)
|
||||
|
@ -74,7 +73,6 @@ function shared_draw(draw_action)
|
|||
bg_gradient:draw(gw/2, gh/2, 480, 270)
|
||||
camera:detach()
|
||||
end)
|
||||
]]--
|
||||
|
||||
main_canvas:draw_to(function()
|
||||
draw_action()
|
||||
|
@ -504,6 +502,7 @@ global_text_tags = {
|
|||
fgm5 = TextTag{draw = function(c, i, text) graphics.set_color(fg[-5]) end},
|
||||
fgm10 = TextTag{draw = function(c, i, text) graphics.set_color(fg[-10]) end},
|
||||
greenm5 = TextTag{draw = function(c, i, text) graphics.set_color(green[-5]) end},
|
||||
green5 = TextTag{draw = function(c, i, text) graphics.set_color(green[5]) end},
|
||||
blue5 = TextTag{draw = function(c, i, text) graphics.set_color(blue[5]) end},
|
||||
bluem5 = TextTag{draw = function(c, i, text) graphics.set_color(blue[-5]) end},
|
||||
wavy = TextTag{update = function(c, dt, i, text) c.oy = 2*math.sin(4*time + i) end},
|
||||
|
@ -544,6 +543,15 @@ global_text_tags = {
|
|||
graphics.set_color(c.color)
|
||||
end},
|
||||
|
||||
cbyc3 = TextTag{init = function(c, i, text)
|
||||
c.color = invisible
|
||||
text.t:after((i-1)*0.05, function()
|
||||
c.color = bg[10]
|
||||
end)
|
||||
end, draw = function(c, i, text)
|
||||
graphics.set_color(c.color)
|
||||
end},
|
||||
|
||||
nudge_down = TextTag{init = function(c, i, text)
|
||||
c.oy = -4
|
||||
text.t:tween(0.1, c, {oy = 0}, math.linear)
|
||||
|
|
2
todo
2
todo
|
@ -3,10 +3,12 @@ Trailers
|
|||
3-4 pure gameplay playthroughs showcasing different builds
|
||||
1 normal 30-40s trailer
|
||||
Misc
|
||||
Squire's Lv.3 effect
|
||||
NG+1-10 (difficulty ramps up faster and goes higher than normal at the end, the player also gains more gold per round, and on NG+1 and NG+5 the maximum number of units is increased by 1 (10->11->12)
|
||||
NG+10 end screen
|
||||
New music
|
||||
Credits
|
||||
Level X/25 text
|
||||
|
||||
|
||||
Engine improvements for after SNKRX release
|
||||
|
|
Loading…
Reference in New Issue