SNKRX/mainmenu.lua

214 lines
9.9 KiB
Lua

MainMenu = Object:extend()
MainMenu:implement(State)
MainMenu:implement(GameObject)
function MainMenu:init(name)
self:init_state(name)
self:init_game_object()
end
function MainMenu:on_enter(from)
slow_amount = 1
trigger:tween(2, main_song_instance, {volume = 0.5, pitch = 1}, math.linear)
steam.friends.setRichPresence('steam_display', '#StatusFull')
steam.friends.setRichPresence('text', 'Main Menu')
self.floor = Group()
self.main = Group():set_as_physics_world(32, 0, 0, {'player', 'enemy', 'projectile', 'enemy_projectile', 'force_field', 'ghost'})
self.post_main = Group()
self.effects = Group()
self.main_ui = Group():no_camera()
self.ui = Group():no_camera()
self.main:disable_collision_between('player', 'player')
self.main:disable_collision_between('player', 'projectile')
self.main:disable_collision_between('player', 'enemy_projectile')
self.main:disable_collision_between('projectile', 'projectile')
self.main:disable_collision_between('projectile', 'enemy_projectile')
self.main:disable_collision_between('projectile', 'enemy')
self.main:disable_collision_between('enemy_projectile', 'enemy')
self.main:disable_collision_between('enemy_projectile', 'enemy_projectile')
self.main:disable_collision_between('player', 'force_field')
self.main:disable_collision_between('projectile', 'force_field')
self.main:disable_collision_between('ghost', 'player')
self.main:disable_collision_between('ghost', 'projectile')
self.main:disable_collision_between('ghost', 'enemy')
self.main:disable_collision_between('ghost', 'enemy_projectile')
self.main:disable_collision_between('ghost', 'ghost')
self.main:disable_collision_between('ghost', 'force_field')
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('player', 'ghost')
self.enemies = {Seeker, EnemyCritter}
-- 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
self.w, self.h = self.x2 - self.x1, self.y2 - self.y1
Wall{group = self.main, vertices = math.to_rectangle_vertices(-40, -40, self.x1, gh + 40), color = bg[-1]}
Wall{group = self.main, vertices = math.to_rectangle_vertices(self.x2, -40, gw + 40, gh + 40), color = bg[-1]}
Wall{group = self.main, vertices = math.to_rectangle_vertices(self.x1, -40, self.x2, self.y1), color = bg[-1]}
Wall{group = self.main, vertices = math.to_rectangle_vertices(self.x1, self.y2, self.x2, gh + 40), color = bg[-1]}
WallCover{group = self.post_main, vertices = math.to_rectangle_vertices(-40, -40, self.x1, gh + 40), color = bg[-1]}
WallCover{group = self.post_main, vertices = math.to_rectangle_vertices(self.x2, -40, gw + 40, gh + 40), color = bg[-1]}
WallCover{group = self.post_main, vertices = math.to_rectangle_vertices(self.x1, -40, self.x2, self.y1), color = bg[-1]}
WallCover{group = self.post_main, vertices = math.to_rectangle_vertices(self.x1, self.y2, self.x2, gh + 40), color = bg[-1]}
self.t:every(0.375, function()
local p = random:table(star_positions)
Star{group = star_group, x = p.x, y = p.y}
end)
self.units = {
{character = 'psykino', level = 1},
{character = 'magician', level = 1},
{character = 'bane', level = 1},
{character = 'scout', level = 1},
{character = 'cannoneer', level = 1},
{character = 'swordsman', level = 1},
{character = 'archer', level = 1},
}
for i, unit in ipairs(self.units) do
if i == 1 then
self.player = Player{group = self.main, x = gw/2 + random:float(-48, 48), y = gh/2 + 16 + random:float(-48, 48), leader = true, character = unit.character, level = unit.level, passives = self.passives, ii = i}
else
self.player:add_follower(Player{group = self.main, character = unit.character, level = unit.level, passives = self.passives, ii = i})
end
end
self.title_text = Text({{text = '[wavy_mid, fg]SNKRX', font = fat_font, alignment = 'center'}}, global_text_tags)
self.arena_run_button = Button{group = self.main_ui, x = 55, y = gh/2 - 10, force_update = true, button_text = 'arena run', fg_color = 'bg10', bg_color = 'bg', action = function(b)
ui_transition2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
TransitionEffect{group = main.transitions, x = gw/2, y = gh/2, color = state.dark_transitions and bg[-2] or fg[0], transition_action = function()
self.transitioning = true
slow_amount = 1
local run = system.load_run()
run_passive_pool = run.run_passive_pool or {
'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', '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', 'hardening', 'kinetic_strike',
}
run_time = run.time or 0
gold = run.gold or 3
passives = run.passives or {}
locked_state = run.locked_state
current_new_game_plus = run.current_new_game_plus or current_new_game_plus or 0
system.save_state()
main:add(BuyScreen'buy_screen')
main:go_to('buy_screen', run.level or 1, run.loop or 0, run.units or {}, passives, run.shop_level or 1, run.shop_xp or 0)
end, text = Text({{text = '[wavy, ' .. tostring(state.dark_transitions and 'fg' or 'bg') .. ']starting...', font = pixul_font, alignment = 'center'}}, global_text_tags)}
end}
self.options_button = Button{group = self.main_ui, x = 47, y = gh/2 + 12, force_update = true, button_text = 'options', fg_color = 'bg10', bg_color = 'bg', action = function(b)
if not self.paused then
open_options(self)
else
close_options(self)
end
end}
self.quit_button = Button{group = self.main_ui, x = 37, y = gh/2 + 34, force_update = true, button_text = 'quit', fg_color = 'bg10', bg_color = 'bg', action = function(b)
system.save_state()
steam.shutdown()
love.event.quit()
end}
self.t:every(2, function() self.soundtrack_button.spring:pull(0.025, 200, 10) end)
self.soundtrack_button = Button{group = self.main_ui, x = gw - 72, y = gh - 40, force_update = true, button_text = 'buy the soundtrack!', fg_color = 'bg10', bg_color = 'bg', action = function(b)
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
b.spring:pull(0.2, 200, 10)
b.selected = true
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
system.open_url('https://kubbimusic.com/album/ember')
end}
self.discord_button = Button{group = self.main_ui, x = gw - 92, y = gh - 17, force_update = true, button_text = 'join the community discord!', fg_color = 'bg10', bg_color = 'bg', action = function(b)
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
b.spring:pull(0.2, 200, 10)
b.selected = true
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
system.open_url('https://discord.gg/Yjk2Q5gDqA')
end}
end
function MainMenu:on_exit()
self.floor:destroy()
self.main:destroy()
self.post_main:destroy()
self.effects:destroy()
self.ui:destroy()
self.main_ui:destroy()
self.t:destroy()
self.floor = nil
self.main = nil
self.post_main = nil
self.effects = nil
self.ui = nil
self.units = nil
self.player = nil
self.t = nil
self.springs = nil
self.flashes = nil
self.hfx = nil
self.title_text = nil
end
function MainMenu:update(dt)
if main_song_instance:isStopped() then
main_song_instance = _G[random:table{'song1', 'song2', 'song3', 'song4', 'song5'}]:play{volume = 0.5}
end
if input.escape.pressed then
if not self.paused then
open_options(self)
else
close_options(self)
end
end
self:update_game_object(dt*slow_amount)
if not self.paused and not self.transitioning then
star_group:update(dt*slow_amount)
self.floor:update(dt*slow_amount)
self.main:update(dt*slow_amount)
self.post_main:update(dt*slow_amount)
self.effects:update(dt*slow_amount)
self.main_ui:update(dt*slow_amount)
if self.title_text then self.title_text:update(dt) end
self.ui:update(dt*slow_amount)
else
self.ui:update(dt*slow_amount)
end
end
function MainMenu:draw()
self.floor:draw()
self.main:draw()
self.post_main:draw()
self.effects:draw()
graphics.draw_with_mask(function()
star_canvas:draw(0, 0, 0, 1, 1)
end, function()
camera:attach()
graphics.rectangle(gw/2, gh/2, self.w, self.h, nil, nil, fg[0])
camera:detach()
end, true)
graphics.rectangle(gw/2, gh/2, 2*gw, 2*gh, nil, nil, modal_transparent)
self.main_ui:draw()
self.title_text:draw(60, gh/2 - 40)
if self.paused then graphics.rectangle(gw/2, gh/2, 2*gw, 2*gh, nil, nil, modal_transparent) end
self.ui:draw()
end