master
a327ex 2021-04-01 22:59:26 -03:00
parent a766914dc7
commit 32cb666cd3
12 changed files with 202 additions and 133 deletions

View File

@ -31,6 +31,7 @@ function Arena:on_enter(from, level, units)
self.main:disable_collision_between('enemy_projectile', 'enemy_projectile')
self.main:enable_trigger_between('projectile', 'enemy')
self.main:enable_trigger_between('enemy_projectile', 'player')
self.main:enable_trigger_between('player', 'enemy_projectile')
self.damage_dealt = 0
self.damage_taken = 0

Binary file not shown.

Binary file not shown.

View File

@ -31,15 +31,15 @@ function BuyScreen:on_enter(from, level, units)
self.units = units
camera.x, camera.y = gw/2, gh/2
steam.friends.setRichPresence('steam_display', '#StatusFull')
steam.friends.setRichPresence('text', 'Shop - Level ' .. self.level)
if self.level == 0 then
cascade_instance = cascade:play{volume = 0.5, loop = true}
self.level = 1
self.first_screen = true
end
steam.friends.setRichPresence('steam_display', '#StatusFull')
steam.friends.setRichPresence('text', 'Shop - Level ' .. self.level)
self.main = Group()
self.effects = Group()
self.ui = Group()
@ -153,9 +153,19 @@ end
function BuyScreen:set_cards(level, dont_spawn_effect)
if self.cards then for i = 1, 3 do if self.cards[i] then self.cards[i]:die(dont_spawn_effect) end end end
self.cards = {}
self.cards[1] = ShopCard{group = self.main, x = 60, y = 75, w = 80, h = 90, unit = random:table(tier_to_characters[random:weighted_pick(unpack(level_to_tier_weights[level or self.level]))]), parent = self, i = 1}
self.cards[2] = ShopCard{group = self.main, x = 140, y = 75, w = 80, h = 90, unit = random:table(tier_to_characters[random:weighted_pick(unpack(level_to_tier_weights[level or self.level]))]), parent = self, i = 2}
self.cards[3] = ShopCard{group = self.main, x = 220, y = 75, w = 80, h = 90, unit = random:table(tier_to_characters[random:weighted_pick(unpack(level_to_tier_weights[level or self.level]))]), parent = self, i = 3}
local all_units = {}
local unit_1
local unit_2
local unit_3
repeat
unit_1 = random:table(tier_to_characters[random:weighted_pick(unpack(level_to_tier_weights[level or self.level]))])
unit_2 = random:table(tier_to_characters[random:weighted_pick(unpack(level_to_tier_weights[level or self.level]))])
unit_3 = random:table(tier_to_characters[random:weighted_pick(unpack(level_to_tier_weights[level or self.level]))])
all_units = {unit_1, unit_2, unit_3}
until not table.all(all_units, function(v) return table.any(non_attacking_characters, function(u) return v == u end) end)
self.cards[1] = ShopCard{group = self.main, x = 60, y = 75, w = 80, h = 90, unit = unit_1, parent = self, i = 1}
self.cards[2] = ShopCard{group = self.main, x = 140, y = 75, w = 80, h = 90, unit = unit_2, parent = self, i = 2}
self.cards[3] = ShopCard{group = self.main, x = 220, y = 75, w = 80, h = 90, unit = unit_3, parent = self, i = 3}
end

View File

@ -759,3 +759,17 @@ objects and the last thing I need is random bugs because a function or variable
# Day 42 - 30/03/21
Added a spawn marker so that it's easier for the player to tell where enemies are spawning and to give a chance to avoid unfair deaths. Slowly getting back into it now...
# Day 44 - 01/04/21
* Added a spawn marker before enemies spawn to help with avoiding enemies spawning on top of the player
* Prevent spawning of units that cost 3 or more gold on the first level
* Prevent spawning of only units that don't attack on the first level
* Reworked position based units so that position in the snake doesn't matter anymore
* Chronomancer now gives +10/20/30% attack speed to all allies
* Psykeeper now stores damage taken by all allies up to 10/20/30% its max HP and redistributes it as healing
* Squire now gives +5/10/15% damage and defense to all allies
* Added enemy modifiers
* green - Grant nearby enemies a speed boost on death
* blue - Explode into projectiles on death
* orange - Charge up and headbutt towards the player at increased speed and damage

