Day 19
parent
36241e694b
commit
edbcdba3dc
100
arena.lua
100
arena.lua
|
@ -12,6 +12,7 @@ function Arena:on_enter(from, level, units)
|
|||
self.hfx:add('condition2', 1)
|
||||
self.level = level or 1
|
||||
|
||||
self.floor = Group()
|
||||
self.main = Group():set_as_physics_world(32, 0, 0, {'player', 'enemy', 'projectile', 'enemy_projectile'})
|
||||
self.post_main = Group()
|
||||
self.effects = Group()
|
||||
|
@ -72,6 +73,7 @@ function Arena:on_enter(from, level, units)
|
|||
6, 7, 8, 9, 9, 10
|
||||
}
|
||||
self.max_waves = self.level_to_max_waves[self.level]
|
||||
self.wave = 0
|
||||
self.start_time = 3
|
||||
self.t:after(1, function()
|
||||
self.t:every(1, function()
|
||||
|
@ -82,9 +84,9 @@ function Arena:on_enter(from, level, units)
|
|||
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.wave = 0
|
||||
self.t:every(function() return #self.main:get_objects_by_classes(self.enemies) <= 0 end, function()
|
||||
self.wave = self.wave + 1
|
||||
if self.wave > self.max_waves then return end
|
||||
self.hfx:use('condition1', 0.25, 200, 10)
|
||||
self.hfx:pull('condition2', 0.0625)
|
||||
self.t:after(0.5, function()
|
||||
|
@ -92,8 +94,9 @@ function Arena:on_enter(from, level, units)
|
|||
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}}
|
||||
self:spawn_n_enemies(spawn_points[spawn_type], nil, 8 + (self.wave-1)*2)
|
||||
end)
|
||||
end, self.max_waves, function() self.can_quit = true 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 == 'enemy_kill' then
|
||||
|
@ -119,12 +122,13 @@ function Arena:on_enter(from, level, units)
|
|||
SpawnEffect{group = self.effects, x = gw/2, y = gh/2 - 48}
|
||||
self:spawn_distributed_enemies()
|
||||
self.t:every(2, function()
|
||||
if love.timer.getTime() - self.last_spawn_enemy_time >= self.enemy_spawn_delay then
|
||||
if love.timer.getTime() - self.last_spawn_enemy_time >= self.enemy_spawn_delay and #self.main:get_objects_by_class(self.enemies) < self.enemies_to_kill and not self.transitioning then
|
||||
self:spawn_distributed_enemies()
|
||||
end
|
||||
end, nil, nil, 'spawn_enemies')
|
||||
end)
|
||||
end)
|
||||
self.t:every(function() return #self.main:get_objects_by_classes(self.enemies) <= 0 and self.enemies_killed >= self.enemies_to_kill end, function() self.can_quit = true end)
|
||||
|
||||
elseif self.win_condition == 'time' then
|
||||
self.level_to_time_left = {
|
||||
|
@ -149,15 +153,27 @@ function Arena:on_enter(from, level, units)
|
|||
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, function() self.can_quit = true end)
|
||||
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 then
|
||||
if #self.main:get_objects_by_classes(self.enemies) <= 0 or love.timer.getTime() - self.last_spawn_enemy_time >= 8 and not self.transitioning 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 end, function() self.can_quit = true end)
|
||||
end
|
||||
|
||||
if self.level == 1 then
|
||||
local t1 = Text2{group = self.floor, x = gw/2, y = gh/2 + 12, sx = 0.6, sy = 0.6, lines = {{text = '[light_bg]<- or a -> or d', font = fat_font, alignment = 'center'}}}
|
||||
local t2 = Text2{group = self.floor, x = gw/2, y = gh/2 + 28, lines = {{text = '[light_bg]turn left turn right', font = pixul_font, alignment = 'center'}}}
|
||||
local t3 = Text2{group = self.floor, x = gw/2, y = gh/2 + 56, sx = 0.6, sy = 0.6, lines = {{text = '[light_bg]n - mute sfx', font = fat_font, alignment = 'center'}}}
|
||||
local t4 = Text2{group = self.floor, x = gw/2, y = gh/2 + 78, sx = 0.6, sy = 0.6, lines = {{text = '[light_bg]m - mute music', font = fat_font, alignment = 'center'}}}
|
||||
t1.t:after(8, function() t1.t:tween(0.2, t1, {sy = 0}, math.linear, function() t1.sy = 0 end) end)
|
||||
t2.t:after(8, function() t2.t:tween(0.2, t2, {sy = 0}, math.linear, function() t2.sy = 0 end) end)
|
||||
t3.t:after(8, function() t3.t:tween(0.2, t3, {sy = 0}, math.linear, function() t3.sy = 0 end) end)
|
||||
t4.t:after(8, function() t4.t:tween(0.2, t4, {sy = 0}, math.linear, function() t4.sy = 0 end) end)
|
||||
end
|
||||
|
||||
-- Calculate class levels
|
||||
|
@ -219,48 +235,58 @@ function Arena:update(dt)
|
|||
if self.enchanter_level == 1 then self.enchanter_dmg_m = 1.25
|
||||
else self.enchanter_dmg_m = 1 end
|
||||
|
||||
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.ui:update(dt*slow_amount)
|
||||
|
||||
if self.win_condition == 'enemy_kill' then
|
||||
if self.can_quit then
|
||||
self.t:after(2, function()
|
||||
TransitionEffect{group = main.transitions, x = self.player.x, y = self.player.y, color = self.color, transition_action = function()
|
||||
main:add(BuyScreen'buy_screen')
|
||||
main:go_to('buy_screen', self, self.level, self.color)
|
||||
end, text = Text({
|
||||
{text = '[bg]resources gained: ' .. tostring(self.resources_gained), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||
{text = '[bg]interest: ' .. tostring(math.floor(resource/10)), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||
{text = '[bg]total: ' .. tostring(self.resources_gained + math.floor(resource/10)), font = pixul_font, alignment = 'center'}
|
||||
}, global_text_tags)}
|
||||
end)
|
||||
end
|
||||
|
||||
else
|
||||
if self.can_quit and #self.main:get_objects_by_classes(self.enemies) <= 0 then
|
||||
self.can_quit = false
|
||||
self.t:after(2, function()
|
||||
if #self.main:get_objects_by_classes(self.enemies) > 0 then
|
||||
self.can_quit = true
|
||||
else
|
||||
TransitionEffect{group = main.transitions, x = self.player.x, y = self.player.y, color = self.color, transition_action = function()
|
||||
main:add(BuyScreen'buy_screen')
|
||||
main:go_to('buy_screen', self, self.level, self.color)
|
||||
end, text = Text({
|
||||
{text = '[bg]resources gained: ' .. tostring(self.resources_gained), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||
{text = '[bg]interest: ' .. tostring(math.floor(resource/10)), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||
{text = '[bg]total: ' .. tostring(self.resources_gained + math.floor(resource/10)), font = pixul_font, alignment = 'center'}
|
||||
}, global_text_tags)}
|
||||
end
|
||||
end)
|
||||
end
|
||||
if self.can_quit and #self.main:get_objects_by_classes(self.enemies) <= 0 then
|
||||
self.can_quit = false
|
||||
self.transitioning = true
|
||||
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.transitioning = false
|
||||
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')
|
||||
main:go_to('buy_screen', self, self.level, self.color)
|
||||
t.t:after(0.1, function()
|
||||
t.text:set_text({
|
||||
{text = '[nudge_down, bg]resources gained: ' .. tostring(self.resources_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]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]resources gained: ' .. tostring(self.resources_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 = '[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]resources gained: ' .. tostring(self.resources_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 = '[nudge_down, bg]total: ' .. tostring(self.resources_gained + math.floor(resource/10)), font = pixul_font, alignment = 'center'}
|
||||
})
|
||||
_G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end, text = Text({
|
||||
{text = '[wavy_lower, bg]resources 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]total: 0', font = pixul_font, alignment = 'center'}
|
||||
}, global_text_tags)}
|
||||
end, 'transition')
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Arena:draw()
|
||||
self.floor:draw()
|
||||
self.main:draw()
|
||||
self.post_main:draw()
|
||||
self.effects:draw()
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -25,7 +25,7 @@ function BuyScreen:on_enter(from, level)
|
|||
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 = '[fg]choose your initial party', font = pixul_font, alignment = 'center'}}, global_text_tags)
|
||||
self.title = Text({{text = '[wavy_mid, fg]choose your initial party', font = pixul_font, alignment = 'center'}}, global_text_tags)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -43,6 +43,8 @@ function BuyScreen:update(dt)
|
|||
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
|
||||
|
@ -50,11 +52,13 @@ function BuyScreen:update(dt)
|
|||
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_switch:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
ui_transition:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
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)
|
||||
|
||||
|
|
|
@ -336,3 +336,8 @@ I wonder if I should try implementing this now or leave it for the next game.
|
|||
|
||||
Transition from first screen to first level works. Polish it up tomorrow with more sounds, tutorial markers (left/right arrows) and more consistency and anticipation when a level ends, and then start work on the main buy
|
||||
screen.
|
||||
|
||||
# Day 19 - 07/03/21
|
||||
|
||||
First screen, transition from it to arena, arena and transition from arena to next screen are 99% complete and polished. There's one small bug left that I can't replicate where it will end the level right away, but I can't tell
|
||||
with which win condition it's happening... I'll fix it in time. Tomorrow I can get started on the main buy screen for real.
|
||||
|
|
|
@ -51,7 +51,7 @@ text = Text({
|
|||
-- If 'alignment_width' is set to a specific line then that line will be automatically set to that width, and if it is the biggest then .w will also be set to that value.
|
||||
Text = Object:extend()
|
||||
function Text:init(text_data, text_tags)
|
||||
self.trigger = Trigger()
|
||||
self.t = Trigger()
|
||||
self.text_data = text_data
|
||||
self.text_tags = text_tags
|
||||
self.white = Color(1, 1, 1, 1)
|
||||
|
@ -61,7 +61,7 @@ end
|
|||
|
||||
|
||||
function Text:update(dt)
|
||||
self.trigger:update(dt)
|
||||
self.t:update(dt)
|
||||
self:format_text()
|
||||
for _, line in ipairs(self.lines) do
|
||||
for i, c in ipairs(line.characters) do
|
||||
|
@ -116,8 +116,8 @@ function Text:format_text()
|
|||
for i, c in ipairs(line.characters) do
|
||||
c.x = x
|
||||
c.y = y
|
||||
c.sx = line.sx or 1
|
||||
c.sy = line.sy or 1
|
||||
c.sx = line.sx or c.sx or 1
|
||||
c.sy = line.sy or c.sy or 1
|
||||
x = x + line.font:get_text_width(c.character)
|
||||
end
|
||||
y = y + h
|
||||
|
|
38
main.lua
38
main.lua
|
@ -17,8 +17,13 @@ function init()
|
|||
input:bind('enter', {'space', 'return'})
|
||||
|
||||
local s = {tags = {sfx}}
|
||||
ui_switch = Sound('Switch.ogg', s)
|
||||
ui_transition = Sound('Wind Bolt 8.ogg', s)
|
||||
ui_switch1 = Sound('Switch.ogg', s)
|
||||
ui_switch2 = Sound('Switch 3.ogg', s)
|
||||
ui_transition1 = Sound('Wind Bolt 8.ogg', s)
|
||||
ui_transition2 = Sound('Wind Bolt 12.ogg', s)
|
||||
coins1 = Sound('Coins 7.ogg', s)
|
||||
coins2 = Sound('Coins 8.ogg', s)
|
||||
coins3 = Sound('Coins 9.ogg', s)
|
||||
shoot1 = Sound('Shooting Projectile (Classic) 11.ogg', s)
|
||||
archer1 = Sound('Releasing Bow String 1.ogg', s)
|
||||
wizard1 = Sound('Wind Bolt 20.ogg', s)
|
||||
|
@ -233,7 +238,34 @@ function init()
|
|||
['engineer'] = function(lvl) return get_character_stat_string('engineer', lvl) end,
|
||||
}
|
||||
|
||||
units = {}
|
||||
class_stat_multipliers = {
|
||||
['warrior'] = {hp = 1.4, dmg = 1.1, aspd = 0.9, area_dmg = 1, area_size = 1, def = 1.25, mvspd = 0.9},
|
||||
['ranger'] = {hp = 1, dmg = 1.2, aspd = 1.5, area_dmg = 1, area_size = 1, def = 0.9, mvspd = 1.2},
|
||||
['healer'] = {hp = 1.2, dmg = 1, aspd = 0.5, area_dmg = 1, area_size = 1, def = 1.2, mvspd = 1},
|
||||
['mage'] = {hp = 0.6, dmg = 1.4, aspd = 1, area_dmg = 1.25, area_size = 1.2, def = 0.75, mvspd = 1},
|
||||
['rogue'] = {hp = 0.8, dmg = 1.3, aspd = 1.1, area_dmg = 0.6, area_size = 0.6, def = 0.8, mvspd = 1.4},
|
||||
['nuker'] = {hp = 0.9, dmg = 1, aspd = 0.75, area_dmg = 1.5, area_size = 1.5, def = 1, mvspd = 1},
|
||||
['conjurer'] = {hp = 1, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 1},
|
||||
['enchanter'] = {hp = 1.2, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1.2, mvspd = 1.2},
|
||||
['psy'] = {hp = 1.5, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 0.5, mvspd = 1},
|
||||
['seeker'] = {hp = 0.5, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 0.3},
|
||||
['saboteur'] = {hp = 1, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 1.4},
|
||||
}
|
||||
|
||||
local ylb1 = function(lvl) return (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) .. ']2[' .. ylb2(lvl) .. ']/4 [fg]- [' .. ylb1(lvl) .. ']10%[' .. ylb2(lvl) .. ']/20% [fg]chance to release a barrage on attack' end,
|
||||
['warrior'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[' .. ylb2(lvl) .. ']/4 [fg]- [' .. ylb1(lvl) .. ']+25[' .. ylb2(lvl) .. ']/+50 [fg]defense to allied warriors' end,
|
||||
['mage'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[' .. ylb2(lvl) .. ']/4 [fg]- [' .. ylb1(lvl) .. ']-15[' .. ylb2(lvl) .. ']/-30 [fg]enemy defense' end,
|
||||
['nuker'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[' .. ylb2(lvl) .. ']/4 [fg]- [' .. ylb1(lvl) .. ']+15%[' .. ylb2(lvl) .. ']/+25% [fg]area damage and size' end,
|
||||
['rogue'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[' .. ylb2(lvl) .. ']/4 [fg]- [' .. ylb1(lvl) .. ']10%[' .. ylb2(lvl) .. ']/20% [fg]chance to crit, dealing [yellow]4x[] damage' end,
|
||||
['healer'] = function(lvl) return '[' .. ylb1(lvl) .. ']3 [fg]- [' .. ylb1(lvl) .. ']+25% [fg]healing effectiveness' end,
|
||||
['conjurer'] = function(lvl) return '[' .. ylb1(lvl) .. ']2 [fg]- [' .. ylb1(lvl) .. ']+25% [fg]construct damage and duration' end,
|
||||
['enchanter'] = function(lvl) return '[' .. ylb1(lvl) .. ']3 [fg]- [' .. ylb1(lvl) .. ']+25% [fg]damage to all allies' end,
|
||||
['psy'] = function(lvl) return 'damage taken by psy units is reflected to enemies at double its value' end,
|
||||
}
|
||||
|
||||
resource = 0
|
||||
|
||||
main = Main()
|
||||
|
|
58
objects.lua
58
objects.lua
|
@ -237,70 +237,26 @@ function Unit:calculate_stats(first_run)
|
|||
self.buff_mvspd_m = 1
|
||||
end
|
||||
|
||||
for _, class in ipairs(self.classes) do
|
||||
if class == 'warrior' then self.class_hp_m = self.class_hp_m*1.4
|
||||
elseif class == 'mage' then self.class_hp_m = self.class_hp_m*0.6
|
||||
elseif class == 'healer' then self.class_hp_m = self.class_hp_m*1.2
|
||||
elseif class == 'nuker' then self.class_hp_m = self.class_hp_m*0.9
|
||||
elseif class == 'rogue' then self.class_hp_m = self.class_hp_m*0.8
|
||||
elseif class == 'enchanter' then self.class_hp_m = self.class_hp_m*1.2
|
||||
elseif class == 'psy' then self.class_hp_m = self.class_hp_m*1.5
|
||||
elseif class == 'seeker' then self.class_hp_m = self.class_hp_m*0.5 end
|
||||
end
|
||||
for _, class in ipairs(self.classes) do self.class_hp_m = self.class_hp_m*class_stat_multipliers[class].hp end
|
||||
self.max_hp = (self.base_hp + self.class_hp_a + self.buff_hp_a)*self.class_hp_m*self.buff_hp_m
|
||||
if first_run then self.hp = self.max_hp end
|
||||
|
||||
for _, class in ipairs(self.classes) do
|
||||
if class == 'warrior' then self.class_dmg_m = self.class_dmg_m*1.1
|
||||
elseif class == 'ranger' then self.class_dmg_m = self.class_dmg_m*1.2
|
||||
elseif class == 'rogue' then self.class_dmg_m = self.class_dmg_m*1.3
|
||||
elseif class == 'mage' then self.class_dmg_m = self.class_dmg_m*1.4
|
||||
elseif class == 'ninja_clone' then self.class_dmg_m = self.class_dmg_m*1.5 end
|
||||
end
|
||||
for _, class in ipairs(self.classes) do self.class_dmg_m = self.class_dmg_m*class_stat_multipliers[class].dmg end
|
||||
self.dmg = (self.base_dmg + self.class_dmg_a + self.buff_dmg_a)*self.class_dmg_m*self.buff_dmg_m
|
||||
|
||||
for _, class in ipairs(self.classes) do
|
||||
if class == 'warrior' then self.class_aspd_m = self.class_aspd_m*0.9
|
||||
elseif class == 'ranger' then self.class_aspd_m = self.class_aspd_m*1.5
|
||||
elseif class == 'healer' then self.class_aspd_m = self.class_aspd_m*0.5
|
||||
elseif class == 'rogue' then self.class_aspd_m = self.class_aspd_m*1.1
|
||||
elseif class == 'nuker' then self.class_aspd_m = self.class_aspd_m*0.75 end
|
||||
end
|
||||
for _, class in ipairs(self.classes) do self.class_aspd_m = self.class_aspd_m*class_stat_multipliers[class].aspd end
|
||||
self.aspd_m = 1/(self.base_aspd_m*self.class_aspd_m*self.buff_aspd_m)
|
||||
|
||||
for _, class in ipairs(self.classes) do
|
||||
if class == 'mage' then self.class_area_dmg_m = self.class_area_dmg_m*1.25
|
||||
elseif class == 'nuker' then self.class_area_dmg_m = self.class_area_dmg_m*1.5
|
||||
elseif class == 'rogue' then self.class_area_dmg_m = self.class_area_dmg_m*0.6 end
|
||||
end
|
||||
for _, class in ipairs(self.classes) do self.class_area_dmg_m = self.class_area_dmg_m*class_stat_multipliers[class].area_dmg end
|
||||
self.area_dmg_m = self.base_area_dmg_m*self.class_area_dmg_m*self.buff_area_dmg_m
|
||||
|
||||
for _, class in ipairs(self.classes) do
|
||||
if class == 'mage' then self.class_area_size_m = self.class_area_size_m*1.2
|
||||
elseif class == 'nuker' then self.class_area_size_m = self.class_area_size_m*1.3
|
||||
elseif class == 'rogue' then self.class_area_size_m = self.class_area_size_m*0.6 end
|
||||
end
|
||||
for _, class in ipairs(self.classes) do self.class_area_size_m = self.class_area_size_m*class_stat_multipliers[class].area_size end
|
||||
self.area_size_m = self.base_area_size_m*self.class_area_size_m*self.buff_area_size_m
|
||||
|
||||
for _, class in ipairs(self.classes) do
|
||||
if class == 'warrior' then self.class_def_m = self.class_def_m*1.25
|
||||
elseif class == 'ranger' then self.class_def_m = self.class_def_m*0.9
|
||||
elseif class == 'mage' then self.class_def_m = self.class_def_m*0.75
|
||||
elseif class == 'rogue' then self.class_def_m = self.class_def_m*0.8
|
||||
elseif class == 'enchanter' then self.class_def_m = self.class_def_m*1.2
|
||||
elseif class == 'psy' then self.class_def_m = self.class_def_m*0.5
|
||||
elseif class == 'healer' then self.class_def_m = self.class_def_m*1.2 end
|
||||
end
|
||||
for _, class in ipairs(self.classes) do self.class_def_m = self.class_def_m*class_stat_multipliers[class].def end
|
||||
self.def = (self.base_def + self.class_def_a + self.buff_def_a)*self.class_def_m*self.buff_def_m
|
||||
|
||||
for _, class in ipairs(self.classes) do
|
||||
if class == 'warrior' then self.class_mvspd_m = self.class_mvspd_m*0.9
|
||||
elseif class == 'ranger' then self.class_mvspd_m = self.class_mvspd_m*1.2
|
||||
elseif class == 'rogue' then self.class_mvspd_m = self.class_mvspd_m*1.4
|
||||
elseif class == 'enchanter' then self.class_mvspd_m = self.class_mvspd_m*1.2
|
||||
elseif class == 'seeker' then self.class_mvspd_m = self.class_mvspd_m*0.3
|
||||
elseif class == 'saboteur' then self.class_mvspd_m = self.class_mvspd_m*1.4 end
|
||||
end
|
||||
for _, class in ipairs(self.classes) do self.class_mvspd_m = self.class_mvspd_m*class_stat_multipliers[class].mvspd end
|
||||
self.v = (self.base_mvspd + self.class_mvspd_a + self.buff_mvspd_a)*self.class_mvspd_m*self.buff_mvspd_m
|
||||
end
|
||||
|
||||
|
|
|
@ -484,7 +484,8 @@ function Player:on_collision_enter(other, contact)
|
|||
|
||||
elseif table.any(main.current.enemies, function(v) return other:is(v) end) then
|
||||
other:push(random:float(25, 35), self:angle_to_object(other))
|
||||
other:hit(20)
|
||||
if self.character == 'vagrant' or self.character == 'psykeeper' then other:hit(40)
|
||||
else other:hit(20) end
|
||||
self:hit(20)
|
||||
HitCircle{group = main.current.effects, x = x, y = y, rs = 6, color = fg[0], duration = 0.1}
|
||||
for i = 1, 2 do HitParticle{group = main.current.effects, x = x, y = y, color = self.color} end
|
||||
|
|
48
shared.lua
48
shared.lua
|
@ -1,3 +1,4 @@
|
|||
-- Shared functions and classes for projects using JUGGLRX's visual style.
|
||||
function shared_init()
|
||||
local colors = {
|
||||
white = ColorRamp(Color(1, 1, 1, 1), 0.025),
|
||||
|
@ -388,7 +389,7 @@ function TransitionEffect:init(args)
|
|||
self.t:tween(0.1, self, {text_sx = 1, text_sy = 1}, math.cubic_in_out)
|
||||
end)
|
||||
self.t:tween(0.6, self, {rs = 1.2*gw}, math.linear, function()
|
||||
if self.transition_action then self.transition_action(unpack(self.transition_action_args or {})) end
|
||||
if self.transition_action then self:transition_action(unpack(self.transition_action_args or {})) end
|
||||
self.t:after(0.3, function()
|
||||
self.x, self.y = gw/2, gh/2
|
||||
self.t:after(0.6, function() self.t:tween(0.05, self, {text_sx = 0, text_sy = 0}, math.cubic_in_out) end)
|
||||
|
@ -419,6 +420,7 @@ end
|
|||
|
||||
|
||||
|
||||
local invisible = Color(1, 1, 1, 0)
|
||||
global_text_tags = {
|
||||
red = TextTag{draw = function(c, i, text) graphics.set_color(red[0]) end},
|
||||
orange = TextTag{draw = function(c, i, text) graphics.set_color(orange[0]) end},
|
||||
|
@ -427,11 +429,53 @@ global_text_tags = {
|
|||
purple = TextTag{draw = function(c, i, text) graphics.set_color(purple[0]) end},
|
||||
blue = TextTag{draw = function(c, i, text) graphics.set_color(blue[0]) end},
|
||||
bg = TextTag{draw = function(c, i, text) graphics.set_color(bg[0]) end},
|
||||
light_bg = TextTag{draw = function(c, i, text) graphics.set_color(bg[5]) end},
|
||||
fg = TextTag{draw = function(c, i, text) graphics.set_color(fg[0]) end},
|
||||
wavy = TextTag{update = function(c, dt, i, text) c.oy = 2*math.sin(4*time + i) end},
|
||||
wavy_lower = TextTag{update = function(c, dt, i, text) c.oy = math.sin(4*time + i) end},
|
||||
wavy_mid = TextTag{update = function(c, dt, i, text) c.oy = 0.75*math.sin(3*time + i) end},
|
||||
wavy_lower = TextTag{update = function(c, dt, i, text) c.oy = 0.25*math.sin(2*time + i) end},
|
||||
|
||||
cbyc = TextTag{init = function(c, i, text)
|
||||
c.color = invisible
|
||||
text.t:after((i-1)*0.15, function()
|
||||
c.color = red[0]
|
||||
camera:shake(3, 0.075)
|
||||
pop1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
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)
|
||||
end},
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Text2 = Object:extend()
|
||||
Text2:implement(GameObject)
|
||||
function Text2:init(args)
|
||||
self:init_game_object(args)
|
||||
self.text = Text(args.lines, global_text_tags)
|
||||
end
|
||||
|
||||
|
||||
function Text2:update(dt)
|
||||
self:update_game_object(dt)
|
||||
self.text:update(dt)
|
||||
end
|
||||
|
||||
|
||||
function Text2:draw()
|
||||
self.text:draw(self.x, self.y, self.r, self.sx, self.sy)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
InfoText = Object:extend()
|
||||
InfoText:implement(GameObject)
|
||||
function InfoText:init(args)
|
||||
|
|
Loading…
Reference in New Issue