Day 27
parent
bb737a618e
commit
4ddee5119c
11
arena.lua
11
arena.lua
|
@ -73,7 +73,7 @@ function Arena:on_enter(from, level, units)
|
||||||
3, 3, 3, random:int(3, 4),
|
3, 3, 3, random:int(3, 4),
|
||||||
4, 4, 4, 4, random:int(4, 5),
|
4, 4, 4, 4, random:int(4, 5),
|
||||||
5, 5, 5, 5, 5, random:int(5, 6),
|
5, 5, 5, 5, 5, random:int(5, 6),
|
||||||
6, 7, 8, 9, 9, 10
|
6, 7, 8, 9, 9, 10, 12
|
||||||
}
|
}
|
||||||
self.max_waves = self.level_to_max_waves[self.level]
|
self.max_waves = self.level_to_max_waves[self.level]
|
||||||
self.wave = 0
|
self.wave = 0
|
||||||
|
@ -108,7 +108,7 @@ function Arena:on_enter(from, level, units)
|
||||||
16, 16, 18, random:int(18, 20),
|
16, 16, 18, random:int(18, 20),
|
||||||
20, 20, 20, 20, random:int(20, 22),
|
20, 20, 20, 20, random:int(20, 22),
|
||||||
22, 22, 22, 22, 22, random:int(22, 24),
|
22, 22, 22, 22, 22, random:int(22, 24),
|
||||||
24, 26, 28, 30, 30, 32
|
24, 26, 28, 30, 30, 32, 40
|
||||||
}
|
}
|
||||||
self.enemies_killed = 0
|
self.enemies_killed = 0
|
||||||
self.enemies_to_kill = self.level_to_enemies_to_kill[self.level]
|
self.enemies_to_kill = self.level_to_enemies_to_kill[self.level]
|
||||||
|
@ -139,7 +139,7 @@ function Arena:on_enter(from, level, units)
|
||||||
25, 25, 25, random:int(25, 30),
|
25, 25, 25, random:int(25, 30),
|
||||||
30, 30, 30, 30, random:int(30, 35),
|
30, 30, 30, 30, random:int(30, 35),
|
||||||
35, 35, 35, 35, 35, random:int(35, 40),
|
35, 35, 35, 35, 35, random:int(35, 40),
|
||||||
40, 45, 50, 55, 55, 60
|
40, 45, 50, 55, 55, 60, 80
|
||||||
}
|
}
|
||||||
self.time_left = self.level_to_time_left[self.level]
|
self.time_left = self.level_to_time_left[self.level]
|
||||||
self.start_time = 3
|
self.start_time = 3
|
||||||
|
@ -244,14 +244,14 @@ function Arena: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.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 and not self.transitioning 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])
|
local gold_gained = random:int(level_to_gold_gained[self.level][1], level_to_gold_gained[self.level][2])
|
||||||
|
print(gold_gained)
|
||||||
gold = gold + gold_gained
|
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
|
|
||||||
ui_transition2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
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)
|
TransitionEffect{group = main.transitions, x = self.player.x, y = self.player.y, color = self.color, transition_action = function(t)
|
||||||
main:add(BuyScreen'buy_screen')
|
main:add(BuyScreen'buy_screen')
|
||||||
|
@ -349,6 +349,7 @@ function Arena:die()
|
||||||
self.death_info_text = Text2{group = self.ui, x = gw/2, y = gh/2 + 16, sx = 0.7, sy = 0.7, lines = {
|
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]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'},
|
{text = '[wavy_mid, light_bg]r - start new run', font = fat_font, alignment = 'center'},
|
||||||
|
{text = '[wavy_mid, light_bg]w - wishlist on steam', font = fat_font, alignment = 'center'},
|
||||||
}}
|
}}
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
|
@ -47,13 +47,14 @@ function BuyScreen:on_enter(from, level, units)
|
||||||
self.party_text = Text({{text = '[wavy_mid, fg]party', font = pixul_font, alignment = 'center'}}, global_text_tags)
|
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]sets', font = pixul_font, alignment = 'center'}}, global_text_tags)
|
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.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 = {
|
self.under_text = Text2{group = self.main, x = 140, y = gh - 55, r = -math.pi/48, lines = {
|
||||||
{text = '[light_bg]under', font = fat_font, alignment = 'center'},
|
{text = '[light_bg]under', font = fat_font, alignment = 'center'},
|
||||||
{text = '[light_bg]construction', font = fat_font, alignment = 'center'},
|
{text = '[light_bg]construction', font = fat_font, alignment = 'center'},
|
||||||
}}
|
}}
|
||||||
|
|
||||||
if not self.first_screen then RerollButton{group = self.main, x = 150, y = 18, parent = self} end
|
if not self.first_screen then RerollButton{group = self.main, x = 150, y = 18, parent = self} end
|
||||||
GoButton{group = self.main, x = gw - 30, y = gh - 20, parent = self}
|
GoButton{group = self.main, x = gw - 30, y = gh - 20, parent = self}
|
||||||
|
WishlistButton{group = self.main, x = gw - 147, y = gh - 20, parent = self}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -175,6 +176,54 @@ end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WishlistButton = Object:extend()
|
||||||
|
WishlistButton:implement(GameObject)
|
||||||
|
function WishlistButton:init(args)
|
||||||
|
self:init_game_object(args)
|
||||||
|
self.shape = Rectangle(self.x, self.y, 110, 18)
|
||||||
|
self.interact_with_mouse = true
|
||||||
|
self.text = Text({{text = '[bg10]wishlist on steam', font = pixul_font, alignment = 'center'}}, global_text_tags)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function WishlistButton:update(dt)
|
||||||
|
self:update_game_object(dt)
|
||||||
|
|
||||||
|
if self.selected and input.m1.pressed then
|
||||||
|
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||||
|
self.spring:pull(0.2, 200, 10)
|
||||||
|
self.selected = true
|
||||||
|
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||||
|
system.open_url'https://store.steampowered.com/app/760330/BYTEPATH/'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function WishlistButton: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 bg[1])
|
||||||
|
self.text:draw(self.x, self.y + 1)
|
||||||
|
graphics.pop()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function WishlistButton: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 = '[fgm5]wishlist on steam', font = pixul_font, alignment = 'center'}}
|
||||||
|
self.spring:pull(0.2, 200, 10)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function WishlistButton:on_mouse_exit()
|
||||||
|
self.text:set_text{{text = '[bg10]wishlist on steam', font = pixul_font, alignment = 'center'}}
|
||||||
|
self.selected = false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GoButton = Object:extend()
|
GoButton = Object:extend()
|
||||||
GoButton:implement(GameObject)
|
GoButton:implement(GameObject)
|
||||||
function GoButton:init(args)
|
function GoButton:init(args)
|
||||||
|
|
12
devlog.md
12
devlog.md
|
@ -395,3 +395,15 @@ spawned by the level. He can also grant modifiers to enemies. Upon completing su
|
||||||
* Trapper: releases +1 trap
|
* Trapper: releases +1 trap
|
||||||
* Plague Doctor [trapper, nuker]: releases an area that deals 6 AoE DoT
|
* 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
|
* Fisherman [trapper, warrior]: throws a net that entangles enemies and prevents them from moving
|
||||||
|
|
||||||
|
# Day 27 - 15/03/21
|
||||||
|
|
||||||
|
Mostly done with balance tuning. Now all that's left are some final details:
|
||||||
|
|
||||||
|
* Pausing
|
||||||
|
* Muting sound/music
|
||||||
|
* Music + pitch
|
||||||
|
* Win screen
|
||||||
|
* W to wishlist
|
||||||
|
* R to restart
|
||||||
|
* Unit death sound
|
||||||
|
|
|
@ -152,3 +152,8 @@ end
|
||||||
function system.remove(path)
|
function system.remove(path)
|
||||||
os.remove(path)
|
os.remove(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function system.open_url(url)
|
||||||
|
love.system.openURL(url)
|
||||||
|
end
|
||||||
|
|
54
main.lua
54
main.lua
|
@ -346,36 +346,36 @@ function init()
|
||||||
}
|
}
|
||||||
|
|
||||||
level_to_tier_weights = {
|
level_to_tier_weights = {
|
||||||
[1] = {100, 0, 0},
|
[1] = {85, 10, 5},
|
||||||
[2] = {95, 5, 0},
|
[2] = {80, 15, 5},
|
||||||
[3] = {90, 10, 0},
|
[3] = {75, 20, 5},
|
||||||
[4] = {85, 15, 0},
|
[4] = {70, 20, 10},
|
||||||
[5] = {80, 20, 0},
|
[5] = {70, 20, 10},
|
||||||
[6] = {75, 25, 0},
|
[6] = {65, 25, 10},
|
||||||
[7] = {70, 30, 0},
|
[7] = {60, 25, 15},
|
||||||
[8] = {65, 35, 0},
|
[8] = {60, 25, 15},
|
||||||
[9] = {60, 40, 0},
|
[9] = {55, 30, 15},
|
||||||
[10] = {55, 45, 0},
|
[10] = {50, 30, 20},
|
||||||
[11] = {50, 50, 0},
|
[11] = {50, 30, 20},
|
||||||
[12] = {45, 50, 5},
|
[12] = {50, 30, 20},
|
||||||
[13] = {40, 50, 10},
|
[13] = {45, 30, 25},
|
||||||
[14] = {35, 50, 15},
|
[14] = {40, 35, 25},
|
||||||
[15] = {30, 50, 20},
|
[15] = {35, 40, 25},
|
||||||
[16] = {25, 50, 25},
|
[16] = {30, 40, 30},
|
||||||
[17] = {20, 55, 25},
|
[17] = {25, 45, 30},
|
||||||
[18] = {15, 60, 25},
|
[18] = {20, 50, 30},
|
||||||
[19] = {10, 65, 25},
|
[19] = {15, 50, 35},
|
||||||
[20] = {5, 70, 25},
|
[20] = {10, 55, 35},
|
||||||
[21] = {0, 75, 25},
|
[21] = {5, 60, 35},
|
||||||
[22] = {0, 70, 30},
|
[22] = {5, 55, 40},
|
||||||
[23] = {0, 65, 35},
|
[23] = {5, 55, 40},
|
||||||
[24] = {0, 60, 40},
|
[24] = {0, 55, 45},
|
||||||
[25] = {0, 55, 45},
|
[25] = {0, 50, 50},
|
||||||
}
|
}
|
||||||
|
|
||||||
level_to_gold_gained = {
|
level_to_gold_gained = {
|
||||||
[1] = {1, 1},
|
[1] = {2, 2},
|
||||||
[2] = {1, 2},
|
[2] = {2, 2},
|
||||||
[3] = {2, 3},
|
[3] = {2, 3},
|
||||||
[4] = {2, 3},
|
[4] = {2, 3},
|
||||||
[5] = {3, 5},
|
[5] = {3, 5},
|
||||||
|
|
|
@ -203,10 +203,10 @@ function Unit:calculate_stats(first_run)
|
||||||
self.base_mvspd = 75
|
self.base_mvspd = 75
|
||||||
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, 5, 9, 4, 6, 11, 7, 9, 15, 8, 10, 18, 9, 11, 21, 14, 15, 24, 25}
|
||||||
self.base_hp = 50 + 40*y[x]
|
self.base_hp = 50 + 60*y[x]
|
||||||
self.base_dmg = 10 + 20*y[x]
|
self.base_dmg = 10 + 40*y[x]
|
||||||
self.base_mvspd = 70 + 7*y[x]
|
self.base_mvspd = 70 + 10*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)
|
||||||
|
|
|
@ -124,7 +124,7 @@ function Player:init(args)
|
||||||
self.classes = character_classes.elementor
|
self.classes = character_classes.elementor
|
||||||
|
|
||||||
self.attack_sensor = Circle(self.x, self.y, 128)
|
self.attack_sensor = Circle(self.x, self.y, 128)
|
||||||
self.t:cooldown(12, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
self.t:cooldown(7, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||||
local enemy = self:get_random_object_in_shape(self.attack_sensor, main.current.enemies)
|
local enemy = self:get_random_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||||
if enemy then
|
if enemy then
|
||||||
self:attack(128, {x = enemy.x, y = enemy.y})
|
self:attack(128, {x = enemy.x, y = enemy.y})
|
||||||
|
@ -911,7 +911,11 @@ function Area:init(args)
|
||||||
self.shape = Rectangle(self.x, self.y, 1.5*self.w, 1.5*self.w, self.r)
|
self.shape = Rectangle(self.x, self.y, 1.5*self.w, 1.5*self.w, self.r)
|
||||||
local enemies = main.current.main:get_objects_in_shape(self.shape, main.current.enemies)
|
local enemies = main.current.main:get_objects_in_shape(self.shape, main.current.enemies)
|
||||||
for _, enemy in ipairs(enemies) do
|
for _, enemy in ipairs(enemies) do
|
||||||
|
if self.character == 'elementor' then
|
||||||
|
enemy:hit(2*self.dmg)
|
||||||
|
else
|
||||||
enemy:hit(self.dmg)
|
enemy:hit(self.dmg)
|
||||||
|
end
|
||||||
HitCircle{group = main.current.effects, x = enemy.x, y = enemy.y, rs = 6, color = fg[0], duration = 0.1}
|
HitCircle{group = main.current.effects, x = enemy.x, y = enemy.y, rs = 6, color = fg[0], duration = 0.1}
|
||||||
for i = 1, 2 do HitParticle{group = main.current.effects, x = enemy.x, y = enemy.y, color = self.color} end
|
for i = 1, 2 do HitParticle{group = main.current.effects, x = enemy.x, y = enemy.y, color = self.color} end
|
||||||
for i = 1, 2 do HitParticle{group = main.current.effects, x = enemy.x, y = enemy.y, color = enemy.color} end
|
for i = 1, 2 do HitParticle{group = main.current.effects, x = enemy.x, y = enemy.y, color = enemy.color} end
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- POST DEMO --
|
||||||
|
|
||||||
|
Mini Boss every 3rd level
|
||||||
|
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
|
||||||
|
|
||||||
|
Classes and characters
|
||||||
|
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
|
||||||
|
|
||||||
|
Enemy modifiers
|
||||||
|
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
|
||||||
|
|
Loading…
Reference in New Issue