Sorcerer update 2/4
parent
cea71538b2
commit
f3997b08a7
|
@ -20,7 +20,7 @@ function Arena:on_enter(from, level, units, passives)
|
|||
steam.friends.setRichPresence('text', 'Arena - Level ' .. self.level)
|
||||
|
||||
self.floor = Group()
|
||||
self.main = Group():set_as_physics_world(32, 0, 0, {'player', 'enemy', 'projectile', 'enemy_projectile'})
|
||||
self.main = Group():set_as_physics_world(32, 0, 0, {'player', 'enemy', 'projectile', 'enemy_projectile', 'force_field'})
|
||||
self.post_main = Group()
|
||||
self.effects = Group()
|
||||
self.ui = Group()
|
||||
|
@ -33,6 +33,8 @@ function Arena:on_enter(from, level, units, passives)
|
|||
self.main:disable_collision_between('projectile', 'enemy')
|
||||
self.main:disable_collision_between('enemy_projectile', 'enemy')
|
||||
self.main:disable_collision_between('enemy_projectile', 'enemy_projectile')
|
||||
self.main:disable_collision_between('player', 'force_field')
|
||||
self.main:disable_collision_between('projectile', 'force_field')
|
||||
self.main:enable_trigger_between('projectile', 'enemy')
|
||||
self.main:enable_trigger_between('enemy_projectile', 'player')
|
||||
self.main:enable_trigger_between('player', 'enemy_projectile')
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1323,6 +1323,7 @@ function CharacterIcon:init(args)
|
|||
self:init_game_object(args)
|
||||
self.shape = Rectangle(self.x, self.y, 40, 20)
|
||||
self.interact_with_mouse = true
|
||||
print(character_color_strings[self.character])
|
||||
self.character_text = Text({{text = '[' .. character_color_strings[self.character] .. ']' .. string.lower(character_names[self.character]), font = pixul_font, alignment = 'center'}}, global_text_tags)
|
||||
end
|
||||
|
||||
|
@ -1394,12 +1395,12 @@ end
|
|||
|
||||
function TutorialClassIcon:draw()
|
||||
graphics.push(self.x, self.y, 0, self.sx*self.spring.x, self.sy*self.spring.x)
|
||||
local i, j, n = class_set_numbers[self.class](self.units)
|
||||
local i, j, k, n = class_set_numbers[self.class](self.units)
|
||||
|
||||
graphics.rectangle(self.x, self.y, 16, 24, 4, 4, self.highlighted and fg[0] or ((n >= i) and class_colors[self.class] or bg[3]))
|
||||
_G[self.class]:draw(self.x, self.y, 0, 0.3, 0.3, 0, 0, self.highlighted and fg[-5] or ((n >= i) and _G[class_color_strings[self.class]][-5] or bg[10]))
|
||||
graphics.rectangle(self.x, self.y + 26, 16, 16, 3, 3, self.highlighted and fg[0] or bg[3])
|
||||
if i == 2 then
|
||||
if i == 2 and not k then
|
||||
if self.highlighted then
|
||||
graphics.line(self.x - 3, self.y + 20, self.x - 3, self.y + 25, (n >= 1) and fg[-5] or fg[-10], 3)
|
||||
graphics.line(self.x - 3, self.y + 27, self.x - 3, self.y + 32, (n >= 2) and fg[-5] or fg[-10], 3)
|
||||
|
@ -1435,7 +1436,7 @@ end
|
|||
function TutorialClassIcon:on_mouse_enter()
|
||||
ui_hover1:play{pitch = random:float(1.3, 1.5), volume = 0.5}
|
||||
self.spring:pull(0.2, 200, 10)
|
||||
local i, j, owned = class_set_numbers[self.class](self.units)
|
||||
local i, j, k, owned = class_set_numbers[self.class](self.units)
|
||||
self.info_text = InfoText{group = main.current.tutorial}
|
||||
self.info_text:activate({
|
||||
{text = '[' .. class_color_strings[self.class] .. ']' .. self.class:capitalize() .. '[fg] - owned: [yellow]' .. owned, font = pixul_font, alignment = 'center', height_multiplier = 1.25},
|
||||
|
@ -1474,7 +1475,7 @@ end
|
|||
|
||||
function ClassIcon:draw()
|
||||
graphics.push(self.x, self.y, 0, self.sx*self.spring.x, self.sy*self.spring.x)
|
||||
local i, j, n = class_set_numbers[self.class](self.units)
|
||||
local i, j, k, n = class_set_numbers[self.class](self.units)
|
||||
local next_n
|
||||
if self.parent:is(ShopCard) then
|
||||
next_n = n+1
|
||||
|
@ -1485,7 +1486,7 @@ function ClassIcon:draw()
|
|||
graphics.rectangle(self.x, self.y, 16, 24, 4, 4, self.highlighted and fg[0] or ((n >= i) and class_colors[self.class] or bg[3]))
|
||||
_G[self.class]:draw(self.x, self.y, 0, 0.3, 0.3, 0, 0, self.highlighted and fg[-5] or ((n >= i) and _G[class_color_strings[self.class]][-5] or bg[10]))
|
||||
graphics.rectangle(self.x, self.y + 26, 16, 16, 3, 3, self.highlighted and fg[0] or bg[3])
|
||||
if i == 2 then
|
||||
if i == 2 and not k then
|
||||
if self.highlighted then
|
||||
graphics.line(self.x - 3, self.y + 20, self.x - 3, self.y + 25, (n >= 1) and fg[-5] or fg[-10], 3)
|
||||
graphics.line(self.x - 3, self.y + 27, self.x - 3, self.y + 32, (n >= 2) and fg[-5] or fg[-10], 3)
|
||||
|
@ -1508,6 +1509,38 @@ function ClassIcon:draw()
|
|||
graphics.line(self.x + 4, self.y + 27, self.x + 4, self.y + 32, self.flash and class_colors[self.class] or bg[10], 3)
|
||||
end
|
||||
end
|
||||
elseif i == 2 and k == 6 then
|
||||
if self.highlighted then
|
||||
graphics.line(self.x - 5, self.y + 21, self.x - 5, self.y + 24, (n >= 1) and fg[-5] or fg[-10], 3)
|
||||
graphics.line(self.x - 5, self.y + 28, self.x - 5, self.y + 31, (n >= 2) and fg[-5] or fg[-10], 3)
|
||||
graphics.line(self.x + 0, self.y + 21, self.x + 0, self.y + 24, (n >= 3) and fg[-5] or fg[-10], 3)
|
||||
graphics.line(self.x + 0, self.y + 28, self.x + 0, self.y + 31, (n >= 4) and fg[-5] or fg[-10], 3)
|
||||
graphics.line(self.x + 5, self.y + 21, self.x + 5, self.y + 24, (n >= 5) and fg[-5] or fg[-10], 3)
|
||||
graphics.line(self.x + 5, self.y + 28, self.x + 5, self.y + 31, (n >= 6) and fg[-5] or fg[-10], 3)
|
||||
else
|
||||
graphics.line(self.x - 5, self.y + 21, self.x - 5, self.y + 24, (n >= 1) and class_colors[self.class] or bg[10], 3)
|
||||
graphics.line(self.x - 5, self.y + 28, self.x - 5, self.y + 31, (n >= 2) and class_colors[self.class] or bg[10], 3)
|
||||
graphics.line(self.x + 0, self.y + 21, self.x + 0, self.y + 24, (n >= 3) and class_colors[self.class] or bg[10], 3)
|
||||
graphics.line(self.x + 0, self.y + 28, self.x + 0, self.y + 31, (n >= 4) and class_colors[self.class] or bg[10], 3)
|
||||
graphics.line(self.x + 5, self.y + 21, self.x + 5, self.y + 24, (n >= 5) and class_colors[self.class] or bg[10], 3)
|
||||
graphics.line(self.x + 5, self.y + 28, self.x + 5, self.y + 31, (n >= 6) and class_colors[self.class] or bg[10], 3)
|
||||
end
|
||||
if next_n then
|
||||
if next_n == 1 then
|
||||
graphics.line(self.x - 5, self.y + 21, self.x - 5, self.y + 24, self.flash and class_colors[self.class] or bg[10], 3)
|
||||
elseif next_n == 2 then
|
||||
graphics.line(self.x - 5, self.y + 28, self.x - 5, self.y + 31, self.flash and class_colors[self.class] or bg[10], 3)
|
||||
elseif next_n == 3 then
|
||||
graphics.line(self.x + 0, self.y + 21, self.x + 0, self.y + 24, self.flash and class_colors[self.class] or bg[10], 3)
|
||||
elseif next_n == 4 then
|
||||
graphics.line(self.x + 0, self.y + 28, self.x + 0, self.y + 31, self.flash and class_colors[self.class] or bg[10], 3)
|
||||
elseif next_n == 5 then
|
||||
graphics.line(self.x + 5, self.y + 21, self.x + 5, self.y + 24, self.flash and class_colors[self.class] or bg[10], 3)
|
||||
elseif next_n == 6 then
|
||||
graphics.line(self.x + 5, self.y + 28, self.x + 5, self.y + 31, self.flash and class_colors[self.class] or bg[10], 3)
|
||||
end
|
||||
end
|
||||
|
||||
elseif i == 3 then
|
||||
if self.highlighted then
|
||||
graphics.line(self.x - 3, self.y + 19, self.x - 3, self.y + 22, (n >= 1) and fg[-5] or fg[-10], 3)
|
||||
|
@ -1547,11 +1580,11 @@ end
|
|||
function ClassIcon:on_mouse_enter()
|
||||
ui_hover1:play{pitch = random:float(1.3, 1.5), volume = 0.5}
|
||||
self.spring:pull(0.2, 200, 10)
|
||||
local i, j, owned = class_set_numbers[self.class](self.units)
|
||||
local i, j, k, owned = class_set_numbers[self.class](self.units)
|
||||
self.info_text = InfoText{group = main.current.ui}
|
||||
self.info_text:activate({
|
||||
{text = '[' .. class_color_strings[self.class] .. ']' .. self.class:capitalize() .. '[fg] - owned: [yellow]' .. owned, font = pixul_font, alignment = 'center', height_multiplier = 1.25},
|
||||
{text = class_descriptions[self.class]((owned >= j and 2) or (owned >= i and 1) or 0), font = pixul_font, alignment = 'center'},
|
||||
{text = class_descriptions[self.class]((k and (owned >= k and 3)) or (owned >= j and 2) or (owned >= i and 1) or 0), 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
|
||||
|
||||
|
@ -1584,7 +1617,7 @@ end
|
|||
|
||||
function ClassIcon:die(dont_spawn_effect)
|
||||
self.dead = true
|
||||
local i, j, n = class_set_numbers[self.class](self.units)
|
||||
local i, j, k, n = class_set_numbers[self.class](self.units)
|
||||
if not dont_spawn_effect then SpawnEffect{group = main.current.effects, x = self.x, y = self.y + 4, color = (n >= i) and class_colors[self.class] or bg[3]} end
|
||||
if self.info_text then
|
||||
self.info_text:deactivate()
|
||||
|
|
16
enemies.lua
16
enemies.lua
|
@ -16,6 +16,7 @@ function Seeker:init(args)
|
|||
if self.boss == 'speed_booster' then
|
||||
self.color = green[0]:clone()
|
||||
self.t:every(8, function()
|
||||
if self.silenced then return end
|
||||
local enemies = table.head(self:get_objects_in_shape(Circle(self.x, self.y, 128), main.current.enemies), 4)
|
||||
if #enemies > 0 then
|
||||
buff1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
|
@ -30,6 +31,7 @@ function Seeker:init(args)
|
|||
elseif self.boss == 'forcer' then
|
||||
self.color = yellow[0]:clone()
|
||||
self.t:every(6, function()
|
||||
if self.silenced then return end
|
||||
local enemies = main.current.main:get_objects_by_classes(main.current.enemies)
|
||||
local x, y = 0, 0
|
||||
if #enemies > 0 then
|
||||
|
@ -74,6 +76,7 @@ function Seeker:init(args)
|
|||
elseif self.boss == 'swarmer' then
|
||||
self.color = purple[0]:clone()
|
||||
self.t:every(4, function()
|
||||
if self.silenced then return end
|
||||
local enemies = table.select(main.current.main:get_objects_by_classes(main.current.enemies), function(v) return v.id ~= self.id and v:is(Seeker) end)
|
||||
local enemy = random:table(enemies)
|
||||
if enemy then
|
||||
|
@ -89,6 +92,7 @@ function Seeker:init(args)
|
|||
elseif self.boss == 'exploder' then
|
||||
self.color = blue[0]:clone()
|
||||
self.t:every(4, function()
|
||||
if self.silenced then return end
|
||||
local enemies = table.select(main.current.main:get_objects_by_classes(main.current.enemies), function(v) return v.id ~= self.id and v:is(Seeker) end)
|
||||
local enemy = random:table(enemies)
|
||||
if enemy then
|
||||
|
@ -104,6 +108,7 @@ function Seeker:init(args)
|
|||
elseif self.boss == 'randomizer' then
|
||||
self.t:every_immediate(0.07, function() self.color = _G[random:table{'green', 'purple', 'yellow', 'blue'}][0]:clone() end)
|
||||
self.t:every(6, function()
|
||||
if self.silenced then return end
|
||||
local attack = random:table{'explode', 'swarm', 'force', 'speed_boost'}
|
||||
if attack == 'explode' then
|
||||
local enemies = self:get_objects_in_shape(Circle(self.x, self.y, 128), {Seeker})
|
||||
|
@ -182,6 +187,7 @@ function Seeker:init(args)
|
|||
self.last_headbutt_time = 0
|
||||
local n = math.remap(current_new_game_plus, 0, 5, 1, 0.5)
|
||||
self.t:every(function() return math.distance(self.x, self.y, main.current.player.x, main.current.player.y) < 64 and love.timer.getTime() - self.last_headbutt_time > 10*n end, function()
|
||||
if self.silenced then return end
|
||||
if self.headbutt_charging or self.headbutting then return end
|
||||
self.headbutt_charging = true
|
||||
self.t:tween(2, self.color, {r = fg[0].r, b = fg[0].b, g = fg[0].g}, math.cubic_in_out, function()
|
||||
|
@ -208,6 +214,7 @@ function Seeker:init(args)
|
|||
self.t:after({2*n, 4*n}, function()
|
||||
self.shooting = true
|
||||
self.t:every({3, 5}, function()
|
||||
if self.silenced then return end
|
||||
for i = 1, 3 do
|
||||
self.t:after((1 - self.level*0.01)*0.15*(i-1), function()
|
||||
shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.1}
|
||||
|
@ -420,6 +427,7 @@ function Seeker:hit(damage, projectile)
|
|||
end
|
||||
|
||||
if self.speed_booster then
|
||||
if self.silenced then return end
|
||||
local enemies = self:get_objects_in_shape(self.area_sensor, main.current.enemies)
|
||||
if #enemies > 0 then
|
||||
buff1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
|
@ -432,6 +440,7 @@ function Seeker:hit(damage, projectile)
|
|||
end
|
||||
|
||||
if self.exploder then
|
||||
if self.silenced then return end
|
||||
shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.4}
|
||||
trigger:after(0.01, function()
|
||||
local n = 8 + current_new_game_plus*2
|
||||
|
@ -442,6 +451,7 @@ function Seeker:hit(damage, projectile)
|
|||
end
|
||||
|
||||
if self.spawner then
|
||||
if self.silenced then return end
|
||||
critter1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
trigger:after(0.01, function()
|
||||
for i = 1, random:int(5, 8) do
|
||||
|
@ -565,6 +575,9 @@ function Seeker:curse(curse, duration, arg1, arg2, arg3)
|
|||
self.infested_dmg = arg2
|
||||
self.infested_ref = arg3
|
||||
self.t:after(duration*curse_m, function() self.infested = false end, 'infestor_curse')
|
||||
elseif curse == 'silencer' then
|
||||
self.silenced = true
|
||||
self.t:after(duration*curse_m, function() self.silenced = false end, 'silencer_curse')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -745,6 +758,9 @@ function EnemyCritter:curse(curse, duration, arg1, arg2, arg3)
|
|||
self.infested_dmg = arg2
|
||||
self.infested_ref = arg3
|
||||
self.t:after(duration*curse_m, function() self.infested = false end, 'infestor_curse')
|
||||
elseif curse == 'silencer' then
|
||||
self.silenced = true
|
||||
self.t:after(duration*curse_m, function() self.silenced = false end, 'silencer_curse')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
121
main.lua
121
main.lua
|
@ -18,6 +18,13 @@ function init()
|
|||
input:bind('enter', {'space', 'return', 'fleft', 'fdown', 'fright'})
|
||||
|
||||
local s = {tags = {sfx}}
|
||||
psychic1 = Sound('Magical Impact 13.ogg', s)
|
||||
fire1 = Sound('Fire bolt 3.ogg', s)
|
||||
fire2 = Sound('Fire bolt 5.ogg', s)
|
||||
fire3 = Sound('Fire bolt 10.ogg', s)
|
||||
earth1 = Sound('Earth Bolt 1.ogg', s)
|
||||
earth2 = Sound('Earth Bolt 14.ogg', s)
|
||||
earth3 = Sound('Earth Bolt 20.ogg', s)
|
||||
illusion1 = Sound('Buff 5.ogg', s)
|
||||
thunder1 = Sound('399656__bajko__sfx-thunder-blast.ogg', s)
|
||||
flagellant1 = Sound('Whipping Horse 3.ogg', s)
|
||||
|
@ -211,6 +218,7 @@ function init()
|
|||
['vagrant'] = 'Vagrant',
|
||||
['swordsman'] = 'Swordsman',
|
||||
['wizard'] = 'Wizard',
|
||||
['magician'] = 'Magician',
|
||||
['archer'] = 'Archer',
|
||||
['scout'] = 'Scout',
|
||||
['cleric'] = 'Cleric',
|
||||
|
@ -262,6 +270,7 @@ function init()
|
|||
['vagrant'] = fg[0],
|
||||
['swordsman'] = yellow[0],
|
||||
['wizard'] = blue[0],
|
||||
['magician'] = blue[0],
|
||||
['archer'] = green[0],
|
||||
['scout'] = red[0],
|
||||
['cleric'] = green[0],
|
||||
|
@ -313,6 +322,7 @@ function init()
|
|||
['vagrant'] = 'fg',
|
||||
['swordsman'] = 'yellow',
|
||||
['wizard'] = 'blue',
|
||||
['magician'] = 'blue',
|
||||
['archer'] = 'green',
|
||||
['scout'] = 'red',
|
||||
['cleric'] = 'green',
|
||||
|
@ -363,7 +373,8 @@ function init()
|
|||
character_classes = {
|
||||
['vagrant'] = {'psyker', 'ranger', 'warrior'},
|
||||
['swordsman'] = {'warrior'},
|
||||
['wizard'] = {'mage'},
|
||||
['wizard'] = {'mage', 'nuker'},
|
||||
['magician'] = {'mage'},
|
||||
['archer'] = {'ranger'},
|
||||
['scout'] = {'rogue'},
|
||||
['cleric'] = {'healer'},
|
||||
|
@ -372,7 +383,7 @@ function init()
|
|||
['elementor'] = {'mage', 'nuker'},
|
||||
['saboteur'] = {'rogue', 'conjurer', 'nuker'},
|
||||
['stormweaver'] = {'enchanter'},
|
||||
['sage'] = {'nuker'},
|
||||
['sage'] = {'forcer', 'nuker'},
|
||||
['squire'] = {'warrior', 'enchanter'},
|
||||
['cannoneer'] = {'ranger', 'nuker'},
|
||||
['dual_gunner'] = {'ranger', 'rogue'},
|
||||
|
@ -414,7 +425,8 @@ function init()
|
|||
character_class_strings = {
|
||||
['vagrant'] = '[fg]Psyker, [green]Ranger, [yellow]Warrior',
|
||||
['swordsman'] = '[yellow]Warrior',
|
||||
['wizard'] = '[blue]Mage',
|
||||
['wizard'] = '[blue]Mage, [red]Nuker',
|
||||
['magician'] = '[blue]Mage',
|
||||
['archer'] = '[green]Ranger',
|
||||
['scout'] = '[red]Rogue',
|
||||
['cleric'] = '[green]Healer',
|
||||
|
@ -482,6 +494,7 @@ function init()
|
|||
['swordsman'] = function(lvl) return '[fg]deals [yellow]' .. get_character_stat('swordsman', lvl, 'dmg') .. '[fg] damage in an area, deals extra [yellow]' ..
|
||||
math.round(get_character_stat('swordsman', lvl, 'dmg')*0.15, 2) .. '[fg] damage per unit hit' end,
|
||||
['wizard'] = function(lvl) return '[fg]shoots a projectile that deals [yellow]' .. get_character_stat('wizard', lvl, 'dmg') .. ' AoE[fg] damage' end,
|
||||
['magician'] = function(lvl) return '[fg]creates a small area that deals [yellow]' .. get_character_stat('magician', lvl, 'dmg') .. 'AoE[fg] damage' end,
|
||||
['archer'] = function(lvl) return '[fg]shoots an arrow that deals [yellow]' .. get_character_stat('archer', lvl, 'dmg') .. '[fg] damage and pierces' end,
|
||||
['scout'] = function(lvl) return '[fg]throws a knife that deals [yellow]' .. get_character_stat('scout', lvl, 'dmg') .. '[fg] damage and chains [yellow]3[fg] times' end,
|
||||
['cleric'] = function(lvl) return '[fg]heals a unit for [yellow]20%[fg] of its max hp when it drops below [yellow]50%[fg] max hp' end,
|
||||
|
@ -508,32 +521,33 @@ function init()
|
|||
['corruptor'] = function(lvl) return '[fg]spawn [yellow]3[fg] small critters if the corruptor kills an enemy' end,
|
||||
['beastmaster'] = function(lvl) return '[fg]spawn [yellow]2[fg] small critters if the beastmaster crits' end,
|
||||
['launcher'] = function(lvl) return '[fg]all nearby enemies are pushed after [yellow]4[fg] seconds, taking [yellow]' .. 2*get_character_stat('launcher', lvl, 'dmg') .. '[fg] damage on wall hit' end,
|
||||
['jester'] = function(lvl) return "[fg]curses [yellow]4[fg] nearby enemies for [yellow]6[fg] seconds, they will explode into [yellow]3[fg] knives on death" end,
|
||||
['jester'] = function(lvl) return "[fg]curses [yellow]6[fg] nearby enemies for [yellow]6[fg] seconds, they will explode into [yellow]3[fg] knives on death" end,
|
||||
['assassin'] = function(lvl) return '[fg]throws a piercing knife that deals [yellow]' .. get_character_stat('assassin', lvl, 'dmg') .. '[fg] damage + [yellow]' ..
|
||||
get_character_stat('assassin', lvl, 'dmg')/2 .. '[fg] damage per second' end,
|
||||
['host'] = function(lvl) return '[fg]periodically spawn [yellow]1[fg] small critter' end,
|
||||
['carver'] = function(lvl) return '[fg]carves a statue that periodically heals [yellow]1[fg] unit for [yellow]20%[fg] max HP if in range' end,
|
||||
['bane'] = function(lvl) return '[fg]curses [yellow]5[fg] nearby enemies for [yellow]6[fg] seconds, they will create small void rifts on death' end,
|
||||
['bane'] = function(lvl) return '[fg]curses [yellow]6[fg] nearby enemies for [yellow]6[fg] seconds, they will create small void rifts on death' end,
|
||||
['psykino'] = function(lvl) return '[fg]pulls enemies together for [yellow]2[fg] seconds' end,
|
||||
['barrager'] = function(lvl) return '[fg]shoots a barrage of [yellow]3[fg] arrows, each dealing [yellow]' .. get_character_stat('barrager', lvl, 'dmg') .. '[fg] damage and pushing enemies' end,
|
||||
['highlander'] = function(lvl) return '[fg]deals [yellow]' .. 5*get_character_stat('highlander', lvl, 'dmg') .. '[fg] AoE damage' end,
|
||||
['fairy'] = function(lvl) return '[fg]periodically heals [yellow]1[fg] unit at random and grants it [yellow]+100%[fg] attack speed for [yellow]6[fg] seconds' end,
|
||||
['priest'] = function(lvl) return '[fg]heals all allies for [yellow]20%[fg] their max HP' end,
|
||||
['infestor'] = function(lvl) return '[fg]curses all nearby enemies for [yellow]6[fg] seconds, they will release [yellow]2[fg] critters on death' end,
|
||||
['infestor'] = function(lvl) return '[fg]curses [yellow]8[fg] nearby enemies for [yellow]6[fg] seconds, they will release [yellow]2[fg] critters on death' end,
|
||||
['flagellant'] = function(lvl) return '[fg]deals [yellow]' .. 2*get_character_stat('flagellant', lvl, 'dmg') .. '[fg] damage to self and grants [yellow]+4%[fg] damage to all allies per cast' end,
|
||||
['arcanist'] = function(lvl) return '[fg]launches a slow moving orb that launches projectiles, each dealing [yellow]' .. get_character_stat('arcanist', lvl, 'dmg') .. '[fg] damage' end,
|
||||
['illusionist'] = function(lvl) return '[fg]launches a projectile that deals [yellow]' .. get_character_stat('illusionist', lvl, 'dmg') .. '[fg] damage and creates copies that do the same' end,
|
||||
['witch'] = function(lvl) return '[fg]creates an area that ricochets around the arena and deals [yellow]' .. get_character_stat('witch', lvl, 'dmg') .. '[fg] damage per second' end,
|
||||
['silencer'] = function(lvl) return '[fg]curses [yellow]5[fg] nearby enemies for [yellow]6[fg] seconds, preventing them from using special attacks' end,
|
||||
['vulcanist'] = function(lvl) return '[fg]creates a volcano that explodes the nearby area [yellow]5[fg] times, dealing [yellow]' .. get_character_stat('vulcanist', lvl, 'dmg') .. 'AoE [fg]damage' end,
|
||||
['vulcanist'] = function(lvl) return '[fg]creates a volcano that explodes the nearby area [yellow]4[fg] times, dealing [yellow]' .. get_character_stat('vulcanist', lvl, 'dmg') .. 'AoE [fg]damage' end,
|
||||
['warden'] = function(lvl) return '[fg]creates a force field around a random unit that prevents enemies from entering' end,
|
||||
['psychic'] = function(lvl) return '[fg]creates a small area that deals [yellow]' .. get_character_stat('psychic', lvl, 'dmg') .. '[fg] damage' end,
|
||||
['psychic'] = function(lvl) return '[fg]creates a small area that deals [yellow]' .. get_character_stat('psychic', lvl, 'dmg') .. 'AoE[fg] damage' end,
|
||||
}
|
||||
|
||||
character_effect_names = {
|
||||
['vagrant'] = '[fg]Champion',
|
||||
['swordsman'] = '[yellow]Cleave',
|
||||
['wizard'] = '[blue]Magic Missile',
|
||||
['magician'] = '[blue]Teleportation',
|
||||
['archer'] = '[green]Bounce Shot',
|
||||
['scout'] = '[red]Dagger Resonance',
|
||||
['cleric'] = '[green]Mass Heal ',
|
||||
|
@ -585,6 +599,7 @@ function init()
|
|||
['vagrant'] = '[light_bg]Champion',
|
||||
['swordsman'] = '[light_bg]Cleave',
|
||||
['wizard'] = '[light_bg]Magic Missile',
|
||||
['magician'] = '[light_bg]Teleportation',
|
||||
['archer'] = '[light_bg]Bounce Shot',
|
||||
['scout'] = '[light_bg]Dagger Resonance',
|
||||
['cleric'] = '[light_bg]Mass Heal ',
|
||||
|
@ -635,12 +650,13 @@ function init()
|
|||
character_effect_descriptions = {
|
||||
['vagrant'] = function() return '[yellow]+10%[fg] damage and [yellow]+10%[fg] attack speed per active set' end,
|
||||
['swordsman'] = function() return "[fg]the swordsman's damage is [yellow]doubled" end,
|
||||
['wizard'] = function() return '[fg]the projectile chains [yellow]3[fg] times' end,
|
||||
['wizard'] = function() return '[fg]the projectile chains [yellow]2[fg] times' end,
|
||||
['magician'] = function() return '[fg]the magician becomes invulnerable for [yellow]6[fg] seconds' end,
|
||||
['archer'] = function() return '[fg]the arrow ricochets off walls [yellow]3[fg] times' end,
|
||||
['scout'] = function() return '[yellow]+25%[fg] damage per chain and [yellow]+3[fg] chains' end,
|
||||
['cleric'] = function() return '[fg]heals all units' end,
|
||||
['outlaw'] = function() return "[yellow]+50%[fg] outlaw attack speed and his knives seek enemies" end,
|
||||
['blade'] = function() return '[fg]deal additional [yellow]' .. get_character_stat('blade', 3, 'dmg')/3 .. '[fg] damage per enemy hit' end,
|
||||
['blade'] = function() return '[fg]deal additional [yellow]' .. math.round(get_character_stat('blade', 3, 'dmg')/3, 2) .. '[fg] damage per enemy hit' end,
|
||||
['elementor'] = function() return '[fg]slows enemies by [yellow]60%[fg] for [yellow]6[fg] seconds on hit' end,
|
||||
['saboteur'] = function() return '[fg]the explosion has [yellow]50%[fg] chance to crit, increasing in size and dealing [yellow]2x[fg] damage' end,
|
||||
['stormweaver'] = function() return "[fg]chain lightning's trigger area of effect and number of units hit is [yellow]doubled" end,
|
||||
|
@ -674,12 +690,12 @@ function init()
|
|||
['priest'] = function() return '[fg]picks [yellow]3[fg] units at random and grants them a buff that prevents death once' end,
|
||||
['infestor'] = function() return '[fg][yellow]triples[fg] the number of critters released' end,
|
||||
['flagellant'] = function() return '[fg]deals [yellow]' .. 2*get_character_stat('flagellant', 3, 'dmg') .. '[fg] damage to all allies and grants [yellow]+12%[fg] damage to all allies per cast' end,
|
||||
['arcanist'] = function() return '[yellow]100%[fg] increased attack speed for the orb and [yellow]2[fg] projectiles are released per cast' end,
|
||||
['arcanist'] = function() return '[yellow]+100%[fg] attack speed for the orb and [yellow]2[fg] projectiles are released per cast' end,
|
||||
['illusionist'] = function() return '[yellow]doubles[fg] the number of copies created and they release [yellow]12[fg] projectiles on death that pierce and ricochet once' end,
|
||||
['witch'] = function() return '[fg]the area periodically releases projectiles, each dealing [yellow]' .. get_character_stat('witch', 3, 'dmg') .. '[fg] damage and chaining once' end,
|
||||
['silencer'] = function() return '[fg]the curse also deals [yellow]' .. get_character_stat('silencer', 3, 'dmg') .. '[fg] damage per second' end,
|
||||
['vulcanist'] = function() return '[fg]the volcano spawn also deals [yellow]' .. get_character_stat('vulcanist', 3, 'dmg') .. 'AoE [fg] damage and [yellow]doubles[fg] the number of explosions' end,
|
||||
['warden'] = function() return '[fg]creates the force field around [yellow]2[fg] additional random units' end,
|
||||
['vulcanist'] = function() return '[fg]the number and speed of explosions is [yellow]doubled[fg]' end,
|
||||
['warden'] = function() return '[fg]creates the force field around [yellow]2[fg] units, and they are always the [yellow]head[fg] and [yellow]tail[fg] of the snake' end,
|
||||
['psychic'] = function() return '[fg]the attack can happen from any distance and deals [yellow]double[fg] damage' end,
|
||||
}
|
||||
|
||||
|
@ -687,11 +703,12 @@ function init()
|
|||
['vagrant'] = function() return '[light_bg]+10% damage and +10% attack speed per active set' end,
|
||||
['swordsman'] = function() return "[light_bg]the swordsman's damage is doubled" end,
|
||||
['wizard'] = function() return '[light_bg]the projectile chains 3 times' end,
|
||||
['magician'] = function() return '[light_bg]the magician becomes invulnerable for 6 seconds' end,
|
||||
['archer'] = function() return '[light_bg]the arrow ricochets off walls 3 times' end,
|
||||
['scout'] = function() return '[light_bg]+25% damage per chain and +3 chains' end,
|
||||
['cleric'] = function() return '[light_bg]heals all units' end,
|
||||
['outlaw'] = function() return "[light_bg]+50% outlaw attack speed and his knives seek enemies" end,
|
||||
['blade'] = function() return '[light_bg]deal additional ' .. get_character_stat('blade', 3, 'dmg')/2 .. ' damage per enemy hit' end,
|
||||
['blade'] = function() return '[light_bg]deal additional ' .. math.round(get_character_stat('blade', 3, 'dmg')/2, 2) .. ' damage per enemy hit' end,
|
||||
['elementor'] = function() return '[light_bg]slows enemies by 60% for 6 seconds on hit' end,
|
||||
['saboteur'] = function() return '[light_bg]the explosion has 50% chance to crit, increasing in size and dealing 2x damage' end,
|
||||
['stormweaver'] = function() return "[light_bg]chain lightning's trigger area of effect and number of units hit is doubled" end,
|
||||
|
@ -725,12 +742,12 @@ function init()
|
|||
['priest'] = function() return '[light_bg]picks 3 units at random and grants them a buff that prevents death once' end,
|
||||
['infestor'] = function() return '[light_bg]triples the number of critters released' end,
|
||||
['flagellant'] = function() return '[light_bg]deals ' .. 2*get_character_stat('flagellant', 3, 'dmg') .. ' damage to all allies and grants +12% damage to all allies per cast' end,
|
||||
['arcanist'] = function() return '[light_bg]100% increased attack speed for the orb and 2 projectiles are released per cast' end,
|
||||
['illusionist'] = function() return '[light_bg]doubles the number of copies created and they release 12 projectiles on death' end,
|
||||
['arcanist'] = function() return '[light_bg]+100% attack speed for the orb and 2 projectiles are released per cast' end,
|
||||
['illusionist'] = function() return '[light_bg]doubles the number of copies created and they release 12 projectiles on death that pierce and ricochet once' end,
|
||||
['witch'] = function() return '[light_bg]the area periodically releases projectiles, each dealing ' .. get_character_stat('witch', 3, 'dmg') .. ' damage and chaining once' end,
|
||||
['silencer'] = function() return '[light_bg]the curse also deals ' .. get_character_stat('silencer', 3, 'dmg') .. ' damage per second' end,
|
||||
['vulcanist'] = function() return '[light_bg]the volcano spawn also deals ' .. get_character_stat('vulcanist', 3, 'dmg') .. 'AoE damage and doubles the number of explosions' end,
|
||||
['warden'] = function() return '[light_bg]creates the force field around 2 additional random units' end,
|
||||
['vulcanist'] = function() return '[light_bg]the number and speed of explosions is doubled' end,
|
||||
['warden'] = function() return '[light_bg]creates the force field around 2 units, and they are always the head and tail of the snake' end,
|
||||
['psychic'] = function() return '[light_bg]the attack can happen from any distance and deals double damage' end,
|
||||
}
|
||||
|
||||
|
@ -738,6 +755,7 @@ function init()
|
|||
['vagrant'] = function(lvl) return get_character_stat_string('vagrant', lvl) end,
|
||||
['swordsman'] = function(lvl) return get_character_stat_string('swordsman', lvl) end,
|
||||
['wizard'] = function(lvl) return get_character_stat_string('wizard', lvl) end,
|
||||
['magician'] = function(lvl) return get_character_stat_string('magician', lvl) end,
|
||||
['archer'] = function(lvl) return get_character_stat_string('archer', lvl) end,
|
||||
['scout'] = function(lvl) return get_character_stat_string('scout', lvl) end,
|
||||
['cleric'] = function(lvl) return get_character_stat_string('cleric', lvl) end,
|
||||
|
@ -797,7 +815,7 @@ function init()
|
|||
['psyker'] = {hp = 1.5, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 0.5, mvspd = 1},
|
||||
['curser'] = {hp = 1, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 0.75, mvspd = 1},
|
||||
['forcer'] = {hp = 1.25, dmg = 1.1, aspd = 0.9, area_dmg = 0.75, area_size = 0.75, def = 1.2, mvspd = 1},
|
||||
['swarmer'] = {hp = 1.2, dmg = 1, aspd = 1.25, area_dmg = 1, area_size = 1, def = 0.75, mvspd = 0.5},
|
||||
['swarmer'] = {hp = 1.2, dmg = 1, aspd = 1.25, area_dmg = 1, area_size = 1, def = 0.75, mvspd = 0.75},
|
||||
['voider'] = {hp = 0.75, dmg = 1.3, aspd = 1, area_dmg = 0.8, area_size = 0.75, def = 0.6, mvspd = 0.8},
|
||||
['sorcerer'] = {hp = 0.8, dmg = 1.3, aspd = 1, area_dmg = 1.2, area_size = 1, def = 0.8, mvspd = 1},
|
||||
['seeker'] = {hp = 0.5, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 0.3},
|
||||
|
@ -836,15 +854,15 @@ function init()
|
|||
['swarmer'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[' .. ylb2(lvl) .. ']/4 [fg]- [' .. ylb1(lvl) .. ']+1[' .. ylb2(lvl) .. ']/+3 [fg]hits to critters' end,
|
||||
['voider'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[' .. ylb2(lvl) .. ']/4 [fg]- [' .. ylb1(lvl) .. ']+15%[' .. ylb2(lvl) .. ']/+25% [fg]damage over time to allied voiders' end,
|
||||
['sorcerer'] = function(lvl)
|
||||
return '[' .. ybl1(lvl) .. ']2[' .. ylb2(lvl) .. ']/4[' .. ylb3(lvl) .. '/6 [fg]- sorcerers repeat their attacks once every [' .. ylb1(lvl) .. ']4/[' .. ylb2(lvl) .. ']3/[' .. ylb3(lvl) .. ']2[fg] attacks'
|
||||
return '[' .. ylb1(lvl) .. ']2[' .. ylb2(lvl) .. ']/4[' .. ylb3(lvl) .. ']/6 [fg]- sorcerers repeat their attacks once every [' .. ylb1(lvl) .. ']4/[' .. ylb2(lvl) .. ']3/[' .. ylb3(lvl) .. ']2[fg] attacks'
|
||||
end,
|
||||
}
|
||||
|
||||
tier_to_characters = {
|
||||
[1] = {'vagrant', 'swordsman', 'wizard', 'archer', 'scout', 'cleric'},
|
||||
[2] = {'saboteur', 'sage', 'squire', 'dual_gunner', 'hunter', 'chronomancer', 'barbarian', 'cryomancer', 'beastmaster', 'launcher', 'jester', 'carver'},
|
||||
[3] = {'outlaw', 'elementor', 'stormweaver', 'spellblade', 'psykeeper', 'engineer', 'juggernaut', 'pyromancer', 'corruptor', 'assassin', 'bane', 'barrager', 'infestor', 'flagellant'},
|
||||
[4] = {'priest', 'highlander', 'psykino', 'lich', 'host', 'fairy', 'blade', 'plague_doctor', 'cannoneer'},
|
||||
[1] = {'vagrant', 'swordsman', 'magician', 'archer', 'scout', 'cleric', 'arcanist'},
|
||||
[2] = {'wizard', 'saboteur', 'sage', 'squire', 'dual_gunner', 'hunter', 'chronomancer', 'barbarian', 'cryomancer', 'beastmaster', 'launcher', 'jester', 'carver', 'psychic', 'witch', 'silencer', 'outlaw'},
|
||||
[3] = {'elementor', 'stormweaver', 'spellblade', 'psykeeper', 'engineer', 'juggernaut', 'pyromancer', 'host', 'assassin', 'bane', 'barrager', 'infestor', 'flagellant', 'illusionist'},
|
||||
[4] = {'priest', 'highlander', 'psykino', 'fairy', 'blade', 'plague_doctor', 'cannoneer', 'vulcanist', 'warden', 'corruptor'},
|
||||
}
|
||||
|
||||
non_attacking_characters = {'cleric', 'stormweaver', 'squire', 'chronomancer', 'sage', 'psykeeper', 'bane', 'carver', 'fairy', 'priest', 'flagellant'}
|
||||
|
@ -853,14 +871,16 @@ function init()
|
|||
character_tiers = {
|
||||
['vagrant'] = 1,
|
||||
['swordsman'] = 1,
|
||||
['wizard'] = 1,
|
||||
['magician'] = 1,
|
||||
['archer'] = 1,
|
||||
['scout'] = 1,
|
||||
['cleric'] = 1,
|
||||
['outlaw'] = 3,
|
||||
['arcanist'] = 1,
|
||||
['outlaw'] = 2,
|
||||
['blade'] = 4,
|
||||
['elementor'] = 3,
|
||||
['saboteur'] = 2,
|
||||
['wizard'] = 2,
|
||||
['stormweaver'] = 3,
|
||||
['sage'] = 2,
|
||||
['squire'] = 2,
|
||||
|
@ -874,15 +894,15 @@ function init()
|
|||
['plague_doctor'] = 4,
|
||||
['barbarian'] = 2,
|
||||
['juggernaut'] = 3,
|
||||
['lich'] = 4,
|
||||
-- ['lich'] = 4,
|
||||
['cryomancer'] = 2,
|
||||
['pyromancer'] = 3,
|
||||
['corruptor'] = 3,
|
||||
['corruptor'] = 4,
|
||||
['beastmaster'] = 2,
|
||||
['launcher'] = 2,
|
||||
['jester'] = 2,
|
||||
['assassin'] = 3,
|
||||
['host'] = 4,
|
||||
['host'] = 3,
|
||||
['carver'] = 2,
|
||||
['bane'] = 3,
|
||||
['psykino'] = 4,
|
||||
|
@ -892,6 +912,12 @@ function init()
|
|||
['priest'] = 4,
|
||||
['infestor'] = 3,
|
||||
['flagellant'] = 3,
|
||||
['psychic'] = 2,
|
||||
['witch'] = 2,
|
||||
['silencer'] = 2,
|
||||
['illusionist'] = 3,
|
||||
['warden'] = 4,
|
||||
['vulcanist'] = 4,
|
||||
}
|
||||
|
||||
get_number_of_units_per_class = function(units)
|
||||
|
@ -976,19 +1002,20 @@ function init()
|
|||
end
|
||||
|
||||
class_set_numbers = {
|
||||
['ranger'] = function(units) return 3, 6, get_number_of_units_per_class(units).ranger end,
|
||||
['warrior'] = function(units) return 3, 6, get_number_of_units_per_class(units).warrior end,
|
||||
['mage'] = function(units) return 3, 6, get_number_of_units_per_class(units).mage end,
|
||||
['nuker'] = function(units) return 3, 6, get_number_of_units_per_class(units).nuker end,
|
||||
['rogue'] = function(units) return 3, 6, get_number_of_units_per_class(units).rogue end,
|
||||
['healer'] = function(units) return 2, 4, get_number_of_units_per_class(units).healer end,
|
||||
['conjurer'] = function(units) return 2, 4, get_number_of_units_per_class(units).conjurer end,
|
||||
['enchanter'] = function(units) return 2, 4, get_number_of_units_per_class(units).enchanter end,
|
||||
['psyker'] = function(units) return 2, 4, get_number_of_units_per_class(units).psyker end,
|
||||
['curser'] = function(units) return 2, 4, get_number_of_units_per_class(units).curser end,
|
||||
['forcer'] = function(units) return 2, 4, get_number_of_units_per_class(units).forcer end,
|
||||
['swarmer'] = function(units) return 2, 4, get_number_of_units_per_class(units).swarmer end,
|
||||
['voider'] = function(units) return 2, 4, get_number_of_units_per_class(units).voider end,
|
||||
['ranger'] = function(units) return 3, 6, nil, get_number_of_units_per_class(units).ranger end,
|
||||
['warrior'] = function(units) return 3, 6, nil, get_number_of_units_per_class(units).warrior end,
|
||||
['mage'] = function(units) return 3, 6, nil, get_number_of_units_per_class(units).mage end,
|
||||
['nuker'] = function(units) return 3, 6, nil, get_number_of_units_per_class(units).nuker end,
|
||||
['rogue'] = function(units) return 3, 6, nil, get_number_of_units_per_class(units).rogue end,
|
||||
['healer'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).healer end,
|
||||
['conjurer'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).conjurer end,
|
||||
['enchanter'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).enchanter end,
|
||||
['psyker'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).psyker end,
|
||||
['curser'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).curser end,
|
||||
['forcer'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).forcer end,
|
||||
['swarmer'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).swarmer end,
|
||||
['voider'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).voider end,
|
||||
['sorcerer'] = function(units) return 2, 4, 6, get_number_of_units_per_class(units).sorcerer end,
|
||||
}
|
||||
|
||||
passive_names = {
|
||||
|
@ -1288,17 +1315,17 @@ function init()
|
|||
if run.level and run.level > 0 then
|
||||
main_song_instance = _G[random:table{'song1', 'song2', 'song3', 'song4', 'song5'}]:play{volume = 0.5}
|
||||
end
|
||||
main_song_instance = _G[random:table{'song1', 'song2', 'song3', 'song4', 'song5'}]:play{volume = 0.5}
|
||||
-- main_song_instance = _G[random:table{'song1', 'song2', 'song3', 'song4', 'song5'}]:play{volume = 0.5}
|
||||
|
||||
--[[
|
||||
main:add(BuyScreen'buy_screen')
|
||||
main:go_to('buy_screen', run.level or 0, run.units or {}, passives)
|
||||
]]--
|
||||
|
||||
--[[
|
||||
main:add(Arena'arena')
|
||||
main:go_to('arena', 16, {
|
||||
{character = 'witch', level = 3},
|
||||
main:go_to('arena', 14, {
|
||||
{character = 'magician', level = 3},
|
||||
}, passives)
|
||||
]]--
|
||||
|
||||
trigger:every(2, function()
|
||||
if debugging_memory then
|
||||
|
|
371
player.lua
371
player.lua
|
@ -34,10 +34,26 @@ function Player:init(args)
|
|||
self.t:cooldown(2, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||
local closest_enemy = self:get_closest_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||
if closest_enemy then
|
||||
self:shoot(self:angle_to_object(closest_enemy), {chain = (self.level == 3 and 3 or 0)})
|
||||
self:shoot(self:angle_to_object(closest_enemy), {chain = (self.level == 3 and 2 or 0)})
|
||||
end
|
||||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'magician' then
|
||||
self.attack_sensor = Circle(self.x, self.y, 96)
|
||||
self.t:cooldown(2, 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)
|
||||
if enemy then
|
||||
self:attack(32, {x = enemy.x, y = enemy.y})
|
||||
end
|
||||
end, nil, nil, 'attack')
|
||||
|
||||
if self.level == 3 then
|
||||
self.t:every(12, function()
|
||||
self.magician_invulnerable = true
|
||||
self.t:after(6, function() self.magician_invulnerable = false end, 'magician_invulnerable')
|
||||
end)
|
||||
end
|
||||
|
||||
elseif self.character == 'archer' then
|
||||
self.attack_sensor = Circle(self.x, self.y, 160)
|
||||
self.t:cooldown(2, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||
|
@ -57,11 +73,10 @@ function Player:init(args)
|
|||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'cleric' then
|
||||
self.last_heal_time = love.timer.getTime()
|
||||
self.t:every(2, function()
|
||||
self.t:every(6, function()
|
||||
local all_units = self:get_all_units()
|
||||
local unit_index = table.contains(all_units, function(v) return v.hp <= 0.5*v.max_hp end)
|
||||
if unit_index and love.timer.getTime() - self.last_heal_time > 6 then
|
||||
if unit_index then
|
||||
local unit = all_units[unit_index]
|
||||
self.last_heal_time = love.timer.getTime()
|
||||
if self.level == 3 then
|
||||
|
@ -74,20 +89,40 @@ function Player:init(args)
|
|||
end, nil, nil, 'heal')
|
||||
|
||||
elseif self.character == 'arcanist' then
|
||||
self.sorcerer_count = 0
|
||||
self.attack_sensor = Circle(self.x, self.y, 128)
|
||||
self.t:cooldown(3, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||
local closest_enemy = self:get_closest_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||
if closest_enemy then
|
||||
self:shoot(self:angle_to_object(closest_enemy), {pierce = 1000, v = 40})
|
||||
if main.current.sorcerer_level > 0 then
|
||||
self.sorcerer_count = self.sorcerer_count + 1
|
||||
if self.sorcerer_count >= ((main.current.sorcerer_level == 3 and 2) or (main.current.sorcerer_level == 2 and 3) or (main.current.sorcerer_level == 1 and 4)) then
|
||||
self.sorcerer_count = 0
|
||||
self.t:after(0.25, function()
|
||||
self:shoot(self:angle_to_object(closest_enemy), {pierce = 1000, v = 40})
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'illusionist' then
|
||||
self.sorcerer_count = 0
|
||||
self.attack_sensor = Circle(self.x, self.y, 96)
|
||||
self.t:cooldown(2, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||
local closest_enemy = self:get_closest_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||
if closest_enemy then
|
||||
self:shoot(self:angle_to_object(closest_enemy))
|
||||
if main.current.sorcerer_level > 0 then
|
||||
self.sorcerer_count = self.sorcerer_count + 1
|
||||
if self.sorcerer_count >= ((main.current.sorcerer_level == 3 and 2) or (main.current.sorcerer_level == 2 and 3) or (main.current.sorcerer_level == 1 and 4)) then
|
||||
self.sorcerer_count = 0
|
||||
self.t:after(0.25, function()
|
||||
self:shoot(self:angle_to_object(closest_enemy))
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
end, nil, nil, 'shoot')
|
||||
self.t:every(8, function()
|
||||
|
@ -96,6 +131,18 @@ function Player:init(args)
|
|||
illusion1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
Illusion{group = main.current.main, x = x, y = y, parent = self, level = self.level, conjurer_buff_m = self.conjurer_buff_m or 1, crit = (self.level == 3) and random:bool(50)}
|
||||
end}
|
||||
if main.current.sorcerer_level > 0 then
|
||||
self.sorcerer_count = self.sorcerer_count + 1
|
||||
if self.sorcerer_count >= ((main.current.sorcerer_level == 3 and 2) or (main.current.sorcerer_level == 2 and 3) or (main.current.sorcerer_level == 1 and 4)) then
|
||||
self.sorcerer_count = 0
|
||||
self.t:after(0.25, function()
|
||||
SpawnEffect{group = main.current.effects, x = self.x, y = self.y, color = self.color, action = function(x, y)
|
||||
illusion1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
Illusion{group = main.current.main, x = x, y = y, parent = self, level = self.level, conjurer_buff_m = self.conjurer_buff_m or 1, crit = (self.level == 3) and random:bool(50)}
|
||||
end}
|
||||
end)
|
||||
end
|
||||
end
|
||||
end, self.level == 3 and 2 or 1)
|
||||
end)
|
||||
|
||||
|
@ -123,6 +170,38 @@ function Player:init(args)
|
|||
end
|
||||
end, nil, nil, 'attack')
|
||||
|
||||
elseif self.character == 'psychic' then
|
||||
self.sorcerer_count = 0
|
||||
self.attack_sensor = Circle(self.x, self.y, self.level == 3 and 512 or 64)
|
||||
self.t:cooldown(3, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||
local strike = function()
|
||||
local enemy = self:get_random_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||
if enemy then
|
||||
if self.level == 3 then
|
||||
self:attack(32, {x = enemy.x, y = enemy.y})
|
||||
self.t:after(0.5, function()
|
||||
local enemy = self:get_random_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||
if enemy then
|
||||
self:attack(32, {x = enemy.x, y = enemy.y})
|
||||
end
|
||||
end)
|
||||
else
|
||||
self:attack(32, {x = enemy.x, y = enemy.y})
|
||||
end
|
||||
end
|
||||
end
|
||||
strike()
|
||||
if main.current.sorcerer_level > 0 then
|
||||
self.sorcerer_count = self.sorcerer_count + 1
|
||||
if self.sorcerer_count >= ((main.current.sorcerer_level == 3 and 2) or (main.current.sorcerer_level == 2 and 3) or (main.current.sorcerer_level == 1 and 4)) then
|
||||
self.sorcerer_count = 0
|
||||
self.t:after(0.1, function()
|
||||
strike()
|
||||
end)
|
||||
end
|
||||
end
|
||||
end, nil, nil, 'attack')
|
||||
|
||||
elseif self.character == 'saboteur' then
|
||||
self.t:every(8, function()
|
||||
self.t:every(0.25, function()
|
||||
|
@ -159,6 +238,38 @@ function Player:init(args)
|
|||
end
|
||||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'vulcanist' then
|
||||
self.sorcerer_count = 0
|
||||
self.attack_sensor = Circle(self.x, self.y, 128)
|
||||
self.t:every(12, function()
|
||||
local volcano = function()
|
||||
local enemies = main.current.main:get_objects_by_classes(main.current.enemies)
|
||||
local x, y = 0, 0
|
||||
if enemies and #enemies > 0 then
|
||||
for _, enemy in ipairs(enemies) do
|
||||
x = x + enemy.x
|
||||
y = y + enemy.y
|
||||
end
|
||||
x = x/#enemies
|
||||
y = y/#enemies
|
||||
end
|
||||
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}
|
||||
end
|
||||
volcano()
|
||||
if main.current.sorcerer_level > 0 then
|
||||
self.sorcerer_count = self.sorcerer_count + 1
|
||||
if self.sorcerer_count >= ((main.current.sorcerer_level == 3 and 2) or (main.current.sorcerer_level == 2 and 3) or (main.current.sorcerer_level == 1 and 4)) then
|
||||
self.sorcerer_count = 0
|
||||
self.t:after(0.5, function()
|
||||
volcano()
|
||||
end)
|
||||
end
|
||||
end
|
||||
end, nil, nil, 'attack')
|
||||
|
||||
elseif self.character == 'dual_gunner' then
|
||||
self.dg_counter = 0
|
||||
self.attack_sensor = Circle(self.x, self.y, 96)
|
||||
|
@ -229,8 +340,18 @@ function Player:init(args)
|
|||
end
|
||||
|
||||
elseif self.character == 'witch' then
|
||||
self.t:every(6, function()
|
||||
self:dot_attack(24, {duration = random:float(12, 16), homing = true})
|
||||
self.sorcerer_count = 0
|
||||
self.t:every(4, function()
|
||||
self:dot_attack(42, {duration = random:float(12, 16)})
|
||||
if main.current.sorcerer_level > 0 then
|
||||
self.sorcerer_count = self.sorcerer_count + 1
|
||||
if self.sorcerer_count >= ((main.current.sorcerer_level == 3 and 2) or (main.current.sorcerer_level == 2 and 3) or (main.current.sorcerer_level == 1 and 4)) then
|
||||
self.sorcerer_count = 0
|
||||
self.t:after(0.25, function()
|
||||
self:dot_attack(42, {duration = random:float(12, 16)})
|
||||
end)
|
||||
end
|
||||
end
|
||||
end, nil, nil, 'attack')
|
||||
|
||||
elseif self.character == 'barbarian' then
|
||||
|
@ -281,7 +402,8 @@ function Player:init(args)
|
|||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'launcher' then
|
||||
self.t:every({6, 10}, function()
|
||||
self.attack_sensor = Circle(self.x, self.y, 96)
|
||||
self.t:cooldown(6, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||
buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
||||
local enemies = main.current.main:get_objects_by_classes(main.current.enemies)
|
||||
for _, enemy in ipairs(enemies) do
|
||||
|
@ -296,9 +418,10 @@ function Player:init(args)
|
|||
end, nil, nil, 'attack')
|
||||
|
||||
elseif self.character == 'jester' then
|
||||
self.t:every({6, 10}, function()
|
||||
self.attack_sensor = Circle(self.x, self.y, 96)
|
||||
self.t:cooldown(6, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||
buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
||||
local enemies = table.first(table.shuffle(main.current.main:get_objects_by_classes(main.current.enemies)), self.level == 3 and 8 or 4)
|
||||
local enemies = table.first(table.shuffle(main.current.main:get_objects_by_classes(main.current.enemies)), 6)
|
||||
for _, enemy in ipairs(enemies) do
|
||||
if self:distance_to_object(enemy) < 128 then
|
||||
enemy:curse('jester', 6*(self.hex_duration_m or 1), self.level == 3, self)
|
||||
|
@ -308,6 +431,40 @@ function Player:init(args)
|
|||
end
|
||||
end, nil, nil, 'attack')
|
||||
|
||||
elseif self.character == 'silencer' then
|
||||
self.sorcerer_count = 0
|
||||
self.attack_sensor = Circle(self.x, self.y, 96)
|
||||
self.t:cooldown(6, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||
local curse = function()
|
||||
buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
||||
local enemies = table.first(table.shuffle(main.current.main:get_objects_by_classes(main.current.enemies)), 6)
|
||||
for _, enemy in ipairs(enemies) do
|
||||
if self:distance_to_object(enemy) < 128 then
|
||||
enemy:curse('silencer', 6*(self.hex_duration_m or 1), self.level == 3, self)
|
||||
if self.level == 3 then
|
||||
local curse_m = 1
|
||||
if main.current.curser_level == 2 then curse_m = 1.5
|
||||
elseif main.current.curser_level == 1 then curse_m = 1.25
|
||||
else curse_m = 1 end
|
||||
enemy:apply_dot(self.dmg*(self.dot_dmg_m or 1)*(main.current.chronomancer_dot or 1), 6*(self.hex_duration_m or 1)*(curse_m or 1))
|
||||
end
|
||||
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = blue2[0], duration = 0.1}
|
||||
LightningLine{group = main.current.effects, src = self, dst = enemy, color = blue2[0]}
|
||||
end
|
||||
end
|
||||
end
|
||||
curse()
|
||||
if main.current.sorcerer_level > 0 then
|
||||
self.sorcerer_count = self.sorcerer_count + 1
|
||||
if self.sorcerer_count >= ((main.current.sorcerer_level == 3 and 2) or (main.current.sorcerer_level == 2 and 3) or (main.current.sorcerer_level == 1 and 4)) then
|
||||
self.sorcerer_count = 0
|
||||
self.t:after(0.5, function()
|
||||
curse()
|
||||
end)
|
||||
end
|
||||
end
|
||||
end, nil, nil, 'attack')
|
||||
|
||||
elseif self.character == 'assassin' then
|
||||
self.attack_sensor = Circle(self.x, self.y, 64)
|
||||
self.t:cooldown(2, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||
|
@ -338,9 +495,10 @@ function Player:init(args)
|
|||
end, nil, nil, 'spawn')
|
||||
|
||||
elseif self.character == 'bane' then
|
||||
self.t:every({6, 10}, function()
|
||||
self.attack_sensor = Circle(self.x, self.y, 96)
|
||||
self.t:cooldown(6, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||
buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
||||
local enemies = table.first(table.shuffle(main.current.main:get_objects_by_classes(main.current.enemies)), 5)
|
||||
local enemies = table.first(table.shuffle(main.current.main:get_objects_by_classes(main.current.enemies)), 6)
|
||||
for _, enemy in ipairs(enemies) do
|
||||
if self:distance_to_object(enemy) < 128 then
|
||||
enemy:curse('bane', 6*(self.hex_duration_m or 1), self.level == 3, self)
|
||||
|
@ -399,24 +557,66 @@ function Player:init(args)
|
|||
local units = self:get_all_units()
|
||||
local unit_1 = random:table_remove(units)
|
||||
local unit_2 = random:table_remove(units)
|
||||
if unit_1 then
|
||||
unit_1:heal(0.2*unit_1.max_hp*(self.heal_effect_m or 1))
|
||||
unit_1.fairy_aspd_m = 3
|
||||
unit_1.t:after(5.98, function() unit_1.fairy_aspd_m = 1 end)
|
||||
end
|
||||
if unit_2 then
|
||||
unit_2:heal(0.2*unit_2.max_hp*(self.heal_effect_m or 1))
|
||||
unit_2.fairy_aspd_m = 3
|
||||
unit_2.t:after(5.98, function() unit_2.fairy_aspd_m = 1 end)
|
||||
end
|
||||
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
buff1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
else
|
||||
local unit = random:table(self:get_all_units())
|
||||
if unit then
|
||||
unit:heal(0.2*unit.max_hp*(self.heal_effect_m or 1))
|
||||
unit.fairy_aspd_m = 2
|
||||
unit.t:after(5.98, function() unit.fairy_aspd_m = 1 end)
|
||||
end
|
||||
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
buff1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
end
|
||||
end, nil, nil, 'heal')
|
||||
|
||||
elseif self.character == 'warden' then
|
||||
self.sorcerer_count = 0
|
||||
self.t:every(12, function()
|
||||
local ward = function()
|
||||
if self.level == 3 then
|
||||
local units = self:get_all_units()
|
||||
local unit_1 = random:table_remove(units)
|
||||
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}
|
||||
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}
|
||||
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}
|
||||
end
|
||||
end
|
||||
end
|
||||
ward()
|
||||
if main.current.sorcerer_level > 0 then
|
||||
self.sorcerer_count = self.sorcerer_count + 1
|
||||
if self.sorcerer_count >= ((main.current.sorcerer_level == 3 and 2) or (main.current.sorcerer_level == 2 and 3) or (main.current.sorcerer_level == 1 and 4)) then
|
||||
self.sorcerer_count = 0
|
||||
self.t:after(0.5, function()
|
||||
ward()
|
||||
end)
|
||||
end
|
||||
end
|
||||
end, nil, nil, 'buff')
|
||||
|
||||
elseif self.character == 'priest' then
|
||||
if self.level == 3 then
|
||||
self.t:after(0.01, function()
|
||||
|
@ -437,9 +637,10 @@ function Player:init(args)
|
|||
end, nil, nil, 'heal')
|
||||
|
||||
elseif self.character == 'infestor' then
|
||||
self.t:every({6, 10}, function()
|
||||
self.attack_sensor = Circle(self.x, self.y, 128)
|
||||
self.t:cooldown(6, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||
buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
||||
local enemies = main.current.main:get_objects_by_classes(main.current.enemies)
|
||||
local enemies = table.first(table.shuffle(main.current.main:get_objects_by_classes(main.current.enemies)), 8)
|
||||
for _, enemy in ipairs(enemies) do
|
||||
if self:distance_to_object(enemy) < 128 then
|
||||
enemy:curse('infestor', 6*(self.hex_duration_m or 1), (self.level == 3 and 6 or 2), self.dmg, self)
|
||||
|
@ -873,8 +1074,12 @@ end
|
|||
function Player:draw()
|
||||
graphics.push(self.x, self.y, self.r, self.hfx.hit.x*self.hfx.shoot.x, self.hfx.hit.x*self.hfx.shoot.x)
|
||||
if self.visual_shape == 'rectangle' then
|
||||
if self.magician_invulnerable then
|
||||
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 3, 3, blue_transparent)
|
||||
else
|
||||
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 3, 3, (self.hfx.hit.f or self.hfx.shoot.f) and fg[0] or self.color)
|
||||
end
|
||||
end
|
||||
graphics.pop()
|
||||
end
|
||||
|
||||
|
@ -939,6 +1144,7 @@ end
|
|||
|
||||
function Player:hit(damage)
|
||||
if self.dead then return end
|
||||
if self.magician_invulnerable then return end
|
||||
self.hfx:use('hit', 0.25, 200, 10)
|
||||
self:show_hp()
|
||||
|
||||
|
@ -1182,14 +1388,14 @@ function Player:shoot(r, mods)
|
|||
Projectile(table.merge(t, mods or {}))
|
||||
end
|
||||
|
||||
if self.character == 'vagrant' then
|
||||
if self.character == 'vagrant' or self.character == 'illusionist' then
|
||||
shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.2}
|
||||
elseif self.character == 'dual_gunner' then
|
||||
dual_gunner1:play{pitch = random:float(0.95, 1.05), volume = 0.3}
|
||||
dual_gunner2:play{pitch = random:float(0.95, 1.05), volume = 0.3}
|
||||
elseif self.character == 'archer' or self.character == 'hunter' or self.character == 'barrager' or self.character == 'corruptor' then
|
||||
archer1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
elseif self.character == 'wizard' or self.character == 'lich' or self.character == 'arcanist' or self.character == 'illusionist' then
|
||||
elseif self.character == 'wizard' or self.character == 'lich' or self.character == 'arcanist' then
|
||||
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
|
||||
elseif self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' or self.character == 'spellblade' or self.character == 'jester' or self.character == 'assassin' or self.character == 'beastmaster' then
|
||||
_G[random:table{'scout1', 'scout2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
|
@ -1226,6 +1432,8 @@ function Player:attack(area, mods)
|
|||
_G[random:table{'swordsman1', 'swordsman2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.75}
|
||||
elseif self.character == 'elementor' then
|
||||
elementor1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
||||
elseif self.character == 'psychic' then
|
||||
psychic1:play{pitch = random:float(0.9, 1.1), volume = 0.4}
|
||||
elseif self.character == 'launcher' then
|
||||
buff1:play{pitch == random:float(0.9, 1.1), volume = 0.5}
|
||||
end
|
||||
|
@ -1500,7 +1708,7 @@ function Projectile:on_collision_enter(other, contact)
|
|||
self.ricochet = self.ricochet - 1
|
||||
end
|
||||
_G[random:table{'arrow_hit_wall1', 'arrow_hit_wall2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.2}
|
||||
elseif self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' or self.character == 'spellblade' or self.character == 'jester' or self.character == 'beastmaster' then
|
||||
elseif self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' or self.character == 'spellblade' or self.character == 'jester' or self.character == 'beastmaster' or self.character == 'witch' then
|
||||
self:die(x, y, r, 0)
|
||||
knife_hit_wall1:play{pitch = random:float(0.9, 1.1), volume = 0.2}
|
||||
local r = Unit.bounce(self, nx, ny)
|
||||
|
@ -1519,7 +1727,7 @@ function Projectile:on_collision_enter(other, contact)
|
|||
self.r = r
|
||||
self.ricochet = self.ricochet - 1
|
||||
end
|
||||
elseif self.character == 'wizard' or self.character == 'lich' or self.character == 'arcanist' or self.character == 'arcanist_projectile' or self.character == 'illusionist' or self.character == 'witch' then
|
||||
elseif self.character == 'wizard' or self.character == 'lich' or self.character == 'arcanist' or self.character == 'arcanist_projectile' or self.character == 'witch' then
|
||||
self:die(x, y, r, random:int(2, 3))
|
||||
magic_area1:play{pitch = random:float(0.95, 1.05), volume = 0.075}
|
||||
elseif self.character == 'cannoneer' then
|
||||
|
@ -1574,12 +1782,12 @@ function Projectile:on_trigger_enter(other, contact)
|
|||
end
|
||||
|
||||
if self.character == 'archer' or self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' or self.character == 'hunter' or self.character == 'spellblade' or self.character == 'engineer' or
|
||||
self.character == 'jester' or self.character == 'assassin' or self.character == 'barrager' or self.character == 'beastmaster' then
|
||||
self.character == 'jester' or self.character == 'assassin' or self.character == 'barrager' or self.character == 'beastmaster' or self.character == 'witch' then
|
||||
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
if self.character == 'spellblade' then
|
||||
magic_area1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
|
||||
end
|
||||
elseif self.character == 'wizard' or self.character == 'lich' or self.character == 'arcanist' or self.character == 'illusionist' or self.character == 'illusionist_death' or self.character == 'witch' then
|
||||
elseif self.character == 'wizard' or self.character == 'lich' or self.character == 'arcanist' then
|
||||
magic_area1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
|
||||
elseif self.character == 'arcanist_projectile' then
|
||||
magic_area1:play{pitch = random:float(0.95, 1.05), volume = 0.075}
|
||||
|
@ -1702,7 +1910,7 @@ function Area:init(args)
|
|||
HitCircle{group = main.current.effects, x = enemy.x, y = enemy.y, rs = 6, color = fg[0], duration = 0.1}
|
||||
for i = 1, 1 do HitParticle{group = main.current.effects, x = enemy.x, y = enemy.y, color = self.color} end
|
||||
for i = 1, 1 do HitParticle{group = main.current.effects, x = enemy.x, y = enemy.y, color = enemy.color} end
|
||||
if self.character == 'wizard' or self.character == 'elementor' then
|
||||
if self.character == 'wizard' or self.character == 'magician' or self.character == 'elementor' or self.character == 'psychic' then
|
||||
magic_hit1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
elseif self.character == 'swordsman' or self.character == 'barbarian' or self.character == 'juggernaut' or self.character == 'highlander' then
|
||||
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
|
@ -1889,11 +2097,12 @@ function DotArea:init(args)
|
|||
self.t:every(1, function()
|
||||
local enemies = main.current.main:get_objects_in_shape(self.closest_sensor, main.current.enemies)
|
||||
if enemies and #enemies > 0 then
|
||||
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.05}
|
||||
local r = self:angle_to_object(enemies[1])
|
||||
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6}
|
||||
local t = {group = main.current.main, x = self.x, y = self.y, v = 250, r = r, color = self.parent.color, dmg = self.parent.dmg, character = 'witch', parent = self.parent, level = self.parent.level}
|
||||
Projectile(table.merge(t, mods or {}))
|
||||
_G[random:table{'scout1', 'scout2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
@ -2103,6 +2312,122 @@ end
|
|||
|
||||
|
||||
|
||||
ForceField = Object:extend()
|
||||
ForceField:implement(GameObject)
|
||||
ForceField:implement(Physics)
|
||||
function ForceField:init(args)
|
||||
self:init_game_object(args)
|
||||
self:set_as_circle(12, 'static', 'force_field')
|
||||
self.hfx:add('hit', 1)
|
||||
|
||||
self.color = fg[0]
|
||||
self.color_transparent = Color(yellow[0].r, yellow[0].g, yellow[0].b, 0.08)
|
||||
self.rs = 0
|
||||
self.hidden = false
|
||||
self.t:tween(0.05, self, {rs = args.rs}, math.cubic_in_out, function() self.spring:pull(0.15) end)
|
||||
self.t:after(0.2, function() self.color = yellow[0] end)
|
||||
|
||||
self.t:after(6, function()
|
||||
self.t:every_immediate(0.05, function() self.hidden = not self.hidden end, 7, function() self.dead = true end)
|
||||
dot1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
function ForceField:update(dt)
|
||||
self:update_game_object(dt)
|
||||
if not self.parent then self.dead = true; return end
|
||||
if self.parent and self.parent.dead then self.dead = true; return end
|
||||
self:set_position(self.parent.x, self.parent.y)
|
||||
end
|
||||
|
||||
|
||||
function ForceField:draw()
|
||||
if self.hidden then return end
|
||||
graphics.push(self.x, self.y, 0, self.spring.x*self.hfx.hit.x, self.spring.x*self.hfx.hit.x)
|
||||
graphics.circle(self.x, self.y, self.shape.rs, self.hfx.hit.f and fg[0] or self.color, 2)
|
||||
graphics.circle(self.x, self.y, self.shape.rs, self.hfx.hit.f and fg_transparent[0] or self.color_transparent)
|
||||
graphics.pop()
|
||||
end
|
||||
|
||||
|
||||
function ForceField:on_collision_enter(other, contact)
|
||||
local x, y = contact:getPositions()
|
||||
if table.any(main.current.enemies, function(v) return other:is(v) end) then
|
||||
other:push(random:float(15, 20)*(self.parent.knockback_m or 1), self.parent:angle_to_object(other))
|
||||
other:hit(0)
|
||||
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
|
||||
for i = 1, 2 do HitParticle{group = main.current.effects, x = x, y = y, color = other.color} end
|
||||
self.hfx:use('hit', 0.2)
|
||||
dot1:play{pitch = random:float(0.95, 1.05), volume = 0.3}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
Volcano = Object:extend()
|
||||
Volcano:implement(GameObject)
|
||||
Volcano:implement(Physics)
|
||||
function Volcano:init(args)
|
||||
self:init_game_object(args)
|
||||
self:set_as_rectangle(9, 9, 'static', 'player')
|
||||
self:set_restitution(0.5)
|
||||
self.hfx:add('hit', 1)
|
||||
self.color = orange[0]
|
||||
self.attack_sensor = Circle(self.x, self.y, 256)
|
||||
|
||||
self.vr = 0
|
||||
self.dvr = random:float(-math.pi/4, math.pi/4)
|
||||
|
||||
self.color = fg[0]
|
||||
self.color_transparent = Color(args.color.r, args.color.g, args.color.b, 0.08)
|
||||
self.rs = 0
|
||||
self.hidden = false
|
||||
self.t:tween(0.05, self, {rs = args.rs}, math.cubic_in_out, function() self.spring:pull(0.15) end)
|
||||
self.t:after(0.2, function() self.color = args.color end)
|
||||
|
||||
camera:shake(6, 1)
|
||||
earth1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
fire1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
self.t:every(self.level == 3 and 0.5 or 1, function()
|
||||
camera:shake(4, 0.5)
|
||||
_G[random:table{'earth1', 'earth2', 'earth3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.25}
|
||||
_G[random:table{'fire1', 'fire2', 'fire3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.25}
|
||||
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*72, r = random:float(0, 2*math.pi), color = self.color, dmg = (self.parent.area_dmg_m or 1)*self.parent.dmg,
|
||||
character = self.parent.character, level = self.parent.level, parent = self, void_rift = self.parent.void_rift, echo_barrage = self.parent.echo_barrage}
|
||||
end, self.level == 3 and 8 or 4)
|
||||
|
||||
self.t:after(4, function()
|
||||
self.t:every_immediate(0.05, function() self.hidden = not self.hidden end, 7, function() self.dead = true end)
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
function Volcano:update(dt)
|
||||
self:update_game_object(dt)
|
||||
self.vr = self.vr + self.dvr*dt
|
||||
end
|
||||
|
||||
|
||||
function Volcano:draw()
|
||||
if self.hidden then return end
|
||||
|
||||
graphics.push(self.x, self.y, math.pi/4, self.spring.x, self.spring.x)
|
||||
graphics.rectangle(self.x, self.y, 1.5*self.shape.w, 4, 2, 2, self.hfx.hit.f and fg[0] or self.color)
|
||||
graphics.rectangle(self.x, self.y, 4, 1.5*self.shape.h, 2, 2, self.hfx.hit.f and fg[0] or self.color)
|
||||
graphics.pop()
|
||||
|
||||
graphics.push(self.x, self.y, self.r + self.vr, self.spring.x, self.spring.x)
|
||||
-- graphics.circle(self.x, self.y, self.shape.rs + random:float(-1, 1), self.color, 2)
|
||||
graphics.circle(self.x, self.y, 24, self.color_transparent)
|
||||
local lw = 2
|
||||
for i = 1, 4 do graphics.arc('open', self.x, self.y, 24, (i-1)*math.pi/2 + math.pi/4 - math.pi/8, (i-1)*math.pi/2 + math.pi/4 + math.pi/8, self.color, lw) end
|
||||
graphics.pop()
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
Turret = Object:extend()
|
||||
Turret:implement(GameObject)
|
||||
|
@ -2375,12 +2700,12 @@ function Illusion:update(dt)
|
|||
self:seek_point(gw/2, gh/2)
|
||||
self:wander(50, 200, 50)
|
||||
self:rotate_towards_velocity(1)
|
||||
self:steering_separate(32, {Illusion, Seeker, Player})
|
||||
self:steering_separate(32, {Illusion, Seeker})
|
||||
else
|
||||
self:seek_point(self.target.x, self.target.y)
|
||||
self:wander(50, 200, 50)
|
||||
self:rotate_towards_velocity(1)
|
||||
self:steering_separate(32, {Illusion, Seeker, Player})
|
||||
self:steering_separate(32, {Illusion, Seeker})
|
||||
end
|
||||
self.r = self:get_angle()
|
||||
|
||||
|
|
|
@ -497,6 +497,7 @@ global_text_tags = {
|
|||
green = TextTag{draw = function(c, i, text) graphics.set_color(green[0]) end},
|
||||
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},
|
||||
blue2 = TextTag{draw = function(c, i, text) graphics.set_color(blue2[0]) end},
|
||||
bg = TextTag{draw = function(c, i, text) graphics.set_color(bg[0]) end},
|
||||
bg3 = TextTag{draw = function(c, i, text) graphics.set_color(bg[3]) end},
|
||||
bg10 = TextTag{draw = function(c, i, text) graphics.set_color(bg[10]) end},
|
||||
|
@ -508,6 +509,8 @@ global_text_tags = {
|
|||
green5 = TextTag{draw = function(c, i, text) graphics.set_color(green[5]) end},
|
||||
blue5 = TextTag{draw = function(c, i, text) graphics.set_color(blue[5]) end},
|
||||
bluem5 = TextTag{draw = function(c, i, text) graphics.set_color(blue[-5]) end},
|
||||
blue25 = TextTag{draw = function(c, i, text) graphics.set_color(blue2[5]) end},
|
||||
blue2m5 = TextTag{draw = function(c, i, text) graphics.set_color(blue2[-5]) end},
|
||||
redm5 = TextTag{draw = function(c, i, text) graphics.set_color(red[-5]) end},
|
||||
orangem5 = TextTag{draw = function(c, i, text) graphics.set_color(orange[-5]) end},
|
||||
purplem5 = TextTag{draw = function(c, i, text) graphics.set_color(purple[-5]) end},
|
||||
|
|
36
todo
36
todo
|
@ -8,7 +8,6 @@ Sorcerer update
|
|||
QoL
|
||||
Item reroll for 15 gold
|
||||
Fix highlight colors and highlight reserve
|
||||
Change cursers to trigger only near enemies
|
||||
Rename tutorial to guide or manual
|
||||
Add visuals for defensive ouroboros
|
||||
Unlock automatically on shop enter
|
||||
|
@ -23,21 +22,24 @@ Sorcerer update
|
|||
Fix lock bug after death/win - https://i.imgur.com/iUyOtLk.png
|
||||
Fix enemies still spawning after arena clear (this happens with the extra enemy spawns that were blocked earlier)
|
||||
Fix death + win at the same time bug
|
||||
Fix leader distance being off on certain speeds
|
||||
Balance
|
||||
Buff tanks, maybe add a simple forcer ability to them
|
||||
Buff 24/25 HP again
|
||||
Buff headbutter (+ trigger range)
|
||||
New
|
||||
Sorcerer = sorcerers repeat their attacks once every 4/3/2 attacks
|
||||
* New
|
||||
* Sorcerer = sorcerers repeat their attacks once every 4/3/2 attacks
|
||||
* Arcanist (tier 1 sorcerer) - launches a slow piercing orb that launches other piercing projectiles, Lv.3 effect - 50% increased attack speed for the orb and 2 projectiles are released per cast
|
||||
* Sorcerer + Conjurer = Illusionist - launches a projectile that deals X damage and creates copies that do the same, Lv.3 effect - doubles the number of copies created and they release additional projectiles on death
|
||||
* Sorcerer + Voider = Witch - creates an area that ricochets around the arena and deals X damage over time, Lv.3 effect - the area periodically releases projectiles that chains once
|
||||
Sorcerer + Curser = Silencer - curses 5 nearby enemies for 6 seconds, preventing them from using special attacks, Lv.3 effect - the curse also deals X damage over time
|
||||
Sorcerer + Nuker = Vulcanist - creates a volcano that explodes the nearby area 5 times, Lv.3 effect - the volcano spawn also deals damage and doubles the number of explosions
|
||||
Sorcerer + Forcer = Warden - creates a force field around a random unit that prevents enemies from entering, Lv.3 effect - creates the force field around 2 other random units
|
||||
Sorcerer + Psyker = Psychic - creates a small area that deals X damage, Lv.3 effect - the attack can happen from any distance and repeats twice
|
||||
* Sorcerer + Conjurer = Illusionist - launches a projectile that deals X damage and creates copies that do the same, Lv.3 effect - doubles the number of copies created and they release 12 projectiles on death that pierce and ricochet once
|
||||
* Sorcerer + Voider = Witch - creates an area that ricochets around the arena and deals X damage over time, Lv.3 effect - the area periodically releases projectiles that chain once
|
||||
* Sorcerer + Curser = Silencer - curses 6 nearby enemies for 6 seconds, preventing them from using special attacks, Lv.3 effect - the curse also deals X damage over time
|
||||
* Sorcerer + Nuker = Vulcanist - creates a volcano that explodes the nearby area 4 times, Lv.3 effect - the number and speed of explosions is doubled
|
||||
* Sorcerer + Forcer = Warden - creates a force field around a random unit that prevents enemies from entering, Lv.3 effect - creates the force field around 2 units instead
|
||||
* Sorcerer + Psyker = Psychic - creates a small area that deals X damage, Lv.3 effect - the attack can happen from any distance and repeats twice
|
||||
* Magician (tier 1 mage) - creates a small area that deals X damage, Lv.3 effect - the magician becomes invulnerable for 6 seconds
|
||||
|
||||
Sorcerer update patch notes
|
||||
Changed cursers to trigger only when near enemies
|
||||
Decreased projectile speed for the exploder (blue enemy)
|
||||
Changed shooters (white enemy) to scale with NG+ difficulty
|
||||
Increased damage and movement speed for enemy swarmers (small purple enemies)
|
||||
|
@ -47,6 +49,18 @@ Sorcerer update patch notes
|
|||
Removed cooldown visuals on snake for units that don't have cooldowns (Squire, Chronomancer and Psykeeper)
|
||||
Slightly decreased base game's difficulty
|
||||
Fixed NG+ difficulty only being able to be lowered, now you can lower or increase it (up to your maximum acquired value)
|
||||
Buffed swarmer movement speed
|
||||
Fixed a visual bug with the cleric, its cooldown was showing as faster than it actually was and thus gave the impression of not healing when it should
|
||||
Changed Corruptor to tier 4
|
||||
Changed Host to tier 3
|
||||
Changed Wizard to tier 2
|
||||
Removed Lich (will come back in future update)
|
||||
Added Magician (tier 1 mage)
|
||||
Change Outlaw to tier 2
|
||||
Added Forcer class to Sage
|
||||
Added Nuker class to Wizard
|
||||
Change Wizard's Lv.3 effect's chain to 2 (from 3)
|
||||
Fixed Blade's Lv.3 effect's damage text not being rounded
|
||||
|
||||
---
|
||||
|
||||
|
@ -55,6 +69,9 @@ Chaos related classes
|
|||
Invoker - shoots a projectile with random properties, Lv.3 effect - ???
|
||||
Trappers:
|
||||
Triangler - drops a trap and the 3rd trap will trigger the area, dealing X AoE damage 2-3 times
|
||||
Brawlers: units focused on crashing on enemies
|
||||
https://i.imgur.com/5YubukS.png - unit idea
|
||||
Hexblaster? - curser that consumes curses to deal damage
|
||||
Bench? - https://i.imgur.com/B1gNVKk.png
|
||||
Balance option for when there are more sets - https://i.imgur.com/JMynwbL.png
|
||||
Negative effect: colliding with yourself kills one of your units
|
||||
|
@ -62,6 +79,7 @@ Go through this later https://i.imgur.com/4t7NA32.png <- lots of good improvemen
|
|||
Remove level 3 units from rotation
|
||||
Hide cursor during waves
|
||||
Mouse follow control?
|
||||
Visuals for divine intervertion, fairy buff
|
||||
|
||||
Roguelite update:
|
||||
Slay the Spire-like node selection map (copy code from SHOOTRX repo as this is already implemented there)
|
||||
|
|
Loading…
Reference in New Issue