Day 55
parent
d006dd3782
commit
dd8540de54
Binary file not shown.
Binary file not shown.
18
devlog.md
18
devlog.md
|
@ -887,3 +887,21 @@ Implemented more 7 units fully. Today was slower because these were all new unit
|
|||
| Pyromancer | Ignite | enemies killed by the pyromancer explode, dealing X AoE damage |
|
||||
| Corruptor | Corruption | spawn 3 small critters if the corruptor hits an enemy |
|
||||
| Beastmaster | Call of the Wild | spawn 2 small critters if the beastmaster gets hit |
|
||||
|
||||
# Day 55 - 12/04/21
|
||||
|
||||
Even slower day today, but I managed to get something done. I'm hoping I can finish the other 9 characters tomorrow but it might go slow too...
|
||||
|
||||
| Character | Classes | Description |
|
||||
| --- | --- | --- |
|
||||
| Launcher | forcer, warrior | nearby enemies are pushed after 4 seconds, taking 2X damage on wall hit |
|
||||
| Bard | curser, rogue | throws a knife that deals X damage and inflicts enemies hit with the bard's curse |
|
||||
| Assassin | voider, rogue | throws a piercing knife that deals X damage and inflicts poison that deals X/2 damage per second for 3 seconds |
|
||||
| Host | swarmer | periodically spawn 1 small critter |
|
||||
|
||||
| Character | Lv.3 Effect Name | Lv.3 Effect Description |
|
||||
| --- | --- | --- |
|
||||
| Launcher | Kineticism | enemies launched take 300% more damage when they hit walls |
|
||||
| Bard | The Bard's Song | every 8th attack consume the curse to deal 4X damage to affected enemies |
|
||||
| Assassin | Toxic Delivery | poison inflicted from crits deals 8X damage |
|
||||
| Host | Invasion | +100% critter spawn rate and spawn 2 critters instead |
|
||||
|
|
29
enemies.lua
29
enemies.lua
|
@ -256,6 +256,7 @@ function Seeker:update(dt)
|
|||
self.being_pushed = false
|
||||
self.steering_enabled = true
|
||||
self.juggernaut_push = false
|
||||
self.launcher_push = false
|
||||
self:set_damping(0)
|
||||
self:set_angular_damping(0)
|
||||
end
|
||||
|
@ -326,6 +327,11 @@ function Seeker:on_collision_enter(other, contact)
|
|||
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
end
|
||||
|
||||
if self.launcher_push then
|
||||
self:hit(self.launcher_push)
|
||||
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
end
|
||||
|
||||
elseif table.any(main.current.enemies, function(v) return other:is(v) end) then
|
||||
if self.being_pushed and math.length(self:get_velocity()) > 60 then
|
||||
other:hit(math.floor(self.push_force/4))
|
||||
|
@ -454,6 +460,29 @@ function Seeker:slow(amount, duration)
|
|||
end
|
||||
|
||||
|
||||
function Seeker:curse(curse, duration, arg1)
|
||||
if curse == 'launcher' then
|
||||
self.t:after(duration, function()
|
||||
self.launcher_push = arg1
|
||||
self:push(random:float(50, 75), random:table{0, math.pi, math.pi/2, -math.pi/2})
|
||||
end, 'launcher_curse')
|
||||
elseif curse == 'bard' then
|
||||
self.bard_cursed = true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Seeker:apply_dot(dmg, duration)
|
||||
self.t:every(0.25, function()
|
||||
hit2:play{pitch = random:float(0.8, 1.2), volume = 0.2}
|
||||
self:hit(dmg/4)
|
||||
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = fg[0], duration = 0.1}
|
||||
for i = 1, 1 do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = self.color} end
|
||||
for i = 1, 1 do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = purple[0]} end
|
||||
end, math.floor(duration/0.2))
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
EnemyCritter = Object:extend()
|
||||
|
|
33
main.lua
33
main.lua
|
@ -19,6 +19,8 @@ function init()
|
|||
music.volume = 0
|
||||
|
||||
local s = {tags = {sfx}}
|
||||
bard2 = Sound('376532__womb-affliction__flute-trill.ogg', s)
|
||||
bard1 = Sound('Magical Impact 12.ogg', s)
|
||||
frost1 = Sound('Frost Bolt 20.ogg', s)
|
||||
pyro1 = Sound('Fire bolt 5.ogg', s)
|
||||
pyro2 = Sound('Explosion Fireworks_01.ogg', s)
|
||||
|
@ -173,7 +175,7 @@ function init()
|
|||
['pyromancer'] = red[0],
|
||||
['corruptor'] = orange[0],
|
||||
['beastmaster'] = red[0],
|
||||
['launcher'] = orange[0],
|
||||
['launcher'] = yellow[0],
|
||||
['bard'] = red[0],
|
||||
['assassin'] = purple[0],
|
||||
['host'] = orange[0],
|
||||
|
@ -217,7 +219,7 @@ function init()
|
|||
['pyromancer'] = 'red',
|
||||
['corruptor'] = 'orange',
|
||||
['beastmaster'] = 'red',
|
||||
['launcher'] = 'orange',
|
||||
['launcher'] = 'yellow',
|
||||
['bard'] = 'red',
|
||||
['assassin'] = 'purple',
|
||||
['host'] = 'orange',
|
||||
|
@ -264,7 +266,7 @@ function init()
|
|||
['launcher'] = {'curser', 'forcer'},
|
||||
['bard'] = {'curser', 'rogue'},
|
||||
['assassin'] = {'rogue', 'voider'},
|
||||
['host'] = {'conjurer', 'swarmer'},
|
||||
['host'] = {'swarmer'},
|
||||
['carver'] = {'conjurer', 'curser', 'healer'},
|
||||
['bane'] = {'curser', 'voider'},
|
||||
['psykino'] = {'mage', 'psyker', 'forcer'},
|
||||
|
@ -305,10 +307,10 @@ function init()
|
|||
['pyromancer'] = '[blue]Mage, [red]Nuker, [purple]Voider',
|
||||
['corruptor'] = '[green]Ranger, [orange]Swarmer',
|
||||
['beastmaster'] = '[red]Rogue, [orange]Swarmer',
|
||||
['launcher'] = '[purple]Curser, [yellow]Forcer',
|
||||
['launcher'] = '[yellow]Forcer, [purple]Curser',
|
||||
['bard'] = '[purple]Curser, [red]Rogue',
|
||||
['assassin'] = '[red]Rogue, [purple]Voider',
|
||||
['host'] = '[orange]Conjurer, [orange]Swarmer',
|
||||
['host'] = '[orange]Swarmer',
|
||||
['carver'] = '[orange]Conjurer, [purple]Curser, [green]Healer',
|
||||
['bane'] = '[purple]Curser, Voider',
|
||||
['psykino'] = '[blue]Mage, [fg]Psyker, [yellow]Forcer',
|
||||
|
@ -365,11 +367,11 @@ function init()
|
|||
['pyromancer'] = function(lvl) return '[fg]nearby enemies take [yellow]' .. get_character_stat('pyromancer', lvl, 'dmg') .. '[fg] damage per second' end,
|
||||
['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]nearby enemies are afflicted with a kinetic curse that triggers after [yellow]4[fg] seconds' end,
|
||||
['bard'] = function(lvl) return "[fg]shoots a projectile that inflicts enemies hit with the bard's curse" end,
|
||||
['launcher'] = function(lvl) return '[fg]nearby enemies are pushed after [yellow]4[fg] seconds, taking [yellow]' .. 2*get_character_stat('launcher', lvl, 'dmg') .. '[fg] damage on wall hit' end,
|
||||
['bard'] = function(lvl) return "[fg]throws a knife that deals [yellow]" .. get_character_stat('bard', lvl, 'dmg') .. "[fg] damage and inflicts enemies hit with the bard's curse" end,
|
||||
['assassin'] = function(lvl) return '[fg]throws a piercing knife that deals [yellow]' .. get_character_stat('assassin', lvl, 'dmg') .. '[fg] damage and inflicts poison that deals [yellow]' ..
|
||||
get_character_stat('assassin', lvl, 'dmg')/2 .. '[fg] damage per second for [yellow]4[fg] seconds' end,
|
||||
['host'] = function(lvl) return '[fg]creates [yellow]2[fg] overlords that periodically spawn small critters' end,
|
||||
get_character_stat('assassin', lvl, 'dmg')/2 .. '[fg] damage per second for [yellow]3[fg] seconds' 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 for [yellow]20%[fg] max HP in an area around it' end,
|
||||
['bane'] = function(lvl) return '[fg]creates a large area that curses enemies to take [yellow]50%[fg] increased damage over time' end,
|
||||
['psykino'] = function(lvl) return '[fg]quickly pulls enemies together and then release them with a force' end,
|
||||
|
@ -411,7 +413,7 @@ function init()
|
|||
['corruptor'] = '[orange]Corruption',
|
||||
['beastmaster'] = '[red]Call of the Wild',
|
||||
['launcher'] = '[orange]Kineticism',
|
||||
['bard'] = "[orange]The Bard's Song",
|
||||
['bard'] = "[red]The Bard's Song",
|
||||
['assassin'] = '[purple]Toxic Delivery',
|
||||
['host'] = '[orange]Invasion',
|
||||
['carver'] = '[green]World Tree',
|
||||
|
@ -498,10 +500,10 @@ function init()
|
|||
['pyromancer'] = function() return '[fg]enemies killed by the pyromancer explode, dealing [yellow]' .. get_character_stat('pyromancer', 3, 'dmg') .. '[fg] AoE damage' end,
|
||||
['corruptor'] = function() return '[fg]spawn [yellow]3[fg] small critters if the corruptor hits an enemy' end,
|
||||
['beastmaster'] = function() return '[fg]spawn [yellow]2[fg] small critters if the beastmaster gets hit' end,
|
||||
['launcher'] = function() return '[fg]enemies launched that hit other enemies push those enemies at double the force they were pushed' end,
|
||||
['bard'] = function() return '[fg] every 5th attack consume the curse to deal [yellow]' .. 3*get_character_stat('bard', 3, 'dmg') .. '[fg] damage to affected enemies' end,
|
||||
['launcher'] = function() return '[fg]enemies launched take [yellow]300%[fg] more damage when they hit walls' end,
|
||||
['bard'] = function() return '[fg]every 8th attack consume the curse to deal [yellow]' .. 4*get_character_stat('bard', 3, 'dmg') .. '[fg] damage to affected enemies' end,
|
||||
['assassin'] = function() return '[fg]poison inflicted from crits deals [yellow]8x[fg] damage' end,
|
||||
['host'] = function() return '[fg][yellow]+50%[fg] critter spawn rate' end,
|
||||
['host'] = function() return '[fg][yellow]+100%[fg] critter spawn rate and spawn [yellow]2[fg] critters instead' end,
|
||||
['carver'] = function() return '[fg]carves a tree that heals in a bigger area and removes all buffs from enemies' end,
|
||||
['bane'] = function() return '[fg]the area also deals [yellow]' .. get_character_stat('bane', 3, 'dmg') .. '[fg] damage per second and slows enemies by [yellow]50%[fg]' end,
|
||||
['psykino'] = function() return '[fg]enemies pulled together are forced to collide with each other multiple times' end,
|
||||
|
@ -575,6 +577,7 @@ function init()
|
|||
['mini_boss'] = {hp = 1, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 0.3},
|
||||
['enemy_critter'] = {hp = 1, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 0.5},
|
||||
['saboteur'] = {hp = 1, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 1.4},
|
||||
['overlord'] = {hp = 1.5, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 0.5},
|
||||
}
|
||||
|
||||
local ylb1 = function(lvl) return lvl >= 2 and 'fg' or (lvl >= 1 and 'yellow' or 'light_bg') end
|
||||
|
@ -806,9 +809,7 @@ function init()
|
|||
main = Main()
|
||||
main:add(BuyScreen'buy_screen')
|
||||
main:go_to('buy_screen', 22, {
|
||||
{character = 'beastmaster', level = 3},
|
||||
{character = 'scout', level = 3},
|
||||
{character = 'outlaw', level = 3},
|
||||
{character = 'host', level = 3},
|
||||
})
|
||||
--[[
|
||||
main:add(Arena'arena')
|
||||
|
|
|
@ -250,6 +250,10 @@ function Unit:calculate_stats(first_run)
|
|||
self.base_hp = 25 + 30*y[x]
|
||||
self.base_dmg = 10 + 3*y[x]
|
||||
self.base_mvspd = 60 + 3*y[x]
|
||||
elseif self:is(Overlord) then
|
||||
self.base_hp = 50*math.pow(2, self.level-1)
|
||||
self.base_dmg = 10*math.pow(2, self.level-1)
|
||||
self.base_mvspd = 40
|
||||
end
|
||||
self.base_aspd_m = 1
|
||||
self.base_area_dmg_m = 1
|
||||
|
|
225
player.lua
225
player.lua
|
@ -6,12 +6,12 @@ function Player:init(args)
|
|||
self:init_game_object(args)
|
||||
self:init_unit()
|
||||
|
||||
if self.character == 'vagrant' then
|
||||
self.color = character_colors.vagrant
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.vagrant
|
||||
self.color = character_colors[self.character]
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes[self.character]
|
||||
|
||||
if self.character == 'vagrant' 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 closest_enemy = self:get_closest_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||
|
@ -21,22 +21,12 @@ function Player:init(args)
|
|||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'swordsman' then
|
||||
self.color = character_colors.swordsman
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.swordsman
|
||||
|
||||
self.attack_sensor = Circle(self.x, self.y, 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()
|
||||
self:attack(96)
|
||||
end, nil, nil, 'attack')
|
||||
|
||||
elseif self.character == 'wizard' then
|
||||
self.color = character_colors.wizard
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.wizard
|
||||
|
||||
self.attack_sensor = Circle(self.x, self.y, 128)
|
||||
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)
|
||||
|
@ -46,11 +36,6 @@ function Player:init(args)
|
|||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'archer' then
|
||||
self.color = character_colors.archer
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.archer
|
||||
|
||||
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()
|
||||
local closest_enemy = self:get_closest_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||
|
@ -60,11 +45,6 @@ function Player:init(args)
|
|||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'scout' then
|
||||
self.color = character_colors.scout
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.scout
|
||||
|
||||
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()
|
||||
local closest_enemy = self:get_closest_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||
|
@ -74,11 +54,6 @@ function Player:init(args)
|
|||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'cleric' then
|
||||
self.color = character_colors.cleric
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.cleric
|
||||
|
||||
self.last_heal_time = love.timer.getTime()
|
||||
self.t:every(2, function()
|
||||
local all_units = self:get_all_units()
|
||||
|
@ -96,11 +71,6 @@ function Player:init(args)
|
|||
end)
|
||||
|
||||
elseif self.character == 'outlaw' then
|
||||
self.color = character_colors.outlaw
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.outlaw
|
||||
|
||||
self.attack_sensor = Circle(self.x, self.y, 96)
|
||||
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)
|
||||
|
@ -110,22 +80,12 @@ function Player:init(args)
|
|||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'blade' then
|
||||
self.color = character_colors.blade
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.blade
|
||||
|
||||
self.attack_sensor = Circle(self.x, self.y, 64)
|
||||
self.t:cooldown(4, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||
self:shoot()
|
||||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'elementor' then
|
||||
self.color = character_colors.elementor
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.elementor
|
||||
|
||||
self.attack_sensor = Circle(self.x, self.y, 128)
|
||||
self.t:cooldown(7, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||
local enemy = self:get_random_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||
|
@ -135,11 +95,6 @@ function Player:init(args)
|
|||
end, nil, nil, 'attack')
|
||||
|
||||
elseif self.character == 'saboteur' then
|
||||
self.color = character_colors.saboteur
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.saboteur
|
||||
|
||||
self.t:every(8, function()
|
||||
self.t:every(0.25, function()
|
||||
SpawnEffect{group = main.current.effects, x = self.x, y = self.y, action = function(x, y)
|
||||
|
@ -149,11 +104,6 @@ function Player:init(args)
|
|||
end)
|
||||
|
||||
elseif self.character == 'stormweaver' then
|
||||
self.color = character_colors.stormweaver
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.stormweaver
|
||||
|
||||
self.t:every(8, function()
|
||||
stormweaver1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
local units = self:get_all_units()
|
||||
|
@ -163,11 +113,6 @@ function Player:init(args)
|
|||
end)
|
||||
|
||||
elseif self.character == 'sage' then
|
||||
self.color = character_colors.sage
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.sage
|
||||
|
||||
self.attack_sensor = Circle(self.x, self.y, 96)
|
||||
self.t:cooldown(12, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||
local closest_enemy = self:get_closest_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||
|
@ -176,18 +121,7 @@ function Player:init(args)
|
|||
end
|
||||
end)
|
||||
|
||||
elseif self.character == 'squire' then
|
||||
self.color = character_colors.squire
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.squire
|
||||
|
||||
elseif self.character == 'cannoneer' then
|
||||
self.color = character_colors.cannoneer
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.cannoneer
|
||||
|
||||
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()
|
||||
local closest_enemy = self:get_closest_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||
|
@ -197,11 +131,6 @@ function Player:init(args)
|
|||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'dual_gunner' then
|
||||
self.color = character_colors.dual_gunner
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.dual_gunner
|
||||
|
||||
self.dg_counter = 0
|
||||
self.attack_sensor = Circle(self.x, self.y, 96)
|
||||
self.gun_kata_sensor = Circle(self.x, self.y, 160)
|
||||
|
@ -213,11 +142,6 @@ function Player:init(args)
|
|||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'hunter' then
|
||||
self.color = character_colors.hunter
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.hunter
|
||||
|
||||
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()
|
||||
local closest_enemy = self:get_closest_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||
|
@ -227,39 +151,20 @@ function Player:init(args)
|
|||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'chronomancer' then
|
||||
self.color = character_colors.chronomancer
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.chronomancer
|
||||
|
||||
if self.level == 3 then
|
||||
main.current.chronomancer_dot = 0.5
|
||||
end
|
||||
|
||||
elseif self.character == 'spellblade' then
|
||||
self.color = character_colors.spellblade
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.spellblade
|
||||
|
||||
self.t:every(2, function()
|
||||
self:shoot(random:float(0, 2*math.pi))
|
||||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'psykeeper' then
|
||||
self.color = character_colors.psykeeper
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.psykeeper
|
||||
self.stored_heal = 0
|
||||
self.last_heal_time = love.timer.getTime()
|
||||
|
||||
elseif self.character == 'engineer' then
|
||||
self.color = character_colors.engineer
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.engineer
|
||||
|
||||
self.turret_counter = 0
|
||||
self.t:every(8, function()
|
||||
SpawnEffect{group = main.current.effects, x = self.x, y = self.y, color = orange[0], action = function(x, y)
|
||||
|
@ -279,11 +184,6 @@ function Player:init(args)
|
|||
end)
|
||||
|
||||
elseif self.character == 'plague_doctor' then
|
||||
self.color = character_colors.plague_doctor
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.plague_doctor
|
||||
|
||||
self.t:every(5, function()
|
||||
self:dot_attack(24, {duration = 12})
|
||||
end)
|
||||
|
@ -295,31 +195,16 @@ function Player:init(args)
|
|||
end
|
||||
|
||||
elseif self.character == 'barbarian' then
|
||||
self.color = character_colors.barbarian
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.barbarian
|
||||
|
||||
self.t:every(8, function()
|
||||
self:attack(96, {stun = 4})
|
||||
end)
|
||||
|
||||
elseif self.character == 'juggernaut' then
|
||||
self.color = character_colors.juggernaut
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.juggernaut
|
||||
|
||||
self.t:every(8, function()
|
||||
self:attack(64, {juggernaut_push = true})
|
||||
end)
|
||||
|
||||
elseif self.character == 'lich' then
|
||||
self.color = character_colors.lich
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.lich
|
||||
|
||||
self.attack_sensor = Circle(self.x, self.y, 128)
|
||||
self.t:cooldown(4, 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)
|
||||
|
@ -329,31 +214,16 @@ function Player:init(args)
|
|||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'cryomancer' then
|
||||
self.color = character_colors.cryomancer
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.cryomancer
|
||||
|
||||
self.t:after(0.01, function()
|
||||
self.dot_area = DotArea{group = main.current.effects, x = self.x, y = self.y, rs = self.area_size_m*48, color = self.color, dmg = self.area_dmg_m*self.dmg, character = self.character, level = self.level, parent = self}
|
||||
end)
|
||||
|
||||
elseif self.character == 'pyromancer' then
|
||||
self.color = character_colors.pyromancer
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.pyromancer
|
||||
|
||||
self.t:after(0.01, function()
|
||||
self.dot_area = DotArea{group = main.current.effects, x = self.x, y = self.y, rs = self.area_size_m*48, color = self.color, dmg = self.area_dmg_m*self.dmg, character = self.character, level = self.level, parent = self}
|
||||
end)
|
||||
|
||||
elseif self.character == 'corruptor' then
|
||||
self.color = character_colors.corruptor
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.corruptor
|
||||
|
||||
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()
|
||||
local closest_enemy = self:get_closest_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||
|
@ -363,11 +233,6 @@ function Player:init(args)
|
|||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'beastmaster' then
|
||||
self.color = character_colors.beastmaster
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.beastmaster
|
||||
|
||||
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()
|
||||
local closest_enemy = self:get_closest_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||
|
@ -375,6 +240,45 @@ function Player:init(args)
|
|||
self:shoot(self:angle_to_object(closest_enemy), {spawn_critters_on_crit = 2})
|
||||
end
|
||||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'launcher' then
|
||||
self.t:every(8, function()
|
||||
self:attack(128)
|
||||
end)
|
||||
|
||||
elseif self.character == 'bard' then
|
||||
self.bard_counter = 0
|
||||
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()
|
||||
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))
|
||||
end
|
||||
end, nil, nil, 'shoot')
|
||||
|
||||
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()
|
||||
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})
|
||||
end
|
||||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'host' then
|
||||
if self.level == 3 then
|
||||
self.t:every(1, function()
|
||||
critter1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
for i = 1, 2 do
|
||||
Critter{group = main.current.main, x = self.x, y = self.y, color = orange[0], r = random:float(0, 2*math.pi), v = 10, dmg = self.dmg, parent = self}
|
||||
end
|
||||
end)
|
||||
else
|
||||
self.t:every(2, function()
|
||||
critter1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
Critter{group = main.current.main, x = self.x, y = self.y, color = orange[0], r = random:float(0, 2*math.pi), v = 10, dmg = self.dmg, parent = self}
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
self:calculate_stats(true)
|
||||
|
@ -598,7 +502,7 @@ function Player:hit(damage)
|
|||
critter1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
trigger:after(0.01, function()
|
||||
for i = 1, 2 do
|
||||
Critter{group = main.current.main, x = self.x, y = self.y, color = orange[0], r = random:float(0, 2*math.pi), v = 20, dmg = self.dmg}
|
||||
Critter{group = main.current.main, x = self.x, y = self.y, color = orange[0], r = random:float(0, 2*math.pi), v = 20, dmg = self.dmg, parent = self}
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
@ -721,13 +625,12 @@ function Player:shoot(r, mods)
|
|||
local dmg_m = 1
|
||||
local crit = false
|
||||
if self.chance_to_crit and random:bool(self.chance_to_crit) then dmg_m = 4; crit = true end
|
||||
print(crit, mods.spawn_critters_on_crit, self.chance_to_crit)
|
||||
|
||||
if crit and mods.spawn_critters_on_crit then
|
||||
critter1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
trigger:after(0.01, function()
|
||||
for i = 1, mods.spawn_critters_on_crit do
|
||||
Critter{group = main.current.main, x = self.x, y = self.y, color = orange[0], r = random:float(0, 2*math.pi), v = 10, dmg = self.dmg}
|
||||
Critter{group = main.current.main, x = self.x, y = self.y, color = orange[0], r = random:float(0, 2*math.pi), v = 10, dmg = self.dmg, parent = self}
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
@ -793,6 +696,22 @@ function Player:shoot(r, mods)
|
|||
Projectile(table.merge(t, mods or {}))
|
||||
end
|
||||
|
||||
if self.character == 'bard' then
|
||||
self.bard_counter = self.bard_counter + 1
|
||||
if self.bard_counter == 8 then
|
||||
self.bard_counter = 0
|
||||
bard2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
self.t:after(3, function()
|
||||
bard1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
local enemies = main.current.main:get_objects_by_classes(main.current.enemies)
|
||||
for _, enemy in ipairs(enemies) do
|
||||
enemy:hit(4*self.dmg)
|
||||
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.2}
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
if self.character == 'vagrant' then
|
||||
shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.2}
|
||||
elseif self.character == 'dual_gunner' then
|
||||
|
@ -802,7 +721,7 @@ function Player:shoot(r, mods)
|
|||
archer1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
elseif self.character == 'wizard' or self.character == 'lich' 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' then
|
||||
elseif self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' or self.character == 'spellblade' or self.character == 'bard' or self.character == 'assassin' then
|
||||
_G[random:table{'scout1', 'scout2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
if self.character == 'spellblade' then
|
||||
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
|
||||
|
@ -833,6 +752,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 == 'launcher' then
|
||||
buff1:play{pitch == random:float(0.9, 1.1), volume = 0.5}
|
||||
end
|
||||
|
||||
if self.character == 'juggernaut' then
|
||||
|
@ -1046,7 +967,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' then
|
||||
elseif self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' or self.character == 'spellblade' or self.character == 'bard' 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)
|
||||
|
@ -1107,7 +1028,8 @@ function Projectile:on_trigger_enter(other, contact)
|
|||
HitParticle{group = main.current.effects, x = self.x, y = self.y, color = other.color}
|
||||
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' then
|
||||
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 == 'bard' or self.character == 'assassin' 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}
|
||||
|
@ -1141,6 +1063,14 @@ function Projectile:on_trigger_enter(other, contact)
|
|||
end)
|
||||
end
|
||||
|
||||
if self.character == 'bard' then
|
||||
other:curse('bard')
|
||||
end
|
||||
|
||||
if self.character == 'assassin' then
|
||||
other:apply_dot(self.crit and 4*self.dmg or self.dmg/2, 3)
|
||||
end
|
||||
|
||||
if self.parent.chain_infused then
|
||||
local units = self.parent:get_all_units()
|
||||
local stormweaver_level = 0
|
||||
|
@ -1193,6 +1123,8 @@ function Area:init(args)
|
|||
enemy:hit(self.dmg + self.dmg*0.33*#enemies)
|
||||
elseif self.character == 'blade' and self.level == 3 then
|
||||
enemy:hit(self.dmg + self.dmg*0.5*#enemies)
|
||||
elseif self.character == 'launcher' then
|
||||
enemy:curse('launcher', 4, (self.level == 3 and 6*self.dmg or 2*self.dmg))
|
||||
else
|
||||
enemy:hit(self.dmg)
|
||||
end
|
||||
|
@ -1577,6 +1509,7 @@ function Critter:init(args)
|
|||
self.invulnerable = true
|
||||
self.t:after(0.5, function() self.invulnerable = false end)
|
||||
|
||||
self.dmg = self.parent.dmg
|
||||
self.hp = 1
|
||||
end
|
||||
|
||||
|
|
10
todo
10
todo
|
@ -68,12 +68,12 @@
|
|||
* Pyromancer [mage, nuker, voider]: nearby enemies take damage over time and deal decreased damage - Lv.3: Ignite - enemies killed by the pyromancer explode, dealing AoE damage
|
||||
* Corruptor [ranger, swarmer]: spawn 3 small critters if the corruptor kills an enemy - Lv.3: Corruption - spawn 3 small critters if the corruptor hits an enemy
|
||||
* Beastmaster [rogue, swarmer]: spawn 2 small critters if the beastmaster crits - Lv.3: Call of the Wild - spawn 2 small critters if the beastmaster gets hit
|
||||
Launcher [curser, forcer]: curses nearby enemies with a kinetic curse that triggers after 4 seconds - Lv.3: Kineticism - enemies launched that hit other enemies transfer their kinetic energy at double value
|
||||
Bard [curser, rogue]: shoots a projectile that inflicts enemies hit with the bard's curse - Lv.3: The Bard's Song - every 5th attack consume the curse to deal massive damage to enemies affected
|
||||
Assassin [rogue, voider]: throws a piercing knife that inflicts poison - Lv.3: Toxic Delivery - poison inflicted from crits deals more damage
|
||||
Host [conjurer, swarmer]: creates overlords that periodically spawn small critters - Lv.3: Invasion - increased critter spawn rate
|
||||
* Launcher [curser, forcer]: curses nearby enemies with a kinetic curse that triggers after 4 seconds - Lv.3: Kineticism - enemies launched that hit other enemies transfer their kinetic energy at double value
|
||||
* Bard [curser, rogue]: shoots a projectile that inflicts enemies hit with the bard's curse - Lv.3: The Bard's Song - every 5th attack consume the curse to deal massive damage to enemies affected
|
||||
* Assassin [rogue, voider]: throws a piercing knife that inflicts poison - Lv.3: Toxic Delivery - poison inflicted from crits deals more damage
|
||||
* Host [swarmer]: creates overlords that periodically spawn small critters - Lv.3: Invasion - increased critter spawn rate
|
||||
Carver [conjurer, curser, healer]: carves a statue that periodically heals in an area - Lv.3: World Tree - carves a tree that heals in a bigger area and removes all buffs from enemies
|
||||
Bane [curser, voider]: creates a large area that curses enemies to take increased DoT - Lv.3: Nightmare - the area also deals DoT and slows enemies
|
||||
Bane [curser, voider]: creates a large area that curses enemies to take increased damage - Lv.3: Nightmare - the area also deals DoT and slows enemies
|
||||
Psykino [mage, psyker, forcer]: quickly pulls enemies together and then releases them with a force - Lv.3: Magnetic Force - enemies pulled together are forced to collide with each other before being released
|
||||
Arbalester [ranger, forcer]: launches a massive arrow that pushes enemies back, ignoring knockback resistances - Lv.3: Ballista Sinistra - enemies hit by the arrow have massively decreased defense
|
||||
Highlander [warrior]: creates a small area that deals massive damage - Lv.3: Crosscut - two crosscutting areas of larger size are created instead
|
||||
|
|
Loading…
Reference in New Issue