View File

@ -8,10 +8,49 @@ function Seeker:init(args)
self:set_as_rectangle(14, 6, 'dynamic', 'enemy')
self:set_restitution(0.5)
self.color = red[0]
self.color = red[0]:clone()
self.classes = {'seeker'}
self:calculate_stats(true)
self:set_as_steerable(self.v, 2000, 4*math.pi, 4)
if random:bool(35) then
local n = random:int(1, 3)
self.speed_booster = n == 1
self.exploder = n == 2
self.headbutter = n == 3
end
if self.speed_booster then
self.color = green[0]:clone()
self.area_sensor = Circle(self.x, self.y, 128)
elseif self.exploder then
self.color = blue[0]:clone()
elseif self.headbutter then
self.color = orange[0]:clone()
self.last_headbutt_time = 0
self.t:every(function() return math.distance(self.x, self.y, main.current.player.x, main.current.player.y) < 64 and love.timer.getTime() - self.last_headbutt_time > 10 end, function()
if self.headbutt_charging or self.headbutting then return end
self.headbutt_charging = true
self.t:tween(2, self.color, {r = fg[0].r, b = fg[0].b, g = fg[0].g}, math.cubic_in_out, function()
self.t:tween(0.25, self.color, {r = orange[0].r, b = orange[0].b, g = orange[0].g}, math.linear)
self.headbutt_charging = false
headbutt1:play{pitch = random:float(0.95, 1.05), volume = 0.2}
self.headbutting = true
self.last_headbutt_time = love.timer.getTime()
self:set_damping(0)
self:apply_steering_impulse(300, self:angle_to_object(main.current.player), 0.75)
self.t:after(0.75, function()
self.headbutting = false
end)
end)
end)
elseif self.tank then
self.color = yellow[0]:clone()
elseif self.shooter then
self.color = white[0]:clone()
elseif self.spawner then
self.color = purple[0]:clone()
end
end
@ -21,6 +60,15 @@ function Seeker:update(dt)
if main.current.mage_level == 2 then self.buff_def_a = -30
elseif main.current.mage_level == 1 then self.buff_def_a = -15
else self.buff_def_a = 0 end
if self.speed_boosting then
local n = math.remap(love.timer.getTime() - self.speed_boosting, 0, 3, 1, 0.5)
self.buff_mvspd_m = (3 + 0.1*self.level)*n
if not self.speed_booster and not self.exploder and not self.headbutter and not self.tank and not self.shooter and not self.spawner then
self.color.r = math.remap(n, 1, 0.5, green[0].r, red[0].r)
self.color.g = math.remap(n, 1, 0.5, green[0].g, red[0].g)
self.color.b = math.remap(n, 1, 0.5, green[0].b, red[0].b)
end
end
self:calculate_stats()
if self.being_pushed then
@ -32,13 +80,20 @@ function Seeker:update(dt)
self:set_angular_damping(0)
end
else
local player = main.current.player
self:seek_point(player.x, player.y)
self:wander(50, 100, 20)
self:steering_separate(16, main.current.enemies)
self:rotate_towards_velocity(0.5)
if self.headbutt_charging then
self:set_damping(10)
self:rotate_towards_object(main.current.player, 0.5)
elseif not self.headbutting then
local player = main.current.player
self:seek_point(player.x, player.y)
self:wander(50, 100, 20)
self:steering_separate(16, main.current.enemies)
self:rotate_towards_velocity(0.5)
end
end
self.r = self:get_angle()
if self.area_sensor then self.area_sensor:move_to(self.x, self.y) end
end
@ -64,6 +119,12 @@ function Seeker:on_collision_enter(other, contact)
HitCircle{group = main.current.effects, x = x, y = y, rs = 6, color = fg[0], duration = 0.1}
for i = 1, 2 do HitParticle{group = main.current.effects, x = x, y = y, color = self.color} end
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
elseif self.headbutting then
other:push(math.length(self:get_velocity())/4, other:angle_to_object(self))
HitCircle{group = main.current.effects, x = x, y = y, rs = 6, color = fg[0], duration = 0.1}
for i = 1, 2 do HitParticle{group = main.current.effects, x = x, y = y, color = self.color} end
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
end
elseif other:is(Turret) then
@ -88,6 +149,27 @@ function Seeker:hit(damage)
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 12}:scale_down(0.3):change_color(0.5, self.color)
main.current:enemy_killed()
_G[random:table{'enemy_die1', 'enemy_die2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.5}
if self.speed_booster then
local enemies = self:get_objects_in_shape(self.area_sensor, main.current.enemies)
if #enemies > 0 then
buff1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = green[0], duration = 0.1}
for _, enemy in ipairs(enemies) do
LightningLine{group = main.current.effects, src = self, dst = enemy, color = green[0]}
enemy:speed_boost(3)
end
end
end
if self.exploder then
shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.4}
trigger:after(0.01, function()
for i = 1, 16 do
EnemyProjectile{group = main.current.main, x = self.x, y = self.y, color = blue[0], r = (i-1)*math.pi/8, v = 150 + 5*self.level, dmg = 2*self.dmg}
end
end)
end
end
end
@ -103,6 +185,12 @@ function Seeker:push(f, r)
end
function Seeker:speed_boost(duration)
self.speed_boosting = love.timer.getTime()
self.t:after(duration, function() self.speed_boosting = false end, 'speed_boost')
end
EnemyProjectile = Object:extend()
@ -137,6 +225,7 @@ function EnemyProjectile:die(x, y, r, n)
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
proj_hit_wall1:play{pitch = random:float(0.9, 1.1), volume = 0.05}
end

