From 15dfd5a1c5df4eabe4d6e1895d8150e92e490aee Mon Sep 17 00:00:00 2001 From: a327ex Date: Tue, 13 Apr 2021 22:12:29 -0300 Subject: [PATCH] Day 56 --- devlog.md | 18 ++++ enemies.lua | 6 +- engine/game/trigger.lua | 2 +- main.lua | 38 +++---- player.lua | 214 +++++++++++++++++++++++++++++++++++++++- todo | 12 +-- 6 files changed, 260 insertions(+), 30 deletions(-) diff --git a/devlog.md b/devlog.md index a45d9d9..abdc094 100644 --- a/devlog.md +++ b/devlog.md @@ -905,3 +905,21 @@ Even slower day today, but I managed to get something done. I'm hoping I can fin | 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 | + +# Day 56 - 13/04/21 + +Still slow... But I got something done :) + +| Character | Classes | Description | +| --- | --- | --- | +| Carver | conjurer, healer | carves a statue that periodically heals 1 unit for 20% max HP if in range | +| Bane | voider, curser | creates a large area that curses enemies to take +50% damage | +| Psykino | mage, psyker, forcer | pulls enemies together for 2 seconds | +| Barrager | ranger, forcer | shoots a barrage of 5 arrows, each dealing X damage and pushing enemies | + +| Character | Lv.3 Effect Name | Lv.3 Effect Description | +| --- | --- | --- | +| Carver | World Tree | carves a tree that heals twice as fast, in a bigger area, and heals 2 units instead | +| Bane | Nightmare | the area also deals X damage per second and slows enemies by 50% | +| Psykino | Magnetic Force | enemies take 4X damage and are pushed away when the area expires | +| Barrager | Barrage | every 3rd attack the barrage shoots 15 projectiles and they push harder | diff --git a/enemies.lua b/enemies.lua index d880ae8..6d68200 100644 --- a/enemies.lua +++ b/enemies.lua @@ -244,6 +244,7 @@ function Seeker:update(dt) self:calculate_stats() self.stun_dmg_m = (self.barbarian_stunned and 2 or 1) + self.bane_dmg_m = (self.baned and 1.5 or 1) if self.shooter then self.t:set_every_multiplier('shooter', (1 - self.level*0.02)) @@ -364,7 +365,7 @@ function Seeker:hit(damage, projectile) if self.push_invulnerable then return end self:show_hp() - local actual_damage = self:calculate_damage(damage)*self.stun_dmg_m + local actual_damage = self:calculate_damage(damage)*self.stun_dmg_m*self.bane_dmg_m self.hp = self.hp - actual_damage main.current.damage_dealt = main.current.damage_dealt + actual_damage @@ -468,6 +469,9 @@ function Seeker:curse(curse, duration, arg1) end, 'launcher_curse') elseif curse == 'bard' then self.bard_cursed = true + elseif curse == 'bane' then + self.baned = true + self.t:after(duration, function() self.baned = false end, 'bane_curse') end end diff --git a/engine/game/trigger.lua b/engine/game/trigger.lua index 477a2c9..2e8bb8c 100644 --- a/engine/game/trigger.lua +++ b/engine/game/trigger.lua @@ -154,7 +154,7 @@ end -- Returns the elapsed time of a given trigger as a number between 0 and 1. -- Useful if you need to know where you currently are in the duration of a during call. function Trigger:get_during_elapsed_time(tag) - return self.triggers[tag].trigger/self.triggers[tag].delay + return self.triggers[tag].timer/self.triggers[tag].delay end diff --git a/main.lua b/main.lua index 1f93959..f4df4e2 100644 --- a/main.lua +++ b/main.lua @@ -182,7 +182,7 @@ function init() ['carver'] = green[0], ['bane'] = purple[0], ['psykino'] = fg[0], - ['arbalester'] = green[0], + ['barrager'] = green[0], ['highlander'] = yellow[0], ['sapper'] = blue[0], ['priest'] = green[0], @@ -226,7 +226,7 @@ function init() ['carver'] = 'green', ['bane'] = 'purple', ['psykino'] = 'fg', - ['arbalester'] = 'green', + ['barrager'] = 'green', ['highlander'] = 'yellow', ['sapper'] = 'blue', ['priest'] = 'green', @@ -267,10 +267,10 @@ function init() ['bard'] = {'curser', 'rogue'}, ['assassin'] = {'rogue', 'voider'}, ['host'] = {'swarmer'}, - ['carver'] = {'conjurer', 'curser', 'healer'}, + ['carver'] = {'conjurer', 'healer'}, ['bane'] = {'curser', 'voider'}, ['psykino'] = {'mage', 'psyker', 'forcer'}, - ['arbalester'] = {'ranger', 'forcer'}, + ['barrager'] = {'ranger', 'forcer'}, ['highlander'] = {'warrior'}, ['sapper'] = {'enchanter', 'voider', 'healer'}, ['priest'] = {'healer'}, @@ -311,10 +311,10 @@ function init() ['bard'] = '[purple]Curser, [red]Rogue', ['assassin'] = '[red]Rogue, [purple]Voider', ['host'] = '[orange]Swarmer', - ['carver'] = '[orange]Conjurer, [purple]Curser, [green]Healer', + ['carver'] = '[orange]Conjurer, [green]Healer', ['bane'] = '[purple]Curser, Voider', ['psykino'] = '[blue]Mage, [fg]Psyker, [yellow]Forcer', - ['arbalester'] = '[green]Ranger, [yellow]Forcer', + ['barrager'] = '[green]Ranger, [yellow]Forcer', ['highlander'] = '[yellow]Warrior', ['sapper'] = '[blue]Enchanter, [purple]Voider, [green]Healer', ['priest'] = '[green]Healer', @@ -372,10 +372,10 @@ function init() ['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]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, - ['arbalester'] = function(lvl) return '[fg]launches a massive arrow that deals [yellow]' .. get_character_stat('arbalester', lvl, 'dmg') .. '[fg] damage and pushes enemies back, ignoring knockback resistances' 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]creates a large area that curses enemies to take [yellow]+50%[fg] damage' 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]5[fg] arrows, each dealing [yellow]' .. get_character_stat('barrager', lvl, 'dmg') .. '[fg] damage and pushing enemies' end, ['highlander'] = function(lvl) return '[fg]deals [yellow]' .. 6*get_character_stat('highlander', lvl, 'dmg') .. '[fg] AoE damage' end, ['sapper'] = function(lvl) return '[fg]periodically steals [yellow]5%[fg] max HP per second from nearby enemies and gain 25% increased movement speed' end, ['priest'] = function(lvl) return '[fg]heals all allies for [yellow]20%[fg] their max HP' end, @@ -419,7 +419,7 @@ function init() ['carver'] = '[green]World Tree', ['bane'] = '[purple]Nightmare', ['psykino'] = '[fg]Magnetic Force', - ['arbalester'] = '[green]Ballista Sinitra', + ['barrager'] = '[green]Barrage', ['highlander'] = '[yellow]Crosscut', ['sapper'] = '[blue]Enduring Sap', ['priest'] = '[green]Divine Intervention', @@ -463,7 +463,7 @@ function init() ['carver'] = '[light_bg]World Tree', ['bane'] = '[light_bg]Baneling Swarm', ['psykino'] = '[light_bg]Magnetic Force', - ['arbalester'] = '[light_bg]Ballista Sinitra', + ['barrager'] = '[light_bg]Ballista Sinitra', ['barbarian'] = '[light_bg]Berserk', ['sapper'] = '[light_bg]Chain Reaction', ['priest'] = '[light_bg]Divine Intervention', @@ -504,10 +504,10 @@ function init() ['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]+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, + ['carver'] = function() return '[fg]carves a tree that heals [yellow]twice[fg] as fast, in a bigger area, and heals [yellow]2[fg] units instead' 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, - ['arbalester'] = function() return '[fg]enemies hit by the arrow have defense decreased by [yellow]100[fg] for [yellow]4[fg] seconds' end, + ['psykino'] = function() return '[fg]enemies take [yellow]' .. 4*get_character_stat('psykino', 3, 'dmg') .. '[fg] damage and are pushed away when the area expires' end, + ['barrager'] = function() return '[fg]every 3rd attack the barrage shoots [yellow]15[fg] projectiles and they push harder' end, ['crosscut'] = function() return '[fg]two crosscutting areas of +100% size are created instead' end, ['sapper'] = function() return '[fg]sapped enemies permanently take [yellow]' .. get_character_stat('sapper', 3, 'dmg') .. '[fg] damage per second' end, ['priest'] = function() return '[fg]at the start of the round pick [yellow]3[fg] units at random and grants them a buff that prevents death once' end, @@ -551,7 +551,7 @@ function init() ['carver'] = function(lvl) return get_character_stat_string('carver', lvl) end, ['bane'] = function(lvl) return get_character_stat_string('bane', lvl) end, ['psykino'] = function(lvl) return get_character_stat_string('psykino', lvl) end, - ['arbalester'] = function(lvl) return get_character_stat_string('arbalester', lvl) end, + ['barrager'] = function(lvl) return get_character_stat_string('barrager', lvl) end, ['highlander'] = function(lvl) return get_character_stat_string('highlander', lvl) end, ['sapper'] = function(lvl) return get_character_stat_string('sapper', lvl) end, ['priest'] = function(lvl) return get_character_stat_string('priest', lvl) end, @@ -601,7 +601,7 @@ function init() tier_to_characters = { [1] = {'vagrant', 'swordsman', 'wizard', 'archer', 'scout', 'cleric'}, [2] = {'saboteur', 'sage', 'squire', 'dual_gunner', 'hunter', 'chronomancer', 'barbarian', 'cryomancer', 'beastmaster', 'launcher', 'bard', 'carver'}, - [3] = {'outlaw', 'elementor', 'stormweaver', 'spellblade', 'psykeeper', 'engineer', 'juggernaut', 'pyromancer', 'corruptor', 'assassin', 'bane', 'arbalester', 'infestor', 'flagellant'}, + [3] = {'outlaw', 'elementor', 'stormweaver', 'spellblade', 'psykeeper', 'engineer', 'juggernaut', 'pyromancer', 'corruptor', 'assassin', 'bane', 'barrager', 'infestor', 'flagellant'}, [4] = {'priest', 'highlander', 'psykino', 'lich', 'host', 'sapper', 'blade', 'plague_doctor', 'cannoneer'}, } @@ -643,7 +643,7 @@ function init() ['carver'] = 2, ['bane'] = 3, ['psykino'] = 4, - ['arbalester'] = 3, + ['barrager'] = 3, ['highlander'] = 4, ['sapper'] = 4, ['priest'] = 4, @@ -809,7 +809,7 @@ function init() main = Main() main:add(BuyScreen'buy_screen') main:go_to('buy_screen', 22, { - {character = 'host', level = 3}, + {character = 'barrager', level = 3}, }) --[[ main:add(Arena'arena') diff --git a/player.lua b/player.lua index 583ec52..b0b718b 100644 --- a/player.lua +++ b/player.lua @@ -279,6 +279,48 @@ function Player:init(args) 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 + + elseif self.character == 'carver' then + self.t:every(16, function() + Tree{group = main.current.main, x = self.x, y = self.y, color = self.color, parent = self, rs = self.area_size_m*(self.level == 3 and 128 or 64), level = self.level} + end) + + elseif self.character == 'bane' then + self.t:every(12, function() + self.dot_area = DotArea{group = main.current.effects, x = self.x, y = self.y, rs = self.area_size_m*128, color = self.color, dmg = self.area_dmg_m*(self.level == 3 and self.dmg or 0), + character = self.character, level = self.level, parent = self, duration = 8} + end) + + elseif self.character == 'psykino' then + self.t:every(4, function() + local center_enemy = self:get_random_object_in_shape(Circle(self.x, self.y, 160), main.current.enemies) + if center_enemy then + ForceArea{group = main.current.effects, x = center_enemy.x, y = center_enemy.y, rs = self.area_size_m*64, color = self.color, character = self.character, level = self.level, parent = self} + end + end) + + elseif self.character == 'barrager' then + self.barrager_counter = 0 + 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) + local r = self:angle_to_object(closest_enemy) + self.barrager_counter = self.barrager_counter + 1 + if self.barrager_counter == 3 then + self.barrage_counter = 0 + for i = 1, 15 do + self.t:after((i-1)*0.05, function() + self:shoot(r + random:float(-math.pi/32, math.pi/32), {knockback = (self.level == 3 and 14 or 7)}) + end) + end + else + for i = 1, 5 do + self.t:after((i-1)*0.075, function() + self:shoot(r + random:float(-math.pi/32, math.pi/32), {knockback = (self.level == 3 and 14 or 7)}) + end) + end + end + end) end self:calculate_stats(true) @@ -717,7 +759,7 @@ function Player:shoot(r, mods) 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 + elseif self.character == 'archer' or self.character == 'hunter' or self.character == 'barrager' then 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} @@ -957,7 +999,7 @@ function Projectile:on_collision_enter(other, contact) else r = 0 end if other:is(Wall) then - if self.character == 'archer' or self.character == 'hunter' or self.character == 'barrage' then + if self.character == 'archer' or self.character == 'hunter' or self.character == 'barrage' or self.character == 'barrager' then if self.ricochet <= 0 then self:die(x, y, r, 0) WallArrow{group = main.current.main, x = x, y = y, r = self.r, color = self.color} @@ -1029,7 +1071,7 @@ 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 == 'bard' or self.character == 'assassin' then + self.character == 'bard' or self.character == 'assassin' or self.character == 'barrager' 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} @@ -1101,6 +1143,10 @@ function Projectile:on_trigger_enter(other, contact) for i = 1, 3 do HitParticle{group = main.current.effects, x = other.x, y = other.y, color = other.color, v = random:float(100, 400)} end HitCircle{group = main.current.effects, x = other.x, y = other.y, rs = 12, color = fg[0], duration = 0.3}:scale_down():change_color(0.5, self.color) end + + if self.knockback then + other:push(self.knockback, self.r) + end end end @@ -1216,6 +1262,7 @@ function DotArea:init(args) 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') + elseif self.character == 'cryomancer' then self.t:every(2, function() local enemies = main.current.main:get_objects_in_shape(self.shape, main.current.enemies) @@ -1233,6 +1280,27 @@ function DotArea:init(args) 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') + + elseif self.character == 'bane' then + if self.level == 3 then + self.t:every(0.5, function() + local enemies = main.current.main:get_objects_in_shape(self.shape, main.current.enemies) + if #enemies > 0 then + self.spring:pull(0.05, 200, 10) + buff1:play{pitch = random:float(0.8, 1.2), volume = 0.1} + end + for _, enemy in ipairs(enemies) do + enemy:curse('bane', 0.5) + if self.level == 3 then + enemy:slow(0.5, 0.5) + enemy:hit(self.dmg/2) + 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 + end, nil, nil, 'dot') + end end self.color = fg[0] @@ -1280,6 +1348,146 @@ end +ForceArea = Object:extend() +ForceArea:implement(GameObject) +ForceArea:implement(Physics) +function ForceArea:init(args) + self:init_game_object(args) + self.shape = Circle(self.x, self.y, self.rs) + + 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) + + self.vr = 0 + self.dvr = random:table{random:float(-6*math.pi, -4*math.pi), random:float(4*math.pi, 6*math.pi)} + + if self.character == 'psykino' then + elementor1:play{pitch = random:float(0.9, 1.1), volume = 0.5} + self.t:tween(2, self, {dvr = 0}, math.linear) + + self.t:during(2, function() + local enemies = main.current.main:get_objects_in_shape(self.shape, main.current.enemies) + local t = self.t:get_during_elapsed_time('psykino') + for _, enemy in ipairs(enemies) do + enemy:apply_steering_force(600*(1-t), enemy:angle_to_point(self.x, self.y)) + end + end, nil, 'psykino') + self.t:after(2 - 0.35, function() + self.t:every_immediate(0.05, function() self.hidden = not self.hidden end, 7, function() self.dead = true end) + if self.level == 3 then + elementor1:play{pitch = random:float(0.9, 1.1), volume = 0.5} + local enemies = main.current.main:get_objects_in_shape(self.shape, main.current.enemies) + for _, enemy in ipairs(enemies) do + enemy:hit(4*self.parent.dmg) + enemy:push(50, self:angle_to_object(enemy)) + end + end + end) + end +end + + +function ForceArea:update(dt) + self:update_game_object(dt) + self.vr = self.vr + self.dvr*dt +end + + +function ForceArea: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, 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 + + + +Tree = Object:extend() +Tree:implement(GameObject) +Tree:implement(Physics) +function Tree: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.heal_sensor = Circle(self.x, self.y, args.rs) + + self.vr = 0 + self.dvr = random:float(-math.pi/4, math.pi/4) + + buff1:play{pitch = random:float(0.95, 1.05), volume = 0.5} + + 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) + + self.t:cooldown(3.33/(self.level == 3 and 2 or 1), function() return #self:get_objects_in_shape(self.heal_sensor, {Player}) > 0 end, function() + local n = n or random:int(3, 4) + for i = 1, n do HitParticle{group = main.current.effects, x = self.x, y = self.y, r = random:float(0, 2*math.pi), color = self.color} end + heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5} + local units = self:get_objects_in_shape(self.heal_sensor, {Player}) + if self.level == 3 then + 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)) + LightningLine{group = main.current.effects, src = self, dst = unit_1, color = green[0]} + end + if unit_2 then + unit_2:heal(0.2*unit_2.max_hp*(self.heal_effect_m or 1)) + LightningLine{group = main.current.effects, src = self, dst = unit_2, color = green[0]} + end + HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = green[0], duration = 0.1} + else + local unit = random:table(units) + unit:heal(0.2*unit.max_hp*(self.heal_effect_m or 1)) + HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = green[0], duration = 0.1} + LightningLine{group = main.current.effects, src = self, dst = unit, color = green[0]} + end + end) + + self.t:after(10*(self.parent.conjurer_buff_m or 1), function() + self.t:every_immediate(0.05, function() self.hidden = not self.hidden end, 7, function() self.dead = true end) + end) +end + + +function Tree:update(dt) + self:update_game_object(dt) + self.vr = self.vr + self.dvr*dt +end + + +function Tree: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, self.heal_sensor.rs, self.color_transparent) + local lw = math.remap(self.heal_sensor.rs, 32, 256, 2, 4) + for i = 1, 4 do graphics.arc('open', self.x, self.y, self.heal_sensor.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 + + + + Turret = Object:extend() Turret:implement(GameObject) Turret:implement(Physics) diff --git a/todo b/todo index 02d48a2..9347148 100644 --- a/todo +++ b/todo @@ -72,14 +72,14 @@ * 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 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 + * Carver [conjurer, 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 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 + * Barrager [ranger, forcer]: shoots a barrage of 5 arrows that knocks enemies back - Lv.3: every 3rd attack the barrage shoots 15 projectiles and they push harder Highlander [warrior]: creates a small area that deals massive damage - Lv.3: Crosscut - two crosscutting areas of larger size are created instead Sapper [enchanter, voider, healer]: periodically steals health from nearby enemies and gain increased movement speed - Lv.3: Enduring Sap - sapped enemies permanently take damage over time, even outside the sapper's area of effect Priest [healer]: heals all units periodically - Lv.3: Divine Intervention - at the start of the round pick 3 units at random and grants them a buff that prevents them from dying once - Infestor [curser, swarmer]: curses enemies in an area for 6 seconds, they will release multiple critters on death - Lv.3: Infestation - triples the number of critters released + Infestor [curser, swarmer]: curses nearby enemies for 6 seconds, they will release multiple critters on death - Lv.3: Infestation - triples the number of critters released Flagellant [psyker, enchanter]: periodically deals damage to self and grants a damage buff to all allies - Lv.3: Zealotry - deals damage to all allies instead and also grants a massive damage buff Sets Ranger = 8/8 @@ -93,7 +93,7 @@ Psyker = 4/4 Healer = 5/5 Enchanter = 5/5 - Curser = 6/6 + Curser = 5/5 Swarmer = 4/4 10. Items