Day 53
parent
1b7c4da414
commit
f3c1475e37
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
33
devlog.md
33
devlog.md
|
@ -830,3 +830,36 @@ Lots of improvements and fixes to lots of different things that needed improving
|
|||
| Blade | Blade Resonance | deal additional X/2 damage per enemy hit |
|
||||
| Elementor | Windfield | slows enemies by 60% for 6 seconds on hit |
|
||||
| Saboteur | Demoman | the explosion has 50% chance to crit, increasing in size and dealing 2X damage |
|
||||
|
||||
# Day 53 - 10/04/21
|
||||
|
||||
Implemented 11 characters today and was going to do more but spent a lot of time trying to make traps work and I couldn't figure it out. Have to idea guy a mechanic other than traps to fill their spot now...
|
||||
Either way, 21 out of 40 characters 100% done is still good.
|
||||
|
||||
| Character | Classes | Description |
|
||||
| --- | --- | --- |
|
||||
| Stormweaver | enchanter | infuses projectiles with chain lightning that deals 20% damage to 2 enemies |
|
||||
| Sage | nuker | shoots a slow projectile that pulls enemies in |
|
||||
| Squire | warrior, enchanter | +15% damage and defense to all allies |
|
||||
| Cannoneer | ranger, nuker | shoots a projectile that deals 2X AoE damage |
|
||||
| Dual Gunner | ranger, rogue | shoots two parallel projectiles, each dealing X damage |
|
||||
| Hunter | ranger, conjurer | shoots an arrow that deals X damage and has a 20% chance to summon a pet |
|
||||
| Chronomancer | mage, enchanter | +20% attack speed to all allies |
|
||||
| Spellblade | mage, rogue | throws knives that deal X damage, pierce and spiral outwards |
|
||||
| Psykeeper | healer, psyker | all damage taken is stored up to 50% max HP and distributed as healing to all allies |
|
||||
| Engineer | conjurer | drops sentries that shoot bursts of projectiles, each dealing X damage |
|
||||
| Plague Doctor | nuker, voider | creates an area that deals X damage per second |
|
||||
|
||||
| Character | Lv.3 Effect Name | Lv.3 Effect Description |
|
||||
| --- | --- | --- |
|
||||
| Stormweaver | Wide Lightning | chain lightning's trigger area of effect and number of units hit is doubled |
|
||||
| Sage | Dimension Compression | when the projectile expires deal 3X damage to all enemies under its influence |
|
||||
| Squire | Repair | you can reroll your item choices once, these opportunities stack if unused |
|
||||
| Cannoneer | Cannon Barrage | showers the area in 5 additional cannon shots that deal X/2 AoE damage |
|
||||
| Dual Gunner | Gun Kata | every 5th attack shoots in rapid succession for 2 seconds |
|
||||
| Hunter | Feral Pack | summons 3 pets and the pets ricochet off walls once |
|
||||
| Chronomancer | Quicken | enemies take damage over time 50% faster |
|
||||
| Spellblade | Spiralism | faster projectile speed and tighter turns |
|
||||
| Psykeeper | Crucio | also redistributes damage taken as damage to all enemies at double value |
|
||||
| Engineer | Upgrade | every 3rd sentry dropped upgrade all sentries with +100% damage and attack speed |
|
||||
| Plague Doctor | Black Death Steam | nearby enemies take an additional X damage per second |
|
||||
|
|
71
main.lua
71
main.lua
|
@ -19,6 +19,11 @@ function init()
|
|||
music.volume = 0
|
||||
|
||||
local s = {tags = {sfx}}
|
||||
dot1 = Sound('Magical Swoosh 18.ogg', s)
|
||||
gun_kata1 = Sound('Pistol Shot_07.ogg', s)
|
||||
gun_kata2 = Sound('Pistol Shot_08.ogg', s)
|
||||
dual_gunner1 = Sound('Revolver Shot_07.ogg', s)
|
||||
dual_gunner2 = Sound('Revolver Shot_08.ogg', s)
|
||||
ui_hover1 = Sound('bamboo_hit_by_lord.ogg', s)
|
||||
ui_switch1 = Sound('Switch.ogg', s)
|
||||
ui_switch2 = Sound('Switch 3.ogg', s)
|
||||
|
@ -148,7 +153,7 @@ function init()
|
|||
['elementor'] = blue[0],
|
||||
['saboteur'] = orange[0],
|
||||
['stormweaver'] = blue[0],
|
||||
['sage'] = red[0],
|
||||
['sage'] = purple[0],
|
||||
['squire'] = yellow[0],
|
||||
['cannoneer'] = orange[0],
|
||||
['dual_gunner'] = green[0],
|
||||
|
@ -177,7 +182,7 @@ function init()
|
|||
['sapper'] = blue[0],
|
||||
['priest'] = green[0],
|
||||
['burrower'] = orange[0],
|
||||
['flagellant'] = red[0],
|
||||
['flagellant'] = fg[0],
|
||||
}
|
||||
|
||||
character_color_strings = {
|
||||
|
@ -192,7 +197,7 @@ function init()
|
|||
['elementor'] = 'blue',
|
||||
['saboteur'] = 'orange',
|
||||
['stormweaver'] = 'blue',
|
||||
['sage'] = 'red',
|
||||
['sage'] = 'purple',
|
||||
['squire'] = 'yellow',
|
||||
['cannoneer'] = 'orange',
|
||||
['dual_gunner'] = 'green',
|
||||
|
@ -221,7 +226,7 @@ function init()
|
|||
['sapper'] = 'blue',
|
||||
['priest'] = 'green',
|
||||
['burrower'] = 'orange',
|
||||
['flagellant'] = 'red',
|
||||
['flagellant'] = 'fg',
|
||||
}
|
||||
|
||||
character_classes = {
|
||||
|
@ -314,17 +319,17 @@ function init()
|
|||
|
||||
get_character_stat_string = function(character, level)
|
||||
local group = Group():set_as_physics_world(32, 0, 0, {'player', 'enemy', 'projectile', 'enemy_projectile'})
|
||||
local mock = Player{group = group, leader = true, character = character, level = level, follower_index = 1}
|
||||
mock:update(0)
|
||||
return '[red]HP: [red]' .. mock.max_hp .. '[fg], [red]DMG: [red]' .. mock.dmg .. '[fg], [green]ASPD: [green]' .. math.round(mock.aspd_m, 2) .. 'x[fg], [blue]AREA: [blue]' ..
|
||||
math.round(mock.area_dmg_m*mock.area_size_m, 2) .. 'x[fg], [yellow]DEF: [yellow]' .. math.round(mock.def, 2) .. '[fg], [green]MVSPD: [green]' .. math.round(mock.v, 2) .. '[fg]'
|
||||
local player = Player{group = group, leader = true, character = character, level = level, follower_index = 1}
|
||||
player:update(0)
|
||||
return '[red]HP: [red]' .. player.max_hp .. '[fg], [red]DMG: [red]' .. player.dmg .. '[fg], [green]ASPD: [green]' .. math.round(player.aspd_m, 2) .. 'x[fg], [blue]AREA: [blue]' ..
|
||||
math.round(player.area_dmg_m*player.area_size_m, 2) .. 'x[fg], [yellow]DEF: [yellow]' .. math.round(player.def, 2) .. '[fg], [green]MVSPD: [green]' .. math.round(player.v, 2) .. '[fg]'
|
||||
end
|
||||
|
||||
get_character_stat = function(character, level, stat)
|
||||
local group = Group():set_as_physics_world(32, 0, 0, {'player', 'enemy', 'projectile', 'enemy_projectile'})
|
||||
local mock = Player{group = group, leader = true, character = character, level = level, follower_index = 1}
|
||||
mock:update(0)
|
||||
return math.round(mock[stat], 2)
|
||||
local player = Player{group = group, leader = true, character = character, level = level, follower_index = 1}
|
||||
player:update(0)
|
||||
return math.round(player[stat], 2)
|
||||
end
|
||||
|
||||
character_descriptions = {
|
||||
|
@ -339,18 +344,18 @@ function init()
|
|||
['blade'] = function(lvl) return '[fg]throws multiple blades that deal [yellow]' .. get_character_stat('blade', lvl, 'dmg') .. ' AoE[fg] damage' end,
|
||||
['elementor'] = function(lvl) return '[fg]deals [yellow]' .. get_character_stat('elementor', lvl, 'dmg') .. ' AoE[fg] damage in a large area centered on a random target' end,
|
||||
['saboteur'] = function(lvl) return '[fg]calls [yellow]2[fg] saboteurs to seek targets and deal [yellow]' .. get_character_stat('saboteur', lvl, 'dmg') .. ' AoE[fg] damage' end,
|
||||
['stormweaver'] = function(lvl) return '[fg]infuses all allied projectiles with chain lightning that deals [yellow]+20%[fg] damage on hit' end,
|
||||
['stormweaver'] = function(lvl) return '[fg]infuses projectiles with chain lightning that deals [yellow]20%[fg] damage to [yellow]2[fg] enemies' end,
|
||||
['sage'] = function(lvl) return '[fg]shoots a slow projectile that draws enemies in' end,
|
||||
['squire'] = function(lvl) return '[yellow]+10%[fg] damage and defense to all allies' end,
|
||||
['cannoneer'] = function(lvl) return '[fg]shoots a projectile that deals [yellow]' .. get_character_stat('cannoneer', lvl, 'dmg') .. ' AoE[fg] damage' end,
|
||||
['dual_gunner'] = function(lvl) return '[fg]shoots two parallel projectiles' end,
|
||||
['squire'] = function(lvl) return '[yellow]+15%[fg] damage and defense to all allies' end,
|
||||
['cannoneer'] = function(lvl) return '[fg]shoots a projectile that deals [yellow]' .. 2*get_character_stat('cannoneer', lvl, 'dmg') .. ' AoE[fg] damage' end,
|
||||
['dual_gunner'] = function(lvl) return '[fg]shoots two parallel projectiles, each dealing [yellow]' .. get_character_stat('dual_gunner', lvl, 'dmg') .. '[fg] damage' end,
|
||||
['hunter'] = function(lvl) return '[fg]shoots an arrow that deals [yellow]' .. get_character_stat('hunter', lvl, 'dmg') .. '[fg] damage and has a [yellow]20%[fg] chance to summon a pet' end,
|
||||
['chronomancer'] = function(lvl) return '[yellow]+20%[fg] attack speed to all allies' end,
|
||||
['spellblade'] = function(lvl) return '[fg]throws knives that deal [yellow]' .. get_character_stat('spellblade', lvl, 'dmg') .. '[fg] damage, pierce and spiral outwards' end,
|
||||
['psykeeper'] = function(lvl) return '[fg]all damage taken is stored up to [yellow]50%[fg] max HP and distributed as healing to all allies' end,
|
||||
['engineer'] = function(lvl) return '[fg]drops sentries that shoot bursts of projectiles, each dealing [yellow]' .. get_character_stat('engineer', lvl, 'dmg') .. '[fg] damage' end,
|
||||
['plague_doctor'] = function(lvl) return '[fg]creates an area that deals [yellow]' .. get_character_stat('plague_doctor', lvl, 'dmg') .. '[fg] damage per second' end,
|
||||
['fisherman'] = function(lvl) return '[fg]throws a net that entangles enemies and prevents them from moving for [yellow]2[fg] seconds' end,
|
||||
['fisherman'] = function(lvl) return '[fg]throws a net that entangles enemies and prevents them from moving for [yellow]4[fg] seconds' end,
|
||||
['juggernaut'] = function(lvl) return '[fg]creates a small area that deals [yellow]' .. get_character_stat('juggernaut', lvl, 'dmg') .. '[fg] damage and pushes enemies away with a strong force' end,
|
||||
['lich'] = function(lvl) return '[fg]launches a chain frost that jumps [yellow]7[fg] times, dealing [yellow]' ..
|
||||
get_character_stat('lich', lvl, 'dmg') .. '[fg] damage and slowing enemies by [yellow]50%[fg] for [yellow]2[fg] seconds on hit' end,
|
||||
|
@ -385,7 +390,7 @@ function init()
|
|||
['blade'] = '[yellow]Blade Resonance',
|
||||
['elementor'] = '[blue]Windfield',
|
||||
['saboteur'] = '[orange]Demoman',
|
||||
['stormweaver'] = '[blue]Lightning Spire',
|
||||
['stormweaver'] = '[blue]Wide Lightning',
|
||||
['sage'] = '[purple]Dimension Compression',
|
||||
['squire'] = '[yellow]Repair',
|
||||
['cannoneer'] = '[orange]Cannon Barrage',
|
||||
|
@ -395,7 +400,7 @@ function init()
|
|||
['spellblade'] = '[blue]Spiralism',
|
||||
['psykeeper'] = '[fg]Crucio',
|
||||
['engineer'] = '[orange]Upgrade',
|
||||
['plague_doctor'] = '[purple]Pandemic',
|
||||
['plague_doctor'] = '[purple]Black Death Steam',
|
||||
['fisherman'] = '[yellow]Electric Net',
|
||||
['juggernaut'] = '[yellow]Brutal Impact',
|
||||
['lich'] = '[blue]Piercing Frost',
|
||||
|
@ -423,13 +428,13 @@ function init()
|
|||
['swordsman'] = '[light_bg]Cleave',
|
||||
['wizard'] = '[light_bg]Magic Missile',
|
||||
['archer'] = '[light_bg]Bounce Shot',
|
||||
['scout'] = '[light_bg]Replica',
|
||||
['scout'] = '[light_bg]Dagger Resonance',
|
||||
['cleric'] = '[light_bg]Mass Heal ',
|
||||
['outlaw'] = '[light_bg]Fatal Roulette',
|
||||
['outlaw'] = '[light_bg]Flying Daggers',
|
||||
['blade'] = '[light_bg]Blade Resonance',
|
||||
['elementor'] = '[light_bg]Windfield',
|
||||
['saboteur'] = '[light_bg]Chain Reaction',
|
||||
['stormweaver'] = '[light_bg]Lightning Spire',
|
||||
['saboteur'] = '[light_bg]Demoman',
|
||||
['stormweaver'] = '[light_bg]Wide Lightning',
|
||||
['sage'] = '[light_bg]Dimension Compression',
|
||||
['squire'] = '[light_bg]Repair',
|
||||
['cannoneer'] = '[light_bg]Cannon Barrage',
|
||||
|
@ -439,7 +444,7 @@ function init()
|
|||
['spellblade'] = '[light_bg]Spiralism',
|
||||
['psykeeper'] = '[light_bg]Crucio',
|
||||
['engineer'] = '[light_bg]Upgrade',
|
||||
['plague_doctor'] = '[light_bg]Pandemic',
|
||||
['plague_doctor'] = '[light_bg]Black Death Steam',
|
||||
['fisherman'] = '[light_bg]Electric Net',
|
||||
['juggernaut'] = '[light_bg]Brutal Impact',
|
||||
['lich'] = '[light_bg]Piercing Frost',
|
||||
|
@ -473,17 +478,17 @@ function init()
|
|||
['blade'] = function() return '[fg]deal additional [yellow]' .. get_character_stat('blade', 3, 'dmg')/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]cast a spire of lightning periodically' end,
|
||||
['sage'] = function() return '[fg]when the projectile expires deal [yellow]' .. get_character_stat('sage', 3, 'dmg') .. '[fg] to all enemies under its influence' end,
|
||||
['stormweaver'] = function() return "[fg]chain lightning's trigger area of effect and number of units hit is [yellow]doubled" end,
|
||||
['sage'] = function() return '[fg]when the projectile expires deal [yellow]' .. 3*get_character_stat('sage', 3, 'dmg') .. '[fg] damage to all enemies under its influence' end,
|
||||
['squire'] = function() return '[fg]you can reroll your item choices once, these opportunities stack if unused' end,
|
||||
['cannoneer'] = function() return '[fg]showers the area in additional cannon shots that deal [yellow]' .. get_character_stat('cannoneer', 3, 'dmg') .. '[fg] AoE damage' end,
|
||||
['dual_gunner'] = function() return '[fg]every 5th attack shoots projectiles in rapid succession targetting all nearby enemies for [yellow]2[fg] seconds' end,
|
||||
['hunter'] = function() return '[fg]summons 3 pets' end,
|
||||
['cannoneer'] = function() return '[fg]showers the hit area in [yellow]5[fg] additional cannon shots that deal [yellow]' .. get_character_stat('cannoneer', 3, 'dmg')/2 .. '[fg] AoE damage' end,
|
||||
['dual_gunner'] = function() return '[fg]every 5th attack shoot in rapid succession for [yellow]2[fg] seconds' end,
|
||||
['hunter'] = function() return '[fg]summons [yellow]3[fg] pets and the pets ricochet off walls once' end,
|
||||
['chronomancer'] = function() return '[fg]enemies take damave over time [yellow]50%[fg] faster' end,
|
||||
['spellblade'] = function() return '[fg]faster projectile speed and tighter turns' end,
|
||||
['psykeeper'] = function() return '[fg]also redistributes damage taken as damage to all enemies' end,
|
||||
['engineer'] = function() return '[fg]every 3rd sentry dropped upgrade all sentries, granting them [yellow]+100%[fg] damage and attack speed' end,
|
||||
['plague_doctor'] = function() return '[fg]inflicts enemies with a contagion that deals additional [yellow]' .. get_character_stat('plague_doctor', 3, 'dmg') .. '[fg] damage per second and spreads to nearby enemies' end,
|
||||
['psykeeper'] = function() return '[fg]also redistributes damage taken as damage to all enemies at [yellow]double[fg] value' end,
|
||||
['engineer'] = function() return '[fg]every 3rd sentry dropped upgrade all sentries with [yellow]+100%[fg] damage and attack speed' end,
|
||||
['plague_doctor'] = function() return '[fg]nearby enemies take an additional [yellow]' .. get_character_stat('plague_doctor', 3, 'dmg') .. '[fg] damage per second' end,
|
||||
['fisherman'] = function() return '[fg]enemies caught take [yellow]' .. get_character_stat('fisherman', 3, 'dmg')/4 .. '[fg] damage per second' end,
|
||||
['juggernaut'] = function() return '[fg]enemies pushed away by the juggernaut are instantly killed if they hit a wall' end,
|
||||
['lich'] = function() return '[fg]chain frost decreases enemy defenses by [yellow]30[fg] for [yellow]4[fg] seconds' end,
|
||||
|
@ -798,8 +803,8 @@ function init()
|
|||
|
||||
main = Main()
|
||||
main:add(BuyScreen'buy_screen')
|
||||
main:go_to('buy_screen', 15, {
|
||||
{character = 'saboteur', level = 3},
|
||||
main:go_to('buy_screen', 22, {
|
||||
{character = 'fisherman', level = 3},
|
||||
})
|
||||
--[[
|
||||
main:add(Arena'arena')
|
||||
|
|
309
player.lua
309
player.lua
|
@ -156,13 +156,9 @@ function Player:init(args)
|
|||
|
||||
self.t:every(8, function()
|
||||
stormweaver1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
local followers
|
||||
local leader = (self.leader and self) or self.parent
|
||||
if self.leader then followers = self.followers else followers = self.parent.followers end
|
||||
for _, f in ipairs(followers) do
|
||||
if f.character ~= 'swordsman' and f.character ~= 'cleric' and f.character ~= 'elementor' and f.character ~= 'saboteur' then
|
||||
f:chain_infuse(4)
|
||||
end
|
||||
local units = self:get_all_units()
|
||||
for _, unit in ipairs(units) do
|
||||
unit:chain_infuse(4)
|
||||
end
|
||||
end)
|
||||
|
||||
|
@ -206,7 +202,9 @@ function Player:init(args)
|
|||
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)
|
||||
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
|
||||
|
@ -234,6 +232,10 @@ function Player:init(args)
|
|||
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')
|
||||
|
@ -249,6 +251,8 @@ function Player:init(args)
|
|||
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
|
||||
|
@ -256,14 +260,24 @@ function Player:init(args)
|
|||
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)
|
||||
Turret{group = main.current.main, x = x, y = y, parent = self}
|
||||
end}
|
||||
self.turret_counter = self.turret_counter + 1
|
||||
if self.turret_counter == 3 then
|
||||
self.turret_counter = 0
|
||||
local turrets = main.current.main:get_objects_by_class(Turret)
|
||||
buff1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
for _, turret in ipairs(turrets) do
|
||||
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = orange[0], duration = 0.1}
|
||||
LightningLine{group = main.current.effects, src = self, dst = turret, color = orange[0]}
|
||||
turret:upgrade()
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--[[
|
||||
elseif self.character == 'plague_doctor' then
|
||||
self.color = character_colors.plague_doctor
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
|
@ -271,10 +285,25 @@ function Player:init(args)
|
|||
self.classes = character_classes.plague_doctor
|
||||
|
||||
self.t:every(5, function()
|
||||
self:attack(64)
|
||||
end, nil, nil, 'attack')
|
||||
self:dot_attack(24, {duration = 12})
|
||||
end)
|
||||
|
||||
if self.level == 3 then
|
||||
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)
|
||||
end
|
||||
|
||||
elseif self.character == 'fisherman' then
|
||||
self.color = character_colors.fisherman
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = character_classes.fisherman
|
||||
|
||||
self.t:every(10, function()
|
||||
Trap{group = main.current.main, x = self.x, y = self.y, color = self.color, v = 50, r = random:float(0, 2*math.pi), dmg = self.dmg, character = self.character, level = self.level, parent = self}
|
||||
end)
|
||||
end
|
||||
]]--
|
||||
|
||||
self:calculate_stats(true)
|
||||
|
||||
|
@ -295,8 +324,8 @@ function Player:update(dt)
|
|||
if self.character == 'squire' then
|
||||
local all_units = self:get_all_units()
|
||||
for _, unit in ipairs(all_units) do
|
||||
unit.squire_dmg_m = 1.1
|
||||
unit.squire_def_m = 1.1
|
||||
unit.squire_dmg_m = 1.15
|
||||
unit.squire_def_m = 1.15
|
||||
end
|
||||
elseif self.character == 'chronomancer' then
|
||||
local all_units = self:get_all_units()
|
||||
|
@ -380,10 +409,10 @@ function Player:update(dt)
|
|||
self:calculate_stats()
|
||||
|
||||
if self.attack_sensor then self.attack_sensor:move_to(self.x, self.y) end
|
||||
if self.gun_kata_sensor then self.gun_kata_sensor:move_to(self.x, self.y) end
|
||||
self.t:set_every_multiplier('shoot', self.aspd_m)
|
||||
self.t:set_every_multiplier('attack', self.aspd_m)
|
||||
|
||||
|
||||
if self.leader then
|
||||
if input.move_left.down then self.r = self.r - 1.66*math.pi*dt end
|
||||
if input.move_right.down then self.r = self.r + 1.66*math.pi*dt end
|
||||
|
@ -496,10 +525,20 @@ function Player:hit(damage)
|
|||
local psykeeper = self:get_unit'psykeeper'
|
||||
if psykeeper then
|
||||
psykeeper.stored_heal = psykeeper.stored_heal + actual_damage
|
||||
if psykeeper.stored_heal > (0.1*self.level*psykeeper.max_hp) then
|
||||
if psykeeper.stored_heal > (0.5*psykeeper.max_hp) and love.timer.getTime() - self.last_heal_time > 6 then
|
||||
self.last_heal_time = love.timer.getTime()
|
||||
local all_units = self:get_all_units()
|
||||
for _, unit in ipairs(all_units) do
|
||||
unit:heal(psykeeper.stored_heal*(self.heal_effect_m or 1))
|
||||
unit:heal(psykeeper.stored_heal*(self.heal_effect_m or 1)/#all_units)
|
||||
end
|
||||
if self.level == 3 then
|
||||
buff1: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(2*psykeeper.stored_heal/#enemies)
|
||||
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = fg[0], duration = 0.1}
|
||||
LightningLine{group = main.current.effects, src = self, dst = enemy, color = fg[0]}
|
||||
end
|
||||
end
|
||||
psykeeper.stored_heal = 0
|
||||
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
|
@ -632,12 +671,28 @@ function Player:shoot(r, mods)
|
|||
HitCircle{group = main.current.effects, x = self.x + 0.8*self.shape.w*math.cos(r) + 4*math.cos(r - math.pi/2), y = self.y + 0.8*self.shape.w*math.sin(r) + 4*math.sin(r - math.pi/2), rs = 6}
|
||||
HitCircle{group = main.current.effects, x = self.x + 0.8*self.shape.w*math.cos(r) + 4*math.cos(r + math.pi/2), y = self.y + 0.8*self.shape.w*math.sin(r) + 4*math.sin(r + math.pi/2), rs = 6}
|
||||
local t1 = {group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(r) + 4*math.cos(r - math.pi/2) , y = self.y + 1.6*self.shape.w*math.sin(r) + 4*math.sin(r - math.pi/2),
|
||||
v = 250, r = r, color = self.color, dmg = self.dmg*dmg_m, crit = crit, character = self.character, parent = self, level = self.level}
|
||||
v = 300, r = r, color = self.color, dmg = self.dmg*dmg_m, crit = crit, character = self.character, parent = self, level = self.level}
|
||||
local t2 = {group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(r) + 4*math.cos(r + math.pi/2) , y = self.y + 1.6*self.shape.w*math.sin(r) + 4*math.sin(r + math.pi/2),
|
||||
v = 250, r = r, color = self.color, dmg = self.dmg*dmg_m, crit = crit, character = self.character, parent = self, level = self.level}
|
||||
v = 300, r = r, color = self.color, dmg = self.dmg*dmg_m, crit = crit, character = self.character, parent = self, level = self.level}
|
||||
Projectile(table.merge(t1, mods or {}))
|
||||
Projectile(table.merge(t2, mods or {}))
|
||||
|
||||
self.dg_counter = self.dg_counter + 1
|
||||
if self.dg_counter == 5 then
|
||||
self.dg_counter = 0
|
||||
self.t:every(0.1, function()
|
||||
local random_enemy = self:get_random_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||
if random_enemy then
|
||||
_G[random:table{'gun_kata1', 'gun_kata2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
camera:spring_shake(2, r)
|
||||
self.hfx:use('shoot', 0.25)
|
||||
local r = self:angle_to_object(random_enemy)
|
||||
HitCircle{group = main.current.effects, x = self.x + 0.8*self.shape.w*math.cos(r) + 4*math.cos(r - math.pi/2), y = self.y + 0.8*self.shape.w*math.sin(r) + 4*math.sin(r - math.pi/2), rs = 6}
|
||||
local t = {group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(r), y = self.y + 1.6*self.shape.w*math.sin(r), v = 300, r = r, color = self.color, dmg = self.dmg, character = self.character,
|
||||
parent = self, level = self.level}
|
||||
Projectile(table.merge(t, mods or {}))
|
||||
end
|
||||
end, 20)
|
||||
end
|
||||
else
|
||||
HitCircle{group = main.current.effects, x = self.x + 0.8*self.shape.w*math.cos(r), y = self.y + 0.8*self.shape.w*math.sin(r), rs = 6}
|
||||
local t = {group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(r), y = self.y + 1.6*self.shape.w*math.sin(r), v = 250, r = r, color = self.color, dmg = self.dmg*dmg_m, crit = crit, character = self.character,
|
||||
|
@ -645,8 +700,11 @@ function Player:shoot(r, mods)
|
|||
Projectile(table.merge(t, mods or {}))
|
||||
end
|
||||
|
||||
if self.character == 'vagrant' or self.character == 'dual_gunner' then
|
||||
if self.character == 'vagrant' 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' then
|
||||
archer1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
elseif self.character == 'wizard' then
|
||||
|
@ -681,6 +739,17 @@ function Player:attack(area, mods)
|
|||
end
|
||||
|
||||
|
||||
function Player:dot_attack(area, mods)
|
||||
mods = mods or {}
|
||||
camera:shake(2, 0.5)
|
||||
self.hfx:use('shoot', 0.25)
|
||||
local t = {group = main.current.effects, x = mods.x or self.x, y = mods.y or self.y, r = self.r, rs = self.area_size_m*(area or 64), color = self.color, dmg = self.area_dmg_m*self.dmg, character = self.character, level = self.level}
|
||||
DotArea(table.merge(t, mods))
|
||||
|
||||
dot1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
||||
end
|
||||
|
||||
|
||||
function Player:barrage(r, n)
|
||||
n = n or 8
|
||||
for i = 1, n do
|
||||
|
@ -710,12 +779,24 @@ function Projectile:init(args)
|
|||
self.infused_enemies_hit = {}
|
||||
|
||||
if self.character == 'sage' then
|
||||
elementor1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
||||
self.compression_dmg = self.dmg
|
||||
self.dmg = 0
|
||||
self.pull_sensor = Circle(self.x, self.y, 64*self.parent.area_size_m)
|
||||
self.rs = 0
|
||||
self.t:tween(0.05, self, {rs = self.shape.w/2.5}, math.cubic_in_out, function() self.spring:pull(0.15) end)
|
||||
self.t:after(4, function()
|
||||
self.t:every_immediate(0.05, function() self.hidden = not self.hidden end, 7, function() self:die() end)
|
||||
self.t:every_immediate(0.05, function() self.hidden = not self.hidden end, 7, function()
|
||||
self:die()
|
||||
if self.level == 3 then
|
||||
_G[random:table{'saboteur_hit1', 'saboteur_hit2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.2}
|
||||
magic_area1:play{pitch = random:float(0.95, 1.05), volume = 0.075}
|
||||
local enemies = self:get_objects_in_shape(self.pull_sensor, main.current.enemies)
|
||||
for _, enemy in ipairs(enemies) do
|
||||
enemy:hit(3*self.compression_dmg)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
self.color_transparent = Color(args.color.r, args.color.g, args.color.b, 0.08)
|
||||
|
@ -726,12 +807,22 @@ function Projectile:init(args)
|
|||
self.dvr = random:float(-math.pi/4, math.pi/4)
|
||||
|
||||
elseif self.character == 'spellblade' then
|
||||
self.pierce = 1000
|
||||
self.orbit_r = 0
|
||||
self.orbit_vr = 8*math.pi
|
||||
self.t:tween(6.25, self, {orbit_vr = math.pi}, math.expo_out, function()
|
||||
self.t:tween(12.25, self, {orbit_vr = 0}, math.linear)
|
||||
end)
|
||||
if self.level == 3 then
|
||||
self.v = 1.5*self.v
|
||||
self.pierce = 1000
|
||||
self.orbit_r = 0
|
||||
self.orbit_vr = 12*math.pi
|
||||
self.t:tween(6.25, self, {orbit_vr = 4*math.pi}, math.expo_out, function()
|
||||
self.t:tween(12.25, self, {orbit_vr = 0}, math.linear)
|
||||
end)
|
||||
else
|
||||
self.pierce = 1000
|
||||
self.orbit_r = 0
|
||||
self.orbit_vr = 8*math.pi
|
||||
self.t:tween(6.25, self, {orbit_vr = math.pi}, math.expo_out, function()
|
||||
self.t:tween(12.25, self, {orbit_vr = 0}, math.linear)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
if self.homing then
|
||||
|
@ -813,6 +904,11 @@ function Projectile:die(x, y, r, n)
|
|||
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*64, color = self.color, dmg = self.parent.area_dmg_m*self.dmg, character = self.character, level = self.level}
|
||||
elseif self.character == 'cannoneer' then
|
||||
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*96, color = self.color, dmg = 2*self.parent.area_dmg_m*self.dmg, character = self.character, level = self.level}
|
||||
self.parent.t:every(0.2, function()
|
||||
_G[random:table{'cannoneer1', 'cannoneer2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
Area{group = main.current.effects, x = self.x + random:float(-32, 32), y = self.y + random:float(-32, 32), r = self.r + random:float(0, 2*math.pi), w = self.parent.area_size_m*48, color = self.color,
|
||||
dmg = 0.5*self.parent.area_dmg_m*self.dmg, character = self.character, level = self.level}
|
||||
end, 5)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -853,7 +949,7 @@ function Projectile:on_collision_enter(other, contact)
|
|||
elseif self.character == 'cannoneer' then
|
||||
self:die(x, y, r, random:int(2, 3))
|
||||
cannon_hit_wall1:play{pitch = random:float(0.95, 1.05), volume = 0.1}
|
||||
elseif self.character == 'engineer' then
|
||||
elseif self.character == 'engineer' or self.character == 'dual_gunner' then
|
||||
self:die(x, y, r, random:int(2, 3))
|
||||
_G[random:table{'turret_hit_wall1', 'turret_hit_wall2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.2}
|
||||
else
|
||||
|
@ -910,14 +1006,22 @@ function Projectile:on_trigger_enter(other, contact)
|
|||
|
||||
if self.character == 'hunter' and random:bool(40) then
|
||||
trigger:after(0.01, function()
|
||||
SpawnEffect{group = main.current.effects, x = self.parent.x, y = self.parent.y, color = orange[0], action = function(x, y)
|
||||
Pet{group = main.current.main, x = x, y = y, r = self.parent:angle_to_object(other), v = 150, parent = self.parent, conjurer_buff_m = self.conjurer_buff_m or 1}
|
||||
end}
|
||||
if self.level == 3 then
|
||||
local r = self.parent:angle_to_object(other)
|
||||
SpawnEffect{group = main.current.effects, x = self.parent.x, y = self.parent.y, color = green[0], action = function(x, y)
|
||||
Pet{group = main.current.main, x = x, y = y, r = r, v = 150, parent = self.parent, conjurer_buff_m = self.conjurer_buff_m or 1}
|
||||
Pet{group = main.current.main, x = x + 12*math.cos(r + math.pi/2), y = y + 12*math.sin(r + math.pi/2), r = r, v = 150, parent = self.parent, conjurer_buff_m = self.conjurer_buff_m or 1}
|
||||
Pet{group = main.current.main, x = x + 12*math.cos(r - math.pi/2), y = y + 12*math.sin(r - math.pi/2), r = r, v = 150, parent = self.parent, conjurer_buff_m = self.conjurer_buff_m or 1}
|
||||
end}
|
||||
else
|
||||
SpawnEffect{group = main.current.effects, x = self.parent.x, y = self.parent.y, color = orange[0], action = function(x, y)
|
||||
Pet{group = main.current.main, x = x, y = y, r = self.parent:angle_to_object(other), v = 150, parent = self.parent, conjurer_buff_m = self.conjurer_buff_m or 1}
|
||||
end}
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
if self.parent.chain_infused then
|
||||
--[[
|
||||
local units = self.parent:get_all_units()
|
||||
local stormweaver_level = 0
|
||||
for _, unit in ipairs(units) do
|
||||
|
@ -926,12 +1030,11 @@ function Projectile:on_trigger_enter(other, contact)
|
|||
break
|
||||
end
|
||||
end
|
||||
]]--
|
||||
local src = other
|
||||
for i = 1, 2 do
|
||||
for i = 1, 2 + (stormweaver_level == 3 and 2 or 0) do
|
||||
_G[random:table{'spark1', 'spark2', 'spark3'}]:play{pitch = random:float(0.9, 1.1), volume = 0.3}
|
||||
table.insert(self.infused_enemies_hit, src)
|
||||
local dst = src:get_random_object_in_shape(Circle(src.x, src.y, 64), main.current.enemies, self.infused_enemies_hit)
|
||||
local dst = src:get_random_object_in_shape(Circle(src.x, src.y, (stormweaver_level == 3 and 128 or 64)), main.current.enemies, self.infused_enemies_hit)
|
||||
if dst then
|
||||
dst:hit(0.2*self.dmg)
|
||||
LightningLine{group = main.current.effects, src = src, dst = dst}
|
||||
|
@ -1027,6 +1130,111 @@ end
|
|||
|
||||
|
||||
|
||||
DotArea = Object:extend()
|
||||
DotArea:implement(GameObject)
|
||||
function DotArea:init(args)
|
||||
self:init_game_object(args)
|
||||
self.shape = Circle(self.x, self.y, self.rs)
|
||||
|
||||
self.t:every(0.2, function()
|
||||
local enemies = main.current.main:get_objects_in_shape(self.shape, main.current.enemies)
|
||||
for _, enemy in ipairs(enemies) do
|
||||
hit2:play{pitch = random:float(0.8, 1.2), volume = 0.2}
|
||||
enemy:hit(self.dmg/5)
|
||||
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
|
||||
end
|
||||
end, nil, nil, 'dot')
|
||||
|
||||
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)
|
||||
if self.duration and self.duration > 0.5 then
|
||||
self.t:after(self.duration - 0.35, function()
|
||||
self.t:every_immediate(0.05, function() self.hidden = not self.hidden end, 7, function() self.dead = true end)
|
||||
end)
|
||||
end
|
||||
|
||||
self.vr = 0
|
||||
self.dvr = random:float(-math.pi/4, math.pi/4)
|
||||
end
|
||||
|
||||
|
||||
function DotArea:update(dt)
|
||||
self:update_game_object(dt)
|
||||
self.t:set_every_multiplier('dot', (main.current.chronomancer_dot or 1))
|
||||
self.vr = self.vr + self.dvr*dt
|
||||
|
||||
if self.parent then
|
||||
if self.character == 'plague_doctor' and self.level == 3 then
|
||||
self.x, self.y = self.parent.x, self.parent.y
|
||||
self.shape:move_to(self.x, self.y)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function DotArea:draw()
|
||||
if self.hidden then return end
|
||||
|
||||
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, self.shape.rs, self.color_transparent)
|
||||
local lw = math.remap(self.shape.rs, 32, 256, 2, 4)
|
||||
for i = 1, 4 do graphics.arc('open', self.x, self.y, self.shape.rs, (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
|
||||
|
||||
|
||||
|
||||
|
||||
--[[
|
||||
Trap = Object:extend()
|
||||
Trap:implement(GameObject)
|
||||
Trap:implement(Physics)
|
||||
function Trap:init(args)
|
||||
self:init_game_object(args)
|
||||
|
||||
self.shape = Rectangle(self.x, self.y, 6, 6)
|
||||
self.spring:pull(0.15, 200, 20)
|
||||
self.vr = 0
|
||||
self.dvr = random:float(-2*math.pi, 2*math.pi)
|
||||
self.t:tween(1, self, {v = 0, dvr = 0}, math.linear)
|
||||
end
|
||||
|
||||
|
||||
function Trap:update(dt)
|
||||
self:update_game_object(dt)
|
||||
self:move_along_angle(self.v, self.r)
|
||||
self.vr = self.vr + self.dvr*dt
|
||||
self.shape:move_to(self.x, self.y)
|
||||
|
||||
local enemies = self:get_objects_in_shape(self.shape, main.current.enemies)
|
||||
if #enemies > 0 then
|
||||
self.dead = true
|
||||
local enemies = self:get_objects_in_shape(Circle(self.x, self.y, 24), main.current.enemies)
|
||||
for _, enemy in ipairs(enemies) do
|
||||
enemy:slow(0.1, 4)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Trap:draw()
|
||||
graphics.push(self.x, self.y, self.r + self.vr, self.spring.x, self.spring.x)
|
||||
graphics.line(self.x - 6, self.y, self.x + 6, self.y, self.color, 3)
|
||||
graphics.line(self.x, self.y - 6, self.x, self.y + 6, self.color, 3)
|
||||
graphics.pop()
|
||||
end
|
||||
]]--
|
||||
|
||||
|
||||
|
||||
|
||||
Turret = Object:extend()
|
||||
Turret:implement(GameObject)
|
||||
Turret:implement(Physics)
|
||||
|
@ -1044,12 +1252,12 @@ function Turret:init(args)
|
|||
self.hfx:use('hit', 0.25, 200, 10)
|
||||
HitCircle{group = main.current.effects, x = self.x + 0.8*self.shape.w*math.cos(self.r), y = self.y + 0.8*self.shape.w*math.sin(self.r), rs = 6}
|
||||
local t = {group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(self.r), y = self.y + 1.6*self.shape.w*math.sin(self.r), v = 200, r = self.r, color = self.color,
|
||||
dmg = self.parent.dmg*(self.parent.conjurer_buff_m or 1), character = self.parent.character, parent = self.parent}
|
||||
dmg = self.parent.dmg*(self.parent.conjurer_buff_m or 1)*self.upgrade_dmg_m, character = self.parent.character, parent = self.parent}
|
||||
Projectile(table.merge(t, mods or {}))
|
||||
turret1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
turret2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
end, 3)
|
||||
end)
|
||||
end, nil, nil, 'shoot')
|
||||
|
||||
self.t:after(24*(self.parent.conjurer_buff_m or 1), function()
|
||||
local n = n or random:int(3, 4)
|
||||
|
@ -1057,12 +1265,17 @@ function Turret:init(args)
|
|||
HitCircle{group = main.current.effects, x = self.x, y = self.y}:scale_down()
|
||||
self.dead = true
|
||||
end)
|
||||
|
||||
self.upgrade_dmg_m = 1
|
||||
self.upgrade_aspd_m = 1
|
||||
end
|
||||
|
||||
|
||||
function Turret:update(dt)
|
||||
self:update_game_object(dt)
|
||||
|
||||
self.t:set_every_multiplier('shoot', 1/self.upgrade_aspd_m)
|
||||
|
||||
local closest_enemy = self:get_closest_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||
if closest_enemy then
|
||||
self:rotate_towards_object(closest_enemy, 0.2)
|
||||
|
@ -1078,6 +1291,14 @@ function Turret:draw()
|
|||
end
|
||||
|
||||
|
||||
function Turret:upgrade()
|
||||
self.upgrade_dmg_m = self.upgrade_dmg_m + 1
|
||||
self.upgrade_aspd_m = self.upgrade_aspd_m + 1
|
||||
for i = 1, 6 do HitParticle{group = main.current.effects, x = self.x, y = self.y, r = random:float(0, 2*math.pi), color = self.color} end
|
||||
HitCircle{group = main.current.effects, x = self.x, y = self.y}:scale_down()
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
Pet = Object:extend()
|
||||
|
@ -1091,6 +1312,7 @@ function Pet:init(args)
|
|||
self.color = character_colors.hunter
|
||||
self.pierce = 6
|
||||
pet1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
self.ricochet = 1
|
||||
end
|
||||
|
||||
|
||||
|
@ -1122,8 +1344,15 @@ function Pet:on_collision_enter(other, contact)
|
|||
local n = n or random:int(3, 4)
|
||||
for i = 1, n do HitParticle{group = main.current.effects, x = x, y = y, r = random:float(0, 2*math.pi), color = self.color} end
|
||||
HitCircle{group = main.current.effects, x = x, y = y}:scale_down()
|
||||
self.dead = true
|
||||
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
|
||||
if self.parent.level == 3 and self.ricochet > 0 then
|
||||
local r = Unit.bounce(self, nx, ny)
|
||||
self.r = r
|
||||
self.ricochet = self.ricochet - 1
|
||||
else
|
||||
self.dead = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1144,6 +1373,8 @@ function Pet:on_trigger_enter(other)
|
|||
other:push(35, self:angle_to_object(other))
|
||||
self.pierce = self.pierce - 1
|
||||
end
|
||||
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
elseif self.character == 'blade' then
|
||||
self.hfx:use('hit', 0.25)
|
||||
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = fg[0], duration = 0.1}
|
||||
HitParticle{group = main.current.effects, x = self.x, y = self.y, color = self.color}
|
||||
|
|
22
todo
22
todo
|
@ -50,17 +50,17 @@
|
|||
* Blade [warrior, nuker]: throws multiple blades that deal AoE damage - Lv.3: Blade Resonance - deal additional damage based on number of enemies hit
|
||||
* Elementor [mage, nuker]: deals AoE damage to a random target in a large area - Lv.3: Windfield - slows enemies hit
|
||||
* Saboteur [rogue, conjurer, nuker]: calls saboteurs to seek targets and deal AoE damage - Lv.3: Chain Reaction - should an enemy die from a saboteur explosion, it also explodes
|
||||
Stormweaver [enchanter]: infuses all allied projectiles with chain lightning that deals extra damage - Lv.3: Lightning Spire - cast a spire of lightning periodically
|
||||
Sage [nuker]: shoots a slow moving projectile that pulls enemies in - Lv.3: Dimension Compression - when the projectile expires deal massive damage to all enemies under its influence
|
||||
Squire [warrior, enchanter]: increased damage and defense to all allies - Lv.3: Repair - you can reroll your item choice once every 3 levels, these opportunities stack if unused
|
||||
Cannoneer [ranger, nuker]: shoots a projectile that deals AoE damage - Lv.3: Cannon Barrage - showers the hit area in additional cannon shots that deal AoE damage
|
||||
Dual Gunner [ranger, rogue]: shoots two parallel projectiles - Lv.3: Gun Kata - every 5th attack shoots projectiles in a rapid succession for a duration, targetting all nearby enemies
|
||||
Hunter [ranger, conjurer]: shoots an arrow that summons a pet - Lv.3: Feral Pack - summons 3 pets
|
||||
Chronomancer [mage, enchanter]: increased attack speed to all allies - Lv.3: Quicken - enemies take DoT faster
|
||||
Spellblade [mage, rogue]: throws knives that spiral outwards and pierce - Lv.3: Spiralism - faster projectile speed and tighter turns
|
||||
Psykeeper [healer, psyker]: stores damage taken by all allies and redistributes it as healing - Lv.3: Crucio - also redistributes it as damage to all enemies
|
||||
Engineer [conjurer]: drops sentries that shoot bursts of projectils - Lv.3: Upgrade - every 3rd sentry dropped, upgrade all sentries temporarily, giving increased damage and attack speed
|
||||
Plague Doctor [nuker, voider]: creates an area that deals DoT - Lv.3: Pandemic - inflicts enemies with a contagion that deals additional DoT, if they die from it it passes to a nearby enemy
|
||||
* Stormweaver [enchanter]: infuses all allied projectiles with chain lightning that deals extra damage - Lv.3: Lightning Spire - cast a spire of lightning periodically
|
||||
* Sage [nuker]: shoots a slow moving projectile that pulls enemies in - Lv.3: Dimension Compression - when the projectile expires deal massive damage to all enemies under its influence
|
||||
(Repair to do after items implemented) * Squire [warrior, enchanter]: increased damage and defense to all allies - Lv.3: Repair - you can reroll your item choice once every 3 levels, these opportunities stack if unused
|
||||
* Cannoneer [ranger, nuker]: shoots a projectile that deals AoE damage - Lv.3: Cannon Barrage - showers the hit area in additional cannon shots that deal AoE damage
|
||||
* Dual Gunner [ranger, rogue]: shoots two parallel projectiles - Lv.3: Gun Kata - every 5th attack shoots projectiles in a rapid succession for a duration, targetting all nearby enemies
|
||||
* Hunter [ranger, conjurer]: shoots an arrow that summons a pet - Lv.3: Feral Pack - summons 3 pets
|
||||
(Apply arena.chronomancer_dot when damage over time is implemented) * Chronomancer [mage, enchanter]: increased attack speed to all allies - Lv.3: Quicken - enemies take DoT faster
|
||||
* Spellblade [mage, rogue]: throws knives that spiral outwards and pierce - Lv.3: Spiralism - faster projectile speed and tighter turns
|
||||
* Psykeeper [healer, psyker]: stores damage taken by all allies and redistributes it as healing - Lv.3: Crucio - also redistributes it as damage to all enemies
|
||||
* Engineer [conjurer]: drops sentries that shoot bursts of projectils - Lv.3: Upgrade - every 3rd sentry dropped, upgrade all sentries temporarily, giving increased damage and attack speed
|
||||
* Plague Doctor [nuker, voider]: creates an area that deals DoT - Lv.3: Pandemic - inflicts enemies with a contagion that deals additional DoT, if they die from it it passes to a nearby enemy
|
||||
Fisherman [trapper, warrior]: throws a net that entangles enemies and prevents them from moving - Lv.3: Electric Net - enemies caught take DoT
|
||||
Juggernaut [forcer, warrior]: creates a small area that deals AoE damage and pushes enemies away - Lv.3: Brutal Impact - enemies pushed away are instantly killed if they hit a wall
|
||||
Lich [mage]: launches a chain frost that chains 7 times, dealing damage and slowing enemies it hits - Lv.3: Piercing Frost - chain frost ignores enemy defenses
|
||||
|
|
Loading…
Reference in New Issue