master
a327ex 2021-03-15 01:01:04 -03:00
parent 9b0c6aa343
commit bb737a618e
8 changed files with 219 additions and 218 deletions

View File

@ -29,8 +29,10 @@ function Arena:on_enter(from, level, units)
self.main:enable_trigger_between('projectile', 'enemy') self.main:enable_trigger_between('projectile', 'enemy')
self.main:enable_trigger_between('enemy_projectile', 'player') self.main:enable_trigger_between('enemy_projectile', 'player')
self.damage_dealt = 0
self.damage_taken = 0
self.main_slow_amount = 1
self.enemies = {Seeker} self.enemies = {Seeker}
self.resources_gained = 0
self.color = self.color or fg[0] self.color = self.color or fg[0]
-- Spawn solids and player -- Spawn solids and player
@ -237,7 +239,7 @@ function Arena:update(dt)
else self.enchanter_dmg_m = 1 end else self.enchanter_dmg_m = 1 end
self.floor:update(dt*slow_amount) self.floor:update(dt*slow_amount)
self.main:update(dt*slow_amount) self.main:update(dt*slow_amount*self.main_slow_amount)
self.post_main:update(dt*slow_amount) self.post_main:update(dt*slow_amount)
self.effects:update(dt*slow_amount) self.effects:update(dt*slow_amount)
self.ui:update(dt*slow_amount) self.ui:update(dt*slow_amount)
@ -245,6 +247,8 @@ function Arena:update(dt)
if self.can_quit and #self.main:get_objects_by_classes(self.enemies) <= 0 then if self.can_quit and #self.main:get_objects_by_classes(self.enemies) <= 0 then
self.can_quit = false self.can_quit = false
self.transitioning = true 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
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 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.t:after(3, function() self.t:after(3, function()
self.transitioning = false self.transitioning = false
@ -254,32 +258,32 @@ function Arena:update(dt)
main:go_to('buy_screen', self.level, self.units) main:go_to('buy_screen', self.level, self.units)
t.t:after(0.1, function() t.t:after(0.1, function()
t.text:set_text({ t.text:set_text({
{text = '[nudge_down, bg]resources gained: ' .. tostring(self.resources_gained), font = pixul_font, alignment = 'center', height_multiplier = 1.5}, {text = '[nudge_down, bg]gold gained: ' .. tostring(gold_gained), 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]damage taken: 0', font = pixul_font, alignment = 'center', height_multiplier = 1.5},
{text = '[wavy_lower, bg]total: 0', font = pixul_font, alignment = 'center'} {text = '[wavy_lower, bg]damage dealt: 0', font = pixul_font, alignment = 'center'}
}) })
_G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5} _G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
t.t:after(0.2, function() t.t:after(0.2, function()
t.text:set_text({ t.text:set_text({
{text = '[wavy_lower, bg]resources gained: ' .. tostring(self.resources_gained), font = pixul_font, alignment = 'center', height_multiplier = 1.5}, {text = '[wavy_lower, bg]gold gained: ' .. tostring(gold_gained), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
{text = '[nudge_down, bg]interest: ' .. tostring(math.floor(resource/10)), 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]total: 0', font = pixul_font, alignment = 'center'} {text = '[wavy_lower, bg]damage dealt: 0', font = pixul_font, alignment = 'center'}
}) })
_G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5} _G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
t.t:after(0.2, function() t.t:after(0.2, function()
t.text:set_text({ t.text:set_text({
{text = '[wavy_lower, bg]resources gained: ' .. tostring(self.resources_gained), font = pixul_font, alignment = 'center', height_multiplier = 1.5}, {text = '[wavy_lower, bg]gold gained: ' .. tostring(gold_gained), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
{text = '[wavy_lower, bg]interest: ' .. tostring(math.floor(resource/10)), 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]total: ' .. tostring(self.resources_gained + math.floor(resource/10)), font = pixul_font, alignment = 'center'} {text = '[nudge_down, bg]damage dealt: ' .. tostring(math.round(self.damage_dealt, 0)), font = pixul_font, alignment = 'center'}
}) })
_G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5} _G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
end) end)
end) end)
end) end)
end, text = Text({ end, text = Text({
{text = '[wavy_lower, bg]resources gained: 0', font = pixul_font, alignment = 'center', height_multiplier = 1.5}, {text = '[wavy_lower, bg]gold gained: 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]damage taken: 0', font = pixul_font, alignment = 'center', height_multiplier = 1.5},
{text = '[wavy_lower, bg]total: 0', font = pixul_font, alignment = 'center'} {text = '[wavy_lower, bg]damage dealt: 0', font = pixul_font, alignment = 'center'}
}, global_text_tags)} }, global_text_tags)}
end, 'transition') end, 'transition')
end end
@ -334,6 +338,23 @@ function Arena:draw()
end end
function Arena:die()
if not self.died_text then
self.died = true
self.t:tween(2, self, {main_slow_amount = 0}, math.linear, function() self.main_slow_amount = 0 end)
self.died_text = Text2{group = self.ui, x = gw/2, y = gh/2 - 32, lines = {
{text = '[wavy_mid, cbyc]you died...', font = fat_font, alignment = 'center', height_multiplier = 1.25},
}}
self.t:after(2, function()
self.death_info_text = Text2{group = self.ui, x = gw/2, y = gh/2 + 16, sx = 0.7, sy = 0.7, lines = {
{text = '[wavy_mid, light_bg]level reached: [wavy_mid, yellow]' .. self.level, font = fat_font, alignment = 'center'},
{text = '[wavy_mid, light_bg]r - start new run', font = fat_font, alignment = 'center'},
}}
end)
end
end
function Arena:enemy_killed() function Arena:enemy_killed()
if self.win_condition == 'enemy_kill' then if self.win_condition == 'enemy_kill' then
self.enemies_killed = self.enemies_killed + 1 self.enemies_killed = self.enemies_killed + 1
@ -384,6 +405,7 @@ end
function Arena:spawn_n_enemies(p, j, n) function Arena:spawn_n_enemies(p, j, n)
if self.died then return end
j = j or 1 j = j or 1
n = n or 4 n = n or 4
self.last_spawn_enemy_time = love.timer.getTime() self.last_spawn_enemy_time = love.timer.getTime()