View File

@ -46,7 +46,7 @@ function Physics:steering_update(dt)
self.side = self.heading:perpendicular()
end
self.apply_force_f:set(0, 0)
self.apply_impulse_f:set(0, 0)
-- self.apply_impulse_f:set(0, 0)
end
end

View File

@ -24,6 +24,7 @@ function init()
ui_switch2 = Sound('Switch 3.ogg', s)
ui_transition1 = Sound('Wind Bolt 8.ogg', s)
ui_transition2 = Sound('Wind Bolt 12.ogg', s)
headbutt1 = Sound('Wind Bolt 14.ogg', s)
error1 = Sound('Error 2.ogg', s)
coins1 = Sound('Coins 7.ogg', s)
coins2 = Sound('Coins 8.ogg', s)
@ -58,6 +59,7 @@ function init()
confirm1 = Sound('80921__justinbw__buttonchime02up.ogg', s)
heal1 = Sound('Buff 3.ogg', s)
spawn1 = Sound('Buff 13.ogg', s)
buff1 = Sound('Buff 14.ogg', s)
spawn_mark1 = Sound('Bonus 2.ogg', s)
spawn_mark2 = Sound('Bonus.ogg', s)
alert1 = Sound('Click.ogg', s)
@ -282,6 +284,8 @@ function init()
[3] = {'blade', 'outlaw', 'elementor', 'psykeeper', 'spellblade', 'engineer'},
}
non_attacking_characters = {'cleric', 'stormweaver', 'squire', 'chronomancer', 'sage'}
character_tiers = {
['vagrant'] = 1,
['swordsman'] = 1,
@ -352,7 +356,7 @@ function init()
}
level_to_tier_weights = {
[1] = {85, 10, 5},
[1] = {90, 10, 0},
[2] = {80, 15, 5},
[3] = {75, 20, 5},
[4] = {70, 20, 10},

View File

@ -48,11 +48,11 @@ function LightningLine:init(args)
self.max_offset = 8
self:generate()
self.t:tween(0.1, self, {w = 1}, math.linear, function() self.dead = true end)
self.color = blue[0]
self.color = args.color or blue[0]
HitCircle{group = main.current.effects, x = self.src.x, y = self.src.y, rs = 6, color = fg[0], duration = 0.1}
for i = 1, 2 do HitParticle{group = main.current.effects, x = self.src.x, y = self.src.y, color = blue[0]} end
for i = 1, 2 do HitParticle{group = main.current.effects, x = self.src.x, y = self.src.y, color = self.color} end
HitCircle{group = main.current.effects, x = self.dst.x, y = self.dst.y, rs = 6, color = fg[0], duration = 0.1}
HitParticle{group = main.current.effects, x = self.dst.x, y = self.dst.y, color = blue[0]}
HitParticle{group = main.current.effects, x = self.dst.x, y = self.dst.y, color = self.color}
end
@ -214,20 +214,6 @@ function Unit:show_infused(n)
end
function Unit:show_squire(n)
self.effect_bar.hidden = false
self.effect_bar.color = purple[0]
self.t:after(n or 4, function() self.effect_bar.hidden = false end, 'effect_bar')
end
function Unit:show_chronomancer(n)
self.effect_bar.hidden = false
self.effect_bar.color = purple[0]
self.t:after(n or 2, function() self.effect_bar.hidden = false end, 'effect_bar')
end
function Unit:calculate_damage(dmg)
if self.def >= 0 then dmg = dmg*(100/(100+self.def))
else dmg = dmg*(2 - 100/(100+self.def)) end
@ -300,6 +286,7 @@ function Unit:calculate_stats(first_run)
self.def = (self.base_def + self.class_def_a + self.buff_def_a)*self.class_def_m*self.buff_def_m
for _, class in ipairs(self.classes) do self.class_mvspd_m = self.class_mvspd_m*class_stat_multipliers[class].mvspd end
self.max_v = (self.base_mvspd + self.class_mvspd_a + self.buff_mvspd_a)*self.class_mvspd_m*self.buff_mvspd_m
self.v = (self.base_mvspd + self.class_mvspd_a + self.buff_mvspd_a)*self.class_mvspd_m*self.buff_mvspd_m
end

View File

@ -1,3 +1,13 @@
Release Patch Notes
Added a spawn marker before enemies spawn to help with avoiding enemies spawning on top of the player
Prevent spawning of units that cost 3 or more gold on the first level
Prevent spawning of only units that don't attack on the first level
Reworked position based units so that position in the snake doesn't matter anymore
Chronomancer now gives +10/20/30% attack speed to all allies
Psykeeper now stores damage taken by all allies up to 10/20/30% its max HP and redistributes it as healing
Squire now gives +5/10/15% damage and defense to all allies
Added enemy modifiers
green - Grant nearby enemies a speed boost on death
blue - Explode into projectiles on death
orange - Charge up and headbutt towards the player at increased speed and damage

View File

@ -81,13 +81,10 @@ function Player:init(args)
self.last_heal_time = love.timer.getTime()
self.t:every(2, function()
local followers
local leader = (self.leader and self) or self.parent
if self.leader then followers = self.followers else followers = self.parent.followers end
if (table.any(followers, function(v) return v.hp <= 0.5*v.max_hp end) or (leader.hp <= 0.5*leader.max_hp)) and love.timer.getTime() - self.last_heal_time > 6 then
local all_units = self:get_all_units()
if table.any(all_units, function(v) return v.hp <= 0.5*v.max_hp end) and love.timer.getTime() - self.last_heal_time > 6 then
self.last_heal_time = love.timer.getTime()
if self.leader then self:heal(0.1*self.max_hp*(self.heal_effect_m or 1)) else self.parent:heal(0.1*self.parent.max_hp*(self.heal_effect_m or 1)) end
for _, f in ipairs(followers) do f:heal(0.1*f.max_hp*(self.heal_effect_m or 1)) end
for _, unit in ipairs(all_units) do unit:heal(0.1*unit.max_hp*(self.heal_effect_m or 1)) end
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
end
end)
@ -183,21 +180,6 @@ function Player:init(args)
self.visual_shape = 'rectangle'
self.classes = character_classes.squire
self.t:every(8, function()
self.applying_buff = true
local followers
local leader = (self.leader and self) or self.parent
if self.leader then followers = self.followers else followers = self.parent.followers end
local next_character = followers[(self.follower_index or 0) + 1]
local previous_character = followers[(self.follower_index or 0) - 1]
if next_character then next_character:squire_buff(8) end
if previous_character then previous_character:squire_buff(8) end
self.t:after(8, function() self.applying_buff = false end, 'squire_buff_apply')
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
if next_character then next_character:heal(0.1*next_character.max_hp*(self.heal_effect_m or 1)) end
if previous_character then previous_character:heal(0.1*previous_character.max_hp*(self.heal_effect_m or 1)) end
end)
elseif self.character == 'cannoneer' then
self.color = character_colors.cannoneer
self:set_as_rectangle(9, 9, 'dynamic', 'player')
@ -246,16 +228,6 @@ function Player:init(args)
self.visual_shape = 'rectangle'
self.classes = character_classes.chronomancer
self.t:every(2, function()
local followers
local leader = (self.leader and self) or self.parent
if self.leader then followers = self.followers else followers = self.parent.followers end
local next_character = followers[(self.follower_index or 0) + 1]
local previous_character = followers[(self.follower_index or 0) - 1]
if next_character then next_character:chronomancer_buff(2) end
if previous_character then previous_character:chronomancer_buff(2) end
end)
elseif self.character == 'spellblade' then
self.color = character_colors.spellblade
self:set_as_rectangle(9, 9, 'dynamic', 'player')
@ -272,21 +244,6 @@ function Player:init(args)
self.visual_shape = 'rectangle'
self.classes = character_classes.psykeeper
self.psykeeper_heal = 0
self.t:every(8, function()
local followers
local leader = (self.leader and self) or self.parent
if self.leader then followers = self.followers else followers = self.parent.followers end
if self.psykeeper_heal > 0 then
local heal_amount = math.floor(self.psykeeper_heal/(#followers+1))
if self.leader then self:heal(heal_amount*(self.heal_effect_m or 1)) else self.parent:heal(heal_amount*(self.heal_effect_m or 1)) end
for _, f in ipairs(followers) do f:heal(heal_amount*(self.heal_effect_m or 1)) end
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
self.psykeeper_heal = 0
end
end)
elseif self.character == 'engineer' then
self.color = character_colors.engineer
self:set_as_rectangle(9, 9, 'dynamic', 'player')
@ -317,39 +274,16 @@ function Player:update(dt)
self:update_game_object(dt)
if self.character == 'squire' then
local followers
local leader = (self.leader and self) or self.parent
if self.leader then followers = self.followers else followers = self.parent.followers end
local next_character = followers[(self.follower_index or 0) + 1]
local previous_character = followers[(self.follower_index or 0) - 1]
if self.applying_buff then
if next_character then
next_character.squire_dmg_a = 10
next_character.squire_def_a = 25
end
if previous_character then
previous_character.squire_dmg_a = 10
previous_character.squire_def_a = 25
end
else
if next_character then
next_character.squire_dmg_a = 0
next_character.squire_def_a = 0
end
if previous_character then
previous_character.squire_dmg_a = 0
previous_character.squire_def_a = 0
end
local all_units = self:get_all_units()
for _, unit in ipairs(all_units) do
unit.squire_dmg_m = 1 + 0.05*self.level
unit.squire_def_m = 1 + 0.05*self.level
end
elseif self.character == 'chronomancer' then
local followers
local leader = (self.leader and self) or self.parent
if self.leader then followers = self.followers else followers = self.parent.followers end
local next_character = followers[(self.follower_index or 0) + 1]
local previous_character = followers[(self.follower_index or 0) - 1]
if next_character then next_character.chronomancer_aspd_m = 1.25 end
if previous_character then previous_character.chronomancer_aspd_m = 1.25 end
local all_units = self:get_all_units()
for _, unit in ipairs(all_units) do
unit.chronomancer_aspd_m = 1 + 0.10*self.level
end
end
if table.any(self.classes, function(v) return v == 'ranger' end) then
@ -391,10 +325,10 @@ function Player:update(dt)
else self.enchanter_dmg_m = 1 end
end
self.buff_dmg_a = (self.squire_dmg_a or 0)
self.buff_def_a = (self.squire_def_a or 0) + (self.warrior_def_a or 0)
self.buff_def_a = (self.warrior_def_a or 0)
self.buff_aspd_m = (self.chronomancer_aspd_m or 1)
self.buff_dmg_m = (main.current.enchanter_dmg_m or 1)
self.buff_dmg_m = (self.squire_dmg_m or 1)*(main.current.enchanter_dmg_m or 1)
self.buff_def_m = (self.squire_def_m or 1)
self.buff_area_size_m = (self.nuker_area_size_m or 1)
self.buff_area_dmg_m = (self.nuker_area_dmg_m or 1)
self:calculate_stats()
@ -492,7 +426,9 @@ function Player:on_collision_enter(other, contact)
other:push(random:float(25, 35), self:angle_to_object(other))
if self.character == 'vagrant' or self.character == 'psykeeper' then other:hit(2*self.dmg)
else other:hit(self.dmg) end
self:hit(other.dmg)
if other.headbutting then
self:hit((4 + math.floor(other.level/3))*other.dmg)
else self:hit(other.dmg) end
HitCircle{group = main.current.effects, x = x, y = y, rs = 6, color = fg[0], duration = 0.1}
for i = 1, 2 do HitParticle{group = main.current.effects, x = x, y = y, color = self.color} end
for i = 1, 2 do HitParticle{group = main.current.effects, x = x, y = y, color = other.color} end
@ -511,7 +447,18 @@ function Player:hit(damage)
camera:shake(4, 0.5)
main.current.damage_taken = main.current.damage_taken + actual_damage
if self.character == 'psykeeper' then self.psykeeper_heal = self.psykeeper_heal + actual_damage end
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
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))
end
psykeeper.stored_heal = 0
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
end
end
if self.hp <= 0 then
hit4:play{pitch = random:float(0.95, 1.05), volume = 0.5}
@ -542,18 +489,23 @@ end
function Player:chain_infuse(duration)
self.chain_infused = true
self:show_infused(duration or 2)
self.t:after(duration or 2, function() self.chain_infused = false end, 'chain_infuse')
end
function Player:squire_buff(duration)
self:show_squire(duration or 2)
function Player:get_all_units()
local followers
local leader = (self.leader and self) or self.parent
if self.leader then followers = self.followers else followers = self.parent.followers end
return {leader, unpack(followers)}
end
function Player:chronomancer_buff(duration)
self:show_chronomancer(duration or 2)
function Player:get_unit(character)
local all_units = self:get_all_units()
for _, unit in ipairs(all_units) do
if unit.character == character then return unit end
end
end

32
todo
View File

@ -1,26 +1,24 @@
* 1. Enemy spawn points should have some markers before enemy spawns, or should avoid spawning near the player at all
2. Prevent spawning of units that cost 3 on first level
3. Prevent spawning of units that don't attack on first level
* 2. Prevent spawning of units that cost 3 on first level
* 3. Prevent spawning of units that don't attack on first level
4. Rework position based units so that position in the snake doesn't matter
Chronomancer: +10%/20%/30% attack speed to all allies
Psykeeper: stores damage taken by all allies up to 20% max HP and redistributes it as healing
Squire: +5%/10%/15% damage and defense to all allies
* 4. Rework position based units so that position in the snake doesn't matter
* Chronomancer: +10%/20%/30% attack speed to all allies
* Psykeeper: stores damage taken by all allies up to 50% its max HP and redistributes it as healing
* Squire: +5%/10%/15% damage and defense to all allies
5. Stat details to each unit when hovering over it in the party section
7. Enemy modifiers
* green - Grant nearby enemies a speed boost on death
* blue - Explode into projectiles on death
* orange - Charge up and headbutt towards the player at increased speed and damage
yellow - Resistance to knockback
white - Remain static and shoot projectiles
purple - Explodes into critters on death
6. Mini boss every 3rd level
This is just a special enemy with more HP and ability to buff nearby enemies with modifiers, no additional AI or attack patterns
... aiming for ~5 different modifier combos that the boss uses
7. Enemy modifiers
Grant nearby enemies a speed boost on death
Grant nearby enemies a damage boost on death
Explode into projectiles on death
Charge up and headbutt towards the player at increased speed and damage
Resistance to knockback
... aiming for about 8-10 of these
8. Additional characters and classes
9. Lv.3 effects for every character
Classes
@ -114,6 +112,9 @@
Call of the Void: +25% DoT damage
... more ideas will come later I'm sure, aiming for 30 total items
5. Stat and description details to each unit when hovering over it in the party section
6. Classes line on each unit's shop card, as well as on party section
11. Steam integration: achievements, etc
12. Hovering over a party member should show which set they belong to and vice-versa
13. Show a unit DPS list like Underlord's to the right side of the screen
@ -128,6 +129,7 @@
Boss ideas
Pretends to be dead, grants speed buffs to enemies after death, especially if the round has gone on for too long which means the player is surviving with 1 unit
Uses Psykino's tech to pull enemies together into a point and have that point move around and bounce on edges, thus having a ball of enemies moving around that occasionally explodes
Map modifiers
Wall spikes: walls damage you when you hit it