From f808b0452f494667c90be3656a3b396df860c271 Mon Sep 17 00:00:00 2001 From: a327ex Date: Wed, 9 Jun 2021 01:35:57 -0300 Subject: [PATCH] Shop update 2/5 --- arena.lua | 53 +++++++++++++++++++++++++++++++++++++++----------- buy_screen.lua | 2 ++ enemies.lua | 1 + main.lua | 51 +++++++++++++++++++++++++++++++----------------- objects.lua | 2 ++ player.lua | 41 +++++++++++++++++++++++++++++++++++--- todo | 24 ++++++++++++----------- 7 files changed, 131 insertions(+), 43 deletions(-) diff --git a/arena.lua b/arena.lua index 6e08ad7..1c5964a 100644 --- a/arena.lua +++ b/arena.lua @@ -14,6 +14,10 @@ function Arena:on_enter(from, level, units, passives) self.units = units self.passives = passives + if not state.mouse_control then + input:set_mouse_visible(false) + end + trigger:tween(2, main_song_instance, {volume = 0.5, pitch = 1}, math.linear) steam.friends.setRichPresence('steam_display', '#StatusFull') @@ -332,6 +336,7 @@ function Arena:update(dt) if input.escape.pressed and not self.transitioning and not self.in_credits and not self.choosing_passives then if not self.paused then + input:set_mouse_visible(true) trigger:tween(0.25, _G, {slow_amount = 0}, math.linear, function() slow_amount = 0 self.paused = true @@ -351,6 +356,7 @@ function Arena:update(dt) self.ng_t = nil if self.resume_button then self.resume_button.dead = true; self.resume_button = nil end if self.restart_button then self.restart_button.dead = true; self.restart_button = nil end + if self.mouse_button then self.mouse_button.dead = true; self.mouse_button = nil end if self.sfx_button then self.sfx_button.dead = true; self.sfx_button = nil end if self.music_button then self.music_button.dead = true; self.music_button = nil end if self.video_button_1 then self.video_button_1.dead = true; self.video_button_1 = nil end @@ -392,28 +398,44 @@ function Arena:update(dt) end, text = Text({{text = '[wavy, bg]restarting...', font = pixul_font, alignment = 'center'}}, global_text_tags)} end} - self.sfx_button = Button{group = self.ui, x = gw/2, y = gh - 175, force_update = true, button_text = 'toggle sfx (n)', fg_color = 'bg10', bg_color = 'bg', action = function(b) + self.mouse_button = Button{group = self.ui, x = gw/2, y = gh - 150, force_update = true, button_text = 'mouse control: ' .. tostring(state.mouse_control and 'yes' or 'no'), fg_color = 'bg10', bg_color = 'bg', + action = function(b) + ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5} + state.mouse_control = not state.mouse_control + b:set_text('mouse control: ' .. tostring(state.mouse_control and 'yes' or 'no')) + input:set_mouse_visible(state.mouse_control) + end} + + self.sfx_button = Button{group = self.ui, x = gw/2 - 46, y = gh - 175, force_update = true, button_text = 'sounds (n): ' .. tostring(state.volume_muted and 'no' or 'yes'), 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} if sfx.volume == 0.5 then sfx.volume = 0 + state.volume_muted = true elseif sfx.volume == 0 then sfx.volume = 0.5 + state.volume_muted = false end + b:set_text('sounds (n): ' .. tostring(state.volume_muted and 'no' or 'yes')) end} - self.music_button = Button{group = self.ui, x = gw/2, y = gh - 150, force_update = true, button_text = 'toggle music (m)', fg_color = 'bg10', bg_color = 'bg', action = function(b) + self.music_button = Button{group = self.ui, x = gw/2 + 46, y = gh - 175, force_update = true, button_text = 'music (m): ' .. tostring(state.music_muted and 'no' or 'yes'), 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} if music.volume == 0.5 then music.volume = 0 + state.music_muted = true elseif music.volume == 0 then music.volume = 0.5 + state.music_muted = false end + b:set_text('music (m): ' .. tostring(state.music_muted and 'no' or 'yes')) end} self.video_button_1 = Button{group = self.ui, x = gw/2 - 86, y = gh - 125, force_update = true, button_text = 'window size-', fg_color = 'bg10', bg_color = 'bg', action = function() @@ -499,6 +521,9 @@ function Arena:update(dt) end} end, 'pause') else + if not state.mouse_control then + input:set_mouse_visible(false) + end trigger:tween(0.25, _G, {slow_amount = 1}, math.linear, function() slow_amount = 1 self.paused = false @@ -510,6 +535,7 @@ function Arena:update(dt) self.ng_t = nil if self.resume_button then self.resume_button.dead = true; self.resume_button = nil end if self.restart_button then self.restart_button.dead = true; self.restart_button = nil end + if self.mouse_button then self.mouse_button.dead = true; self.mouse_button = nil end if self.sfx_button then self.sfx_button.dead = true; self.sfx_button = nil end if self.music_button then self.music_button.dead = true; self.music_button = nil end if self.video_button_1 then self.video_button_1.dead = true; self.video_button_1 = nil end @@ -807,6 +833,7 @@ function Arena:quit() else if not self.arena_clear_text then self.arena_clear_text = Text2{group = self.ui, x = gw/2, y = gh/2 - 48, lines = {{text = '[wavy_mid, cbyc]arena clear!', font = fat_font, alignment = 'center'}}} end + self:gain_gold() self.t:after(3, function() if self.level % 3 == 0 then self.arena_clear_text.dead = true @@ -1030,11 +1057,15 @@ function Arena:create_credits() end +function Arena:gain_gold() + 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) + gold = gold + self.gold_gained + self.interest +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]) - local interest = math.min(math.floor(gold/5), 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) slow_amount = 1 @@ -1043,23 +1074,23 @@ function Arena:transition() main:go_to('buy_screen', self.level, self.units, self.passives) 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 = '[nudge_down, bg]gold gained: ' .. tostring(self.gold_gained or 0), font = pixul_font, alignment = 'center', height_multiplier = 1.5}, {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]interest: ' .. tostring(interest), font = pixul_font, alignment = 'center', height_multiplier = 1.5}, + {text = '[wavy_lower, bg]gold gained: ' .. tostring(self.gold_gained or 0), font = pixul_font, alignment = 'center', height_multiplier = 1.5}, + {text = '[nudge_down, bg]interest: ' .. tostring(self.interest or 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 = '[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'} + {text = '[wavy_lower, bg]gold gained: ' .. tostring(self.gold_gained or 0), font = pixul_font, alignment = 'center', height_multiplier = 1.5}, + {text = '[wavy_lower, bg]interest: ' .. tostring(self.interest or 0), font = pixul_font, alignment = 'center', height_multiplier = 1.5}, + {text = '[nudge_down, bg]total: ' .. tostring((self.gold_gained or 0) + (self.interest or 0)), font = pixul_font, alignment = 'center'} }) _G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5} end) diff --git a/buy_screen.lua b/buy_screen.lua index 529f2cf..782594f 100644 --- a/buy_screen.lua +++ b/buy_screen.lua @@ -43,6 +43,8 @@ function BuyScreen:on_enter(from, level, units, passives) self.passives = passives camera.x, camera.y = gw/2, gh/2 + 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 diff --git a/enemies.lua b/enemies.lua index 262a5d8..bbd63a0 100644 --- a/enemies.lua +++ b/enemies.lua @@ -637,6 +637,7 @@ function EnemyCritter:update(dt) if self.slowed then self.slow_mvspd_m = self.slowed else self.slow_mvspd_m = 1 end self.buff_mvspd_m = (self.speed_boosting_mvspd_m or 1)*(self.slow_mvspd_m or 1)*(self.temporal_chains_mvspd_m or 1) + if not self.classes then return end self:calculate_stats() if self.being_pushed then diff --git a/main.lua b/main.lua index ea54784..dfcb3d8 100644 --- a/main.lua +++ b/main.lua @@ -9,6 +9,7 @@ require 'media' function init() + print('Initializing engine...') shared_init() input:bind('move_left', {'a', 'left', 'dpleft', 'm1'}) @@ -17,6 +18,7 @@ function init() input:bind('move_down', {'s', 'down', 'dpdown'}) input:bind('enter', {'space', 'return', 'fleft', 'fdown', 'fright'}) + print('Loading sounds...') local s = {tags = {sfx}} psychic1 = Sound('Magical Impact 13.ogg', s) fire1 = Sound('Fire bolt 3.ogg', s) @@ -109,6 +111,7 @@ function init() rogue_crit1 = Sound('Dagger Stab (Flesh) 4.ogg', s) rogue_crit2 = Sound('Sword hits another sword 6.ogg', s) + print('Loading songs...') song1 = Sound('Kubbi - Ember - 01 Pathfinder.ogg', {tags = {music}}) song2 = Sound('Kubbi - Ember - 02 Ember.ogg', {tags = {music}}) song3 = Sound('Kubbi - Ember - 03 Firelight.ogg', {tags = {music}}) @@ -116,6 +119,7 @@ function init() song5 = Sound('Kubbi - Ember - 05 Compass.ogg', {tags = {music}}) death_song = Sound('Kubbi - Ember - 09 Formed by Glaciers.ogg', {tags = {music}}) + print('Loading images...') lock_image = Image('lock') speed_booster_elite = Image('speed_booster_elite') exploder_elite = Image('exploder_elite') @@ -181,6 +185,7 @@ function init() star = Image('star') arrow = Image('arrow') + print('Initializing game...') class_colors = { ['warrior'] = yellow[0], ['ranger'] = green[0], @@ -1309,7 +1314,7 @@ function init() if not state.new_game_plus then state.new_game_plus = new_game_plus end current_new_game_plus = state.current_new_game_plus or new_game_plus if not state.current_new_game_plus then state.current_new_game_plus = current_new_game_plus end - max_units = 7 + new_game_plus + max_units = 7 + current_new_game_plus main = Main() @@ -1325,15 +1330,15 @@ function init() --[[ main:add(Arena'arena') - main:go_to('arena', 21, { - {character = 'arcanist', level = 3}, + main:go_to('arena', 17, { + {character = 'arcanist', level = 2}, {character = 'silencer', level = 2}, - {character = 'warden', level = 2}, + {character = 'warden', level = 3}, {character = 'chronomancer', level = 1}, - {character = 'witch', level = 2}, + {character = 'witch', level = 3}, {character = 'illusionist', level = 3}, {character = 'psychic', level = 2}, - {character = 'vulcanist', level = 2}, + {character = 'vulcanist', level = 3}, }, passives) ]]-- @@ -1380,22 +1385,32 @@ function update(dt) ]]-- if input.n.pressed then - if sfx.volume == 0.5 then - sfx.volume = 0 - state.volume_muted = true - elseif sfx.volume == 0 then - sfx.volume = 0.5 - state.volume_muted = false + if main.current.sfx_button then + main.current.sfx_button:action() + main.current.sfx_button.selected = false + else + if sfx.volume == 0.5 then + sfx.volume = 0 + state.volume_muted = true + elseif sfx.volume == 0 then + sfx.volume = 0.5 + state.volume_muted = false + end end end if input.m.pressed then - if music.volume == 0.5 then - state.music_muted = true - music.volume = 0 - elseif music.volume == 0 then - music.volume = 0.5 - state.music_muted = false + if main.current.music_button then + main.current.music_button:action() + main.current.music_button.selected = false + else + if music.volume == 0.5 then + state.music_muted = true + music.volume = 0 + elseif music.volume == 0 then + music.volume = 0.5 + state.music_muted = false + end end end diff --git a/objects.lua b/objects.lua index 5ea29b4..b3a1b58 100644 --- a/objects.lua +++ b/objects.lua @@ -237,6 +237,7 @@ function Unit:calculate_stats(first_run) self.base_dmg = (12 + current_new_game_plus*2) + (2 + current_new_game_plus)*y[x] self.base_mvspd = 35 + 1.5*y[x] if x == 25 then + self.base_dmg = (12 + current_new_game_plus*2) + (1.25 + current_new_game_plus)*y[x] self.base_mvspd = 35 + 1.2*y[x] end else @@ -254,6 +255,7 @@ function Unit:calculate_stats(first_run) self.base_dmg = (12 + current_new_game_plus*2) + (2 + current_new_game_plus)*y[x] self.base_mvspd = 35 + 1.5*y[x] if x == 25 then + self.base_dmg = (12 + current_new_game_plus*2) + (2 + 0.5*current_new_game_plus)*y[x] self.base_mvspd = 35 + 1.2*y[x] end else diff --git a/player.lua b/player.lua index ab680f1..647c4d5 100644 --- a/player.lua +++ b/player.lua @@ -261,7 +261,14 @@ function Player:init(args) if x == 0 and y == 0 then x, y = gw/2, gh/2 end x, y = x + self.x, y + self.y x, y = x/2, y/2 - Volcano{group = main.current.main, x = x, y = y, color = self.color, parent = self, rs = 24, level = self.level} + trigger:every_immediate(0.1, function() + local check_circle = Circle(x, y, 2) + local objects = main.current.main:get_objects_in_shape(check_circle, {Player, Seeker, EnemyCritter, Critter, Illusion, Saboteur, Pet, Turret}) + if #objects == 0 then + Volcano{group = main.current.main, x = x, y = y, color = self.color, parent = self, rs = 24, level = self.level} + trigger:cancel('volcano_spawn') + end + end, nil, nil, 'volcano_spawn') end volcano() if main.current.sorcerer_level > 0 then @@ -596,17 +603,39 @@ function Player:init(args) local unit_2 = random:table_remove(units) if unit_1 then illusion1:play{pitch = random:float(0.95, 1.05), volume = 0.5} - ForceField{group = main.current.main, x = unit_1.x, y = unit_1.y, parent = unit_1} + trigger:every_immediate(0.1, function() + local check_circle = Circle(unit_1.x, unit_1.y, 6) + local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter}) + if #objects == 0 then + ForceField{group = main.current.main, x = unit_1.x, y = unit_1.y, parent = unit_1} + trigger:cancel('warden_force_field_1') + end + end, nil, nil, 'warden_force_field_1') end if unit_2 then illusion1:play{pitch = random:float(0.95, 1.05), volume = 0.5} ForceField{group = main.current.main, x = unit_2.x, y = unit_2.y, parent = unit_2} + trigger:every_immediate(0.1, function() + local check_circle = Circle(unit_2.x, unit_2.y, 6) + local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter}) + if #objects == 0 then + ForceField{group = main.current.main, x = unit_2.x, y = unit_2.y, parent = unit_2} + trigger:cancel('warden_force_field_2') + end + end, nil, nil, 'warden_force_field_2') end else local unit = random:table(self:get_all_units()) if unit then illusion1:play{pitch = random:float(0.95, 1.05), volume = 0.5} - ForceField{group = main.current.main, x = unit.x, y = unit.y, parent = unit} + trigger:every_immediate(0.1, function() + local check_circle = Circle(unit.x, unit.y, 6) + local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter}) + if #objects == 0 then + ForceField{group = main.current.main, x = unit.x, y = unit.y, parent = unit} + trigger:cancel('warden_force_field_0') + end + end, nil, nil, 'warden_force_field_0') end end end @@ -1022,6 +1051,11 @@ function Player:update(dt) if input.move_left.down then self.r = self.r - 1.66*math.pi*dt end if input.move_right.down then self.r = self.r + 1.66*math.pi*dt end + if state.mouse_control then + local v = Vector(math.cos(self.r), math.sin(self.r)):perpendicular():dot(Vector(math.cos(self:angle_to_mouse()), math.sin(self:angle_to_mouse()))) + self.r = self.r + math.sign(v)*1.66*math.pi*dt + end + local total_v = 0 local units = self:get_all_units() for _, unit in ipairs(units) do @@ -2522,6 +2556,7 @@ Pet:implement(GameObject) Pet:implement(Physics) function Pet:init(args) self:init_game_object(args) + if tostring(self.x) == tostring(0/0) or tostring(self.y) == tostring(0/0) then self.dead = true; return end self:set_as_rectangle(8, 8, 'dynamic', 'projectile') self:set_restitution(0.5) self.hfx:add('hit', 1) diff --git a/todo b/todo index 682be12..c715cf0 100644 --- a/todo +++ b/todo @@ -16,18 +16,17 @@ Shop Update Owned units highlighted in shop Fix highlight colors and highlight reserve Shop level up + Remove level 3 units from rotation + + Item changes QoL * Added sorcerer achievement * Removed restart button from end screen * First item reroll is now free - Gold is given right after the round ends in the arena rather than on the shop for easier item rerolls - Show hero HP - Endless mode - Remove level 3 units from rotation - Hide cursor during waves - Mouse follow control - Volume slider + * Gold is given right after the round ends in the arena rather than on the shop for easier item rerolls + * Added mouse follow control mode + * The cursor is now invisible during waves, unless mouse follow mode is enabled Options menu from buy screen Add visuals for defensive ouroboros, divine intervention, fairy buff @@ -37,13 +36,15 @@ Shop Update Bug fixes * Fixed a crash when too many illusions would be spawned in short succession * Fixed a bug where enemy critters would sometimes be unkillable + * Fixed a rare crash involving broken enemy critter state * Fixed text for the illusionist's Lv.3 effect going outside the screen * Fixed a rare crash when hovering over your owned in the shop - Fix a crash when warden's force field would spawn on top of enemies - Fix enemies still spawning after arena clear (this happens with the extra enemy spawns that were blocked earlier) + * Fixed a crash when warden's force field would spawn on top of enemies + * Fixed a crash when a pet would spawn on top of enemies + * Fixed a bug where the maximum number of units would be wrong on certain conditions + Fix bug where quitting on level 2 arena goes back to level 1 shop Fix fullscreen with different resolutions that don't scale properly - https://i.imgur.com/Lxu8skX.png - https://i.imgur.com/mnivI4d.png + Fix enemies still spawning after arena clear (this happens with the extra enemy spawns that were blocked earlier) Sacrifice Update New mechanics @@ -64,6 +65,7 @@ Sacrifice Update Zombie QoL Current items visible on item selection screen + Endless mode ---