View File

@ -7,46 +7,53 @@ function BuyScreen:init(name)
end end
function BuyScreen:on_exit()
self.main:destroy()
self.effects:destroy()
self.ui:destroy()
self.main = nil
self.effects = nil
self.ui = nil
self.shop_text = nil
self.party_text = nil
self.sets_text = nil
self.items_text = nil
self.under_text = nil
self.characters = nil
self.sets = nil
self.cards = nil
self.info_text = nil
end
function BuyScreen:on_enter(from, level, units) function BuyScreen:on_enter(from, level, units)
self.level = level self.level = level
self.units = units self.units = units
camera.x, camera.y = gw/2, gh/2
if self.level == 0 then
self.level = 1
self.first_screen = true
end
self.main = Group() self.main = Group()
self.effects = Group() self.effects = Group()
self.ui = Group() self.ui = Group()
if self.level == 0 then self:set_cards()
pop1:play{pitch = random:float(0.95, 1.05), volume = 0.5} self:set_party_and_sets()
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
player_hit_wall1:play{pitch = r, volume = 0.5}
self.first_screen = true
self.cards = {}
self.selected_card_index = 1
local units = {'vagrant', 'swordsman', 'wizard', 'archer', 'scout', 'cleric'}
self.cards[1] = PairCard{group = self.main, x = gw/2, y = 85, w = gw, h = gh/4, unit_1 = random:table_remove(units), unit_2 = random:table_remove(units), i = 1, parent = self}
local units = {'vagrant', 'swordsman', 'wizard', 'archer', 'scout', 'cleric'}
self.cards[2] = PairCard{group = self.main, x = gw/2, y = 155, w = gw, h = gh/4, unit_1 = random:table_remove(units), unit_2 = random:table_remove(units), i = 2, parent = self}
local units = {'vagrant', 'swordsman', 'wizard', 'archer', 'scout', 'cleric'}
self.cards[3] = PairCard{group = self.main, x = gw/2, y = 225, w = gw, h = gh/4, unit_1 = random:table_remove(units), unit_2 = random:table_remove(units), i = 3, parent = self}
self.title_sy = 1
self.title = Text({{text = '[wavy_mid, fg]choose your initial party', font = pixul_font, alignment = 'center'}}, global_text_tags)
else self.shop_text = Text({{text = '[wavy_mid, fg]shop [fg]- gold: [yellow]' .. gold, font = pixul_font, alignment = 'center'}}, global_text_tags)
self:set_cards() self.party_text = Text({{text = '[wavy_mid, fg]party', font = pixul_font, alignment = 'center'}}, global_text_tags)
self:set_party_and_sets() self.sets_text = Text({{text = '[wavy_mid, fg]sets', 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.under_text = Text2{group = self.main, x = 140, y = gh - 60, r = -math.pi/48, lines = {
{text = '[light_bg]under', font = fat_font, alignment = 'center'},
{text = '[light_bg]construction', font = fat_font, alignment = 'center'},
}}
self.shop_text = Text({{text = '[wavy_mid, fg]shop [fg]- gold: [yellow]' .. gold, 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
self.party_text = Text({{text = '[wavy_mid, fg]party', font = pixul_font, alignment = 'center'}}, global_text_tags) GoButton{group = self.main, x = gw - 30, y = gh - 20, parent = self}
self.sets_text = Text({{text = '[wavy_mid, fg]sets', 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.under_text = Text2{group = self.main, x = 140, y = gh - 60, r = -math.pi/48, lines = {
{text = '[light_bg]under', font = fat_font, alignment = 'center'},
{text = '[light_bg]construction', font = fat_font, alignment = 'center'},
}}
RerollButton{group = self.main, x = 150, y = 18, parent = self}
GoButton{group = self.main, x = gw - 30, y = gh - 20, parent = self}
end
end end
@ -56,59 +63,10 @@ function BuyScreen:update(dt)
self.effects:update(dt*slow_amount) self.effects:update(dt*slow_amount)
self.ui:update(dt*slow_amount) self.ui:update(dt*slow_amount)
if self.level == 0 and self.first_screen then if self.shop_text then self.shop_text:update(dt) end
if self.title then self.title:update(dt) end if self.sets_text then self.sets_text:update(dt) end
if self.party_text then self.party_text:update(dt) end
if input.move_up.pressed then if self.items_text then self.items_text:update(dt) end
self.selected_card_index = self.selected_card_index - 1
if self.selected_card_index == 0 then self.selected_card_index = 3 end
for i = 1, 3 do self.cards[i]:unselect() end
self.cards[self.selected_card_index]:select()
pop1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
player_hit_wall1:play{pitch = r, volume = 0.5}
end
if input.move_down.pressed then
self.selected_card_index = self.selected_card_index + 1
if self.selected_card_index == 4 then self.selected_card_index = 1 end
for i = 1, 3 do self.cards[i]:unselect() end
self.cards[self.selected_card_index]:select()
pop1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
player_hit_wall1:play{pitch = r, volume = 0.5}
end
if input.enter.pressed and not self.transitioning then
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
self.t:tween(0.1, self, {title_sy = 0}, math.linear, function() self.title_sy = 0; self.title = nil end)
local unit_1, unit_2 = self.cards[self.selected_card_index].unit_1, self.cards[self.selected_card_index].unit_2
TransitionEffect{group = main.transitions, x = 50, y = 85 + (self.selected_card_index-1)*70, color = character_colors[unit_1], transition_action = function()
main:add(Arena'arena')
main:go_to('arena', 1, {{character = unit_1, level = 1}, {character = unit_2, level = 1}})
end}
--[[
, text = Text({
{text = '[' .. character_color_strings[unit_1] .. ']' .. unit_1:upper() .. ' [yellow]Lv.1 [fg]- ' .. table.reduce(character_classes[unit_1],
function(memo, v) return memo .. '[' .. class_color_strings[v] .. ']' .. v .. '[fg], ' end, ''):sub(1, -3), font = pixul_font, height_multiplier = 1.7, alignment = 'center'},
{text = character_stats[unit_1](1), font = pixul_font, height_multiplier = 1.3, alignment = 'center'},
{text = character_descriptions[unit_1](get_character_stat(unit_1, 1, 'dmg')), font = pixul_font, alignment = 'center', height_multiplier = 3},
{text = '[' .. character_color_strings[unit_2] .. ']' .. unit_2:upper() .. ' [yellow]Lv.1 [fg]- ' .. table.reduce(character_classes[unit_2],
function(memo, v) return memo .. '[' .. class_color_strings[v] .. ']' .. v .. '[fg], ' end, ''):sub(1, -3), font = pixul_font, height_multiplier = 1.7, alignment = 'center'},
{text = character_stats[unit_2](1), font = pixul_font, height_multiplier = 1.3, alignment = 'center'},
{text = character_descriptions[unit_2](get_character_stat(unit_2, 1, 'dmg')), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
}, global_text_tags)}
]]--
end
else
if self.shop_text then self.shop_text:update(dt) end
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
end
end end
@ -118,19 +76,15 @@ function BuyScreen:draw()
if self.items_text then self.items_text:draw(32, 150) end if self.items_text then self.items_text:draw(32, 150) end
self.ui:draw() self.ui:draw()
if self.level == 0 then if self.shop_text then self.shop_text:draw(64, 20) end
if self.title then self.title:draw(3.25*gw/4, 32, 0, 1, self.title_sy) end if self.sets_text then self.sets_text:draw(328, 20) end
else if self.party_text then self.party_text:draw(440, 20) end
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
end
end end
function BuyScreen:buy(character, i) function BuyScreen:buy(character, i)
local bought local bought
if table.any(self.units, function(v) return v.character == character end) then if table.any(self.units, function(v) return v.character == character end) and gold >= character_tiers[character] then
gold = gold - character_tiers[character] gold = gold - character_tiers[character]
self.shop_text:set_text{{text = '[wavy_mid, fg]shop [fg]- [fg, nudge_down]gold: [yellow, nudge_down]' .. gold, font = pixul_font, alignment = 'center'}} self.shop_text:set_text{{text = '[wavy_mid, fg]shop [fg]- [fg, nudge_down]gold: [yellow, nudge_down]' .. gold, font = pixul_font, alignment = 'center'}}
for _, unit in ipairs(self.units) do for _, unit in ipairs(self.units) do
@ -170,10 +124,12 @@ function BuyScreen:buy(character, i)
end end
self.t:after(2, function() self.info_text:deactivate(); self.info_text.dead = true; self.info_text = nil end, 'info_text') self.t:after(2, function() self.info_text:deactivate(); self.info_text.dead = true; self.info_text = nil end, 'info_text')
else else
gold = gold - character_tiers[character] if gold >= character_tiers[character] then
self.shop_text:set_text{{text = '[wavy_mid, fg]shop [fg]- [fg, nudge_down]gold: [yellow, nudge_down]' .. gold, font = pixul_font, alignment = 'center'}} gold = gold - character_tiers[character]
table.insert(self.units, {character = character, level = 1, reserve = {0, 0}}) self.shop_text:set_text{{text = '[wavy_mid, fg]shop [fg]- [fg, nudge_down]gold: [yellow, nudge_down]' .. gold, font = pixul_font, alignment = 'center'}}
bought = true table.insert(self.units, {character = character, level = 1, reserve = {0, 0}})
bought = true
end
end end
end end
self:set_party_and_sets() self:set_party_and_sets()
@ -223,27 +179,39 @@ GoButton = Object:extend()
GoButton:implement(GameObject) GoButton:implement(GameObject)
function GoButton:init(args) function GoButton:init(args)
self:init_game_object(args) self:init_game_object(args)
self.shape = Rectangle(self.x, self.y, 24, 16) self.shape = Rectangle(self.x, self.y, 28, 18)
self.interact_with_mouse = true self.interact_with_mouse = true
self.text = Text({{text = '[bg10]go!', font = pixul_font, alignment = 'center'}}, global_text_tags) self.text = Text({{text = '[bg10]GO!', font = pixul_font, alignment = 'center'}}, global_text_tags)
end end
function GoButton:update(dt) function GoButton:update(dt)
self:update_game_object(dt) self:update_game_object(dt)
if self.selected and input.m1.pressed and not self.transitioning then if self.selected and input.m1.pressed and not self.transitioning then
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5} if #self.parent.units == 0 then
self.spring:pull(0.2, 200, 10) if not self.info_text then
self.selected = true error1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
self.info_text = InfoText{group = main.current.ui}
self.info_text:activate({
{text = '[fg]cannot start the round with [yellow]0 [fg]units', font = pixul_font, alignment = 'center'},
}, nil, nil, nil, nil, 16, 4, nil, 2)
self.info_text.x, self.info_text.y = gw/2, gh/2 + 10
end
self.t:after(2, function() self.info_text:deactivate(); self.info_text.dead = true; self.info_text = nil end, 'info_text')
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5} else
ui_transition1:play{pitch = random:float(0.95, 1.05), volume = 0.5} ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
self.transitioning = true self.spring:pull(0.2, 200, 10)
self.selected = true
TransitionEffect{group = main.transitions, x = self.x, y = self.y, color = character_colors[random:table(self.parent.units).character], transition_action = function() ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
main:add(Arena'arena') ui_transition1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
main:go_to('arena', 1, self.parent.units) self.transitioning = true
end} TransitionEffect{group = main.transitions, x = self.x, y = self.y, color = 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)
end, text = Text({{text = '[wavy, bg]level ' .. ((self.parent.first_screen and 1) or (self.parent.level + 1)), font = pixul_font, alignment = 'center'}}, global_text_tags)}
end
end end
end end
@ -260,13 +228,13 @@ function GoButton:on_mouse_enter()
ui_hover1:play{pitch = random:float(1.3, 1.5), volume = 0.5} 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} pop2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
self.selected = true self.selected = true
self.text:set_text{{text = '[fgm5]go!', font = pixul_font, alignment = 'center'}} self.text:set_text{{text = '[fgm5]GO!', font = pixul_font, alignment = 'center'}}
self.spring:pull(0.2, 200, 10) self.spring:pull(0.2, 200, 10)
end end
function GoButton:on_mouse_exit() function GoButton:on_mouse_exit()
self.text:set_text{{text = '[bg10]go!', font = pixul_font, alignment = 'center'}} self.text:set_text{{text = '[bg10]GO!', font = pixul_font, alignment = 'center'}}
self.selected = false self.selected = false
end end
@ -682,85 +650,3 @@ function ClassIcon:die(dont_spawn_effect)
self.info_text = nil self.info_text = nil
end end
end end
PairCard = Object:extend()
PairCard:implement(GameObject)
function PairCard:init(args)
self:init_game_object(args)
self.plus_r = 0
if self.i == 1 then self:select() end
end
function PairCard:update(dt)
self:update_game_object(dt)
end
function PairCard:select()
self.selected = true
self.spring:pull(0.2, 200, 10)
self.t:every_immediate(1.4, function()
if self.selected then
self.t:tween(0.7, self, {sx = 0.97, sy = 0.97, plus_r = -math.pi/32}, math.linear, function()
self.t:tween(0.7, self, {sx = 1.03, sy = 1.03, plus_r = math.pi/32}, math.linear, nil, 'pulse_1')
end, 'pulse_2')
end
end, nil, nil, 'pulse')
end
function PairCard:unselect()
self.selected = false
self.t:cancel'pulse'
self.t:cancel'pulse_1'
self.t:cancel'pulse_2'
self.t:tween(0.1, self, {sx = 1, sy = 1, plus_r = 0}, math.linear, function() self.sx, self.sy, self.plus_r = 1, 1, 0 end, 'pulse')
end
function PairCard:draw()
local x = self.x - self.w/3
if self.selected then
graphics.push(x + (fat_font:get_text_width(self.i) + 20)/2, self.y - 25 + 37/2, 0, self.spring.x*self.sx, self.spring.x*self.sy)
graphics.rectangle2(x - 52, self.y - 25, fat_font:get_text_width(self.i) + 20, 37, 6, 6, bg[2])
graphics.pop()
end
-- 1, 2, 3
graphics.push(x - 40 + fat_font:get_text_width(self.i)/2, self.y - fat_font.h/8, 0, self.spring.x*self.sx, self.spring.x*self.sy)
graphics.print(self.i, fat_font, x - 40, self.y, 0, self.sx, self.sy, nil, fat_font.h/2, fg[0])
graphics.pop()
-- Unit 1 + class symbols
graphics.push(x + (fat_font:get_text_width(self.unit_1:capitalize() .. 'w') + table.reduce(character_classes[self.unit_1], function(memo, v) return memo + 0.5*_G[v].w end, 0))/2, self.y - fat_font.h/8, 0,
self.spring.x*self.sx, self.spring.x*self.sy)
graphics.print(self.unit_1:capitalize(), fat_font, x, self.y, 0, 1, 1, nil, fat_font.h/2, character_colors[self.unit_1])
x = x + fat_font:get_text_width(self.unit_1 .. 'w')
for i, class in ipairs(character_classes[self.unit_1]) do
_G[class]:draw(x, self.y, 0, 0.4, 0.4, nil, 20, class_colors[class])
x = x + 0.5*_G[class].w
end
graphics.pop()
-- +
graphics.push(x + fat_font:get_text_width('+')/2, self.y, self.plus_r, self.spring.x*self.sx, self.spring.x*self.sy)
graphics.print('+', fat_font, x, self.y, 0, 1, 1, nil, fat_font.h/2, fg[0])
graphics.pop()
-- Unit 2 + class symbols
x = x + fat_font:get_text_width('+l')
graphics.push(x + (fat_font:get_text_width(self.unit_2:capitalize() .. 'w') + table.reduce(character_classes[self.unit_2], function(memo, v) return memo + 0.5*_G[v].w end, 0))/2, self.y - fat_font.h/8, 0,
self.spring.x*self.sx, self.spring.x*self.sy)
graphics.print(self.unit_2:capitalize(), fat_font, x, self.y, 0, 1, 1, nil, fat_font.h/2, character_colors[self.unit_2])
x = x + fat_font:get_text_width(self.unit_2 .. 'w')
for i, class in ipairs(character_classes[self.unit_2]) do
_G[class]:draw(x, self.y, 0, 0.4, 0.4, nil, 20, class_colors[class])
x = x + 0.5*_G[class].w
end
graphics.pop()
end

View File

@ -365,3 +365,33 @@ I'm planning will probably help with this, especially the idea of everything sim
Finished buy screen. Now the only two things left is are redoing the first screen to take advantage of all the UI built for the buy screen, balance/progression and then fixing smaller details and finishing everything up. Finished buy screen. Now the only two things left is are redoing the first screen to take advantage of all the UI built for the buy screen, balance/progression and then fixing smaller details and finishing everything up.
I can probably finish it all before day 30 which would be great. I can probably finish it all before day 30 which would be great.
# Day 26 - 14/03/21
The game is finally playable from start to finish. It is pretty fun as it is but it's clear that a few things need to be added so it can be even better. I'll add these after I release the demo with the game in the current
state since these additions will take some time and I don't want to delay the demo's release any more than necessary.
#### Enemy Modifiers
Enemies right now feel pretty samey, and a few small modifiers would help a lot:
* Grant nearby enemies a speed boost on death
* Grant nearby enemies a damage boost on death
* Explode into projectiles on death
* Charge up and headbutt towards the player at increased speed and damage
* Immune to knockback
#### Mini Boss
Every 3rd level there should be a difficult increase in the multiplier for enemy stats as well as a mini boss. This mini boss has significantly increased HP and damage and can spawn enemies of his own on top of the ones
spawned by the level. He can also grant modifiers to enemies. Upon completing such a level, the player will be granted the chance to choose 1 out of 3 passive items.
#### Other Ideas
* Show a unit DPS list like Underlord's to the right side of the screen
* About 20-30 passive items that can be collected every 3 levels
* Lv.3 effects for every character
* New classes and characters (I'm not in idea guy mode ATM so I can't think of much, but it will come to me eventually):
* Trapper: releases +1 trap
* Plague Doctor [trapper, nuker]: releases an area that deals 6 AoE DoT
* Fisherman [trapper, warrior]: throws a net that entangles enemies and prevents them from moving

View File

@ -81,6 +81,7 @@ function Seeker:hit(damage)
local actual_damage = self:calculate_damage(damage) local actual_damage = self:calculate_damage(damage)
self.hp = self.hp - actual_damage self.hp = self.hp - actual_damage
main.current.damage_dealt = main.current.damage_dealt + actual_damage
if self.hp <= 0 then if self.hp <= 0 then
self.dead = true self.dead = true
for i = 1, random:int(4, 6) do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = self.color} end for i = 1, random:int(4, 6) do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = self.color} end

View File

@ -154,7 +154,7 @@ end
function Group:destroy() function Group:destroy()
for _, object in ipairs(self.objects) do object:destroy() end for _, object in ipairs(self.objects) do if object.destroy then object:destroy() end end
self.objects = {} self.objects = {}
self.objects.by_id = {} self.objects.by_id = {}
self.objects.by_class = {} self.objects.by_class = {}

View File

@ -191,7 +191,7 @@ function init()
['outlaw'] = function(dmg) return '[fg]throws a fan of [yellow]5[] knives, each dealing [yellow]' .. dmg .. '[fg] damage' end, ['outlaw'] = function(dmg) return '[fg]throws a fan of [yellow]5[] knives, each dealing [yellow]' .. dmg .. '[fg] damage' end,
['blade'] = function(dmg) return '[fg]throws multiple blades that deal [yellow]' .. dmg .. ' AoE[fg] damage' end, ['blade'] = function(dmg) return '[fg]throws multiple blades that deal [yellow]' .. dmg .. ' AoE[fg] damage' end,
['elementor'] = function(dmg) return '[fg]deals [yellow]' .. dmg .. ' AoE[fg] damage to a random target' end, ['elementor'] = function(dmg) return '[fg]deals [yellow]' .. dmg .. ' AoE[fg] damage to a random target' end,
['saboteur'] = function(dmg) return '[fg]calls [yellow]4[] saboteus to seek targets and deal [yellow]' .. dmg .. ' AoE[fg] damage' end, ['saboteur'] = function(dmg) return '[fg]calls [yellow]2[] saboteurs to seek targets and deal [yellow]' .. dmg .. ' AoE[fg] damage' end,
['stormweaver'] = function(dmg) return '[fg]infuses all allied projectiles with chain lightning that deals [yellow]+' .. dmg .. '[fg] damage on hit' end, ['stormweaver'] = function(dmg) return '[fg]infuses all allied projectiles with chain lightning that deals [yellow]+' .. dmg .. '[fg] damage on hit' end,
['sage'] = function(dmg) return '[fg]shoots a slow projectile that draws enemies in' end, ['sage'] = function(dmg) return '[fg]shoots a slow projectile that draws enemies in' end,
['squire'] = function(dmg) return '[yellow]+10 dmg[fg] & [yellow]+25 def[fg] to adjacent units, heal them for [yellow]10%[fg] max hp every 8 seconds' end, ['squire'] = function(dmg) return '[yellow]+10 dmg[fg] & [yellow]+25 def[fg] to adjacent units, heal them for [yellow]10%[fg] max hp every 8 seconds' end,
@ -373,13 +373,39 @@ function init()
[25] = {0, 55, 45}, [25] = {0, 55, 45},
} }
gold = 100 level_to_gold_gained = {
[1] = {1, 1},
[2] = {1, 2},
[3] = {2, 3},
[4] = {2, 3},
[5] = {3, 5},
[6] = {3, 5},
[7] = {4, 7},
[8] = {4, 7},
[9] = {5, 8},
[10] = {5, 8},
[11] = {5, 8},
[12] = {6, 10},
[13] = {6, 10},
[14] = {6, 10},
[15] = {7, 11},
[16] = {8, 12},
[17] = {8, 12},
[18] = {8, 12},
[19] = {8, 12},
[20] = {10, 14},
[21] = {10, 14},
[22] = {11, 15},
[23] = {11, 15},
[24] = {12, 18},
[25] = {12, 18},
}
gold = 2
main = Main() main = Main()
main:add(BuyScreen'buy_screen') main:add(BuyScreen'buy_screen')
main:go_to('buy_screen', 1, { main:go_to('buy_screen', 0, {})
{character = 'vagrant', level = 1, reserve = {0, 0}}, {character = 'swordsman', level = 1, reserve = {0, 0}},
})
end end

View File

@ -204,9 +204,9 @@ function Unit:calculate_stats(first_run)
elseif self:is(Seeker) then elseif self:is(Seeker) then
local x = self.level local x = self.level
local y = {0, 1, 4, 2, 3, 6, 3, 4, 8, 4, 5, 10, 5, 6, 12, 7, 8, 15, 9, 10, 18, 14, 15, 24, 25} local y = {0, 1, 4, 2, 3, 6, 3, 4, 8, 4, 5, 10, 5, 6, 12, 7, 8, 15, 9, 10, 18, 14, 15, 24, 25}
self.base_hp = 50 + 20*y[x] self.base_hp = 50 + 40*y[x]
self.base_dmg = 10 + 3*y[x] self.base_dmg = 10 + 20*y[x]
self.base_mvspd = 70 + 2*y[x] self.base_mvspd = 70 + 7*y[x]
elseif self:is(Saboteur) then elseif self:is(Saboteur) then
self.base_hp = 100*math.pow(2, self.level-1) self.base_hp = 100*math.pow(2, self.level-1)
self.base_dmg = 10*math.pow(2, self.level-1) self.base_dmg = 10*math.pow(2, self.level-1)

View File

@ -142,7 +142,7 @@ function Player:init(args)
SpawnEffect{group = main.current.effects, x = self.x, y = self.y, action = function(x, y) SpawnEffect{group = main.current.effects, x = self.x, y = self.y, action = function(x, y)
Saboteur{group = main.current.main, x = x, y = y, parent = self, conjurer_buff_m = self.conjurer_buff_m or 1} Saboteur{group = main.current.main, x = x, y = y, parent = self, conjurer_buff_m = self.conjurer_buff_m or 1}
end} end}
end, 4) end, 2)
end) end)
elseif self.character == 'stormweaver' then elseif self.character == 'stormweaver' then
@ -300,7 +300,6 @@ function Player:init(args)
end) end)
end end
print(self.character)
self:calculate_stats(true) self:calculate_stats(true)
if self.leader then if self.leader then
@ -500,11 +499,13 @@ function Player:hit(damage)
if self.dead then return end if self.dead then return end
self.hfx:use('hit', 0.25, 200, 10) self.hfx:use('hit', 0.25, 200, 10)
self:show_hp() self:show_hp()
local actual_damage = self:calculate_damage(damage) local actual_damage = self:calculate_damage(damage)
self.hp = self.hp - actual_damage self.hp = self.hp - actual_damage
_G[random:table{'player_hit1', 'player_hit2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5} _G[random:table{'player_hit1', 'player_hit2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
camera:shake(4, 0.5) camera:shake(4, 0.5)
main.current.damage_taken = main.current.damage_taken + actual_damage
if self.character == 'psykeeper' then self.psykeeper_heal = self.psykeeper_heal + actual_damage end if self.character == 'psykeeper' then self.psykeeper_heal = self.psykeeper_heal + actual_damage end
@ -513,6 +514,12 @@ function Player:hit(damage)
self.dead = true self.dead = true
for i = 1, random:int(4, 6) do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = self.color} end for i = 1, random:int(4, 6) do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = self.color} end
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 12}:scale_down(0.3):change_color(0.5, self.color) HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 12}:scale_down(0.3):change_color(0.5, self.color)
if self.leader and #self.followers == 0 then
main.current:die()
else
if self.leader then self:recalculate_followers()
else self.parent:recalculate_followers() end
end
end end
end end
@ -545,6 +552,35 @@ function Player:chronomancer_buff(duration)
end end
function Player:recalculate_followers()
if self.dead then
local new_leader = table.remove(self.followers, 1)
new_leader.leader = true
new_leader.previous_positions = {}
new_leader.followers = self.followers
new_leader.t:every(0.01, function()
table.insert(new_leader.previous_positions, 1, {x = new_leader.x, y = new_leader.y, r = new_leader.r})
if #new_leader.previous_positions > 256 then new_leader.previous_positions[257] = nil end
end)
main.current.player = new_leader
for i, follower in ipairs(self.followers) do
follower.parent = new_leader
follower.follower_index = i
end
else
for i = #self.followers, 1, -1 do
if self.followers[i].dead then
table.remove(self.followers, i)
break
end
end
for i, follower in ipairs(self.followers) do
follower.follower_index = i
end
end
end
function Player:add_follower(unit) function Player:add_follower(unit)
table.insert(self.followers, unit) table.insert(self.followers, unit)
unit.parent = self unit.parent = self
@ -990,7 +1026,7 @@ function Pet:init(args)
self:set_as_rectangle(8, 8, 'dynamic', 'projectile') self:set_as_rectangle(8, 8, 'dynamic', 'projectile')
self:set_restitution(0.5) self:set_restitution(0.5)
self.hfx:add('hit', 1) self.hfx:add('hit', 1)
self.color = orange[0] self.color = character_colors.hunter
self.pierce = 6 self.pierce = 6
pet1:play{pitch = random:float(0.95, 1.05), volume = 0.35} pet1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
end end