Item update 3/5

master
a327ex 2021-06-17 02:45:14 -03:00
parent e99644a45b
commit 31a7a403e3
8 changed files with 297 additions and 109 deletions

View File

@ -397,7 +397,7 @@ function Arena:update(dt)
passives = {} passives = {}
main_song_instance:stop() main_song_instance:stop()
run_passive_pool = { run_passive_pool = {
'centipede', 'ouroboros_technique_r', 'ouroboros_technique_l', 'amplify', 'resonance', 'ballista', 'call_of_the_void', 'crucio', 'speed_3', 'damage_4', 'level_5', 'death_6', 'lasting_7', 'centipede', 'ouroboros_technique_r', 'ouroboros_technique_l', 'amplify', 'resonance', 'ballista', 'call_of_the_void', 'crucio', 'speed_3', 'damage_4', 'shoot_5', 'death_6', 'lasting_7',
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'pandemic', 'whispers_of_doom', 'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'pandemic', 'whispers_of_doom',
'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment', 'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment',
'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism', 'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism',
@ -585,7 +585,7 @@ function Arena:update(dt)
passives = {} passives = {}
main_song_instance:stop() main_song_instance:stop()
run_passive_pool = { run_passive_pool = {
'centipede', 'ouroboros_technique_r', 'ouroboros_technique_l', 'amplify', 'resonance', 'ballista', 'call_of_the_void', 'crucio', 'speed_3', 'damage_4', 'level_5', 'death_6', 'lasting_7', 'centipede', 'ouroboros_technique_r', 'ouroboros_technique_l', 'amplify', 'resonance', 'ballista', 'call_of_the_void', 'crucio', 'speed_3', 'damage_4', 'shoot_5', 'death_6', 'lasting_7',
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'pandemic', 'whispers_of_doom', 'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'pandemic', 'whispers_of_doom',
'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment', 'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment',
'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism', 'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism',
@ -998,7 +998,7 @@ function Arena:die()
passives = {} passives = {}
main_song_instance:stop() main_song_instance:stop()
run_passive_pool = { run_passive_pool = {
'centipede', 'ouroboros_technique_r', 'ouroboros_technique_l', 'amplify', 'resonance', 'ballista', 'call_of_the_void', 'crucio', 'speed_3', 'damage_4', 'level_5', 'death_6', 'lasting_7', 'centipede', 'ouroboros_technique_r', 'ouroboros_technique_l', 'amplify', 'resonance', 'ballista', 'call_of_the_void', 'crucio', 'speed_3', 'damage_4', 'shoot_5', 'death_6', 'lasting_7',
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'pandemic', 'whispers_of_doom', 'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'pandemic', 'whispers_of_doom',
'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment', 'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment',
'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism', 'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism',

View File

Before

Width:  |  Height:  |  Size: 440 B

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

Binary file not shown.

View File

@ -143,7 +143,7 @@ function BuyScreen:on_enter(from, level, units, passives, shop_level, shop_xp)
passives = {} passives = {}
main_song_instance:stop() main_song_instance:stop()
run_passive_pool = { run_passive_pool = {
'centipede', 'ouroboros_technique_r', 'ouroboros_technique_l', 'amplify', 'resonance', 'ballista', 'call_of_the_void', 'crucio', 'speed_3', 'damage_4', 'level_5', 'death_6', 'lasting_7', 'centipede', 'ouroboros_technique_r', 'ouroboros_technique_l', 'amplify', 'resonance', 'ballista', 'call_of_the_void', 'crucio', 'speed_3', 'damage_4', 'shoot_5', 'death_6', 'lasting_7',
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'pandemic', 'whispers_of_doom', 'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'pandemic', 'whispers_of_doom',
'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment', 'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment',
'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism', 'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism',
@ -384,7 +384,7 @@ function BuyScreen:set_items()
local y = 182 local y = 182
for k, passive in ipairs(self.passives) do for k, passive in ipairs(self.passives) do
local i, j = math.index_to_coordinates(k, 4) local i, j = math.index_to_coordinates(k, 4)
table.insert(self.items, ItemCard{group = self.main, x = 45 + (i-1)*60, y = y + (j-1)*50, w = 40, h = 50, passive = passive.passive , level = passive.level, xp = passive.xp}) table.insert(self.items, ItemCard{group = self.main, x = 45 + (i-1)*60, y = y + (j-1)*50, w = 40, h = 50, passive = passive.passive , level = passive.level, xp = passive.xp, parent = self})
end end
end end
@ -530,7 +530,7 @@ function RestartButton:update(dt)
passives = {} passives = {}
main_song_instance:stop() main_song_instance:stop()
run_passive_pool = { run_passive_pool = {
'centipede', 'ouroboros_technique_r', 'ouroboros_technique_l', 'amplify', 'resonance', 'ballista', 'call_of_the_void', 'crucio', 'speed_3', 'damage_4', 'level_5', 'death_6', 'lasting_7', 'centipede', 'ouroboros_technique_r', 'ouroboros_technique_l', 'amplify', 'resonance', 'ballista', 'call_of_the_void', 'crucio', 'speed_3', 'damage_4', 'shoot_5', 'death_6', 'lasting_7',
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'pandemic', 'whispers_of_doom', 'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'pandemic', 'whispers_of_doom',
'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment', 'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment',
'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism', 'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism',
@ -853,7 +853,7 @@ function LevelButton:create_info_text()
local t41, t42 = get_shop_odds(self.parent.shop_level, 4), get_shop_odds(self.parent.shop_level+1, 4) local t41, t42 = get_shop_odds(self.parent.shop_level, 4), get_shop_odds(self.parent.shop_level+1, 4)
self.info_text = InfoText{group = main.current.ui} self.info_text = InfoText{group = main.current.ui}
self.info_text:activate({ self.info_text:activate({
{text = '[yellow]Lv.' .. self.parent.shop_level .. '[fg] shop, XP: [yellow]' .. self.shop_xp .. '/' .. self.max_xp, font = pixul_font, alignment = 'center', height_multiplier = 1.5}, {text = '[yellow]Lv.' .. self.parent.shop_level .. '[fg] shop, XP: [yellow]' .. self.shop_xp .. '/' .. self.max_xp .. '[fg], +1 XP cost: [yellow]5', font = pixul_font, alignment = 'center', height_multiplier = 1.5},
{text = '[bg10]chances of units appearing on the shop', font = pixul_font, alignment = 'center', height_multiplier = 1.25}, {text = '[bg10]chances of units appearing on the shop', font = pixul_font, alignment = 'center', height_multiplier = 1.25},
{text = '[yellow]current shop level [fgm10]next shop level', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, {text = '[yellow]current shop level [fgm10]next shop level', font = pixul_font, alignment = 'left', height_multiplier = 1.25},
{text = '[fg]tier 1: ' .. t11 .. '%' .. tostring(t11 < 10 and ' ' or '') .. ' [fgm8]tier 1: ' .. t12 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, {text = '[fg]tier 1: ' .. t11 .. '%' .. tostring(t11 < 10 and ' ' or '') .. ' [fgm8]tier 1: ' .. t12 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25},
@ -869,7 +869,7 @@ function LevelButton:create_info_text()
local t41 = get_shop_odds(self.parent.shop_level, 4) local t41 = get_shop_odds(self.parent.shop_level, 4)
self.info_text = InfoText{group = main.current.ui} self.info_text = InfoText{group = main.current.ui}
self.info_text:activate({ self.info_text:activate({
{text = '[yellow]Lv.' .. self.parent.shop_level .. '[fg] shop, XP: [yellow]' .. self.shop_xp .. '/' .. self.max_xp, font = pixul_font, alignment = 'center', height_multiplier = 1.5}, {text = '[yellow]Lv.' .. self.parent.shop_level .. '[fg] shop', font = pixul_font, alignment = 'center', height_multiplier = 1.5},
{text = '[bg10]chances of units appearing on the shop', font = pixul_font, alignment = 'center', height_multiplier = 1.25}, {text = '[bg10]chances of units appearing on the shop', font = pixul_font, alignment = 'center', height_multiplier = 1.25},
{text = '[yellow]current shop level', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, {text = '[yellow]current shop level', font = pixul_font, alignment = 'left', height_multiplier = 1.25},
{text = '[fg]tier 1: ' .. t11 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25}, {text = '[fg]tier 1: ' .. t11 .. '%', font = pixul_font, alignment = 'left', height_multiplier = 1.25},
@ -1360,11 +1360,55 @@ function ItemCard:init(args)
self:init_game_object(args) self:init_game_object(args)
self.shape = Rectangle(self.x, self.y, self.w, self.h) self.shape = Rectangle(self.x, self.y, self.w, self.h)
self.interact_with_mouse = true self.interact_with_mouse = true
self.max_xp = (self.level == 0 and 0) or (self.level == 1 and 2) or (self.level == 2 and 3) or (self.level == 3 and 0)
end end
function ItemCard:update(dt) function ItemCard:update(dt)
self:update_game_object(dt) self:update_game_object(dt)
if self.selected and input.m1.pressed then
if self.level >= 3 then return end
if gold < 5 then
self.spring:pull(0.2, 200, 10)
self.selected = true
error1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
if not self.info_text_2 then
self.info_text_2 = InfoText{group = main.current.ui}
self.info_text_2:activate({
{text = '[fg]not enough gold', font = pixul_font, alignment = 'center'},
}, nil, nil, nil, nil, 16, 4, nil, 2)
self.info_text_2.x, self.info_text_2.y = gw/2, gh/2 + 30
end
self.t:after(2, function() self.info_text_2:deactivate(); self.info_text_2.dead = true; self.info_text_2 = nil end, 'info_text_2')
else
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
self.xp = self.xp + 1
if self.xp >= self.max_xp then
self.xp = 0
self.level = self.level + 1
self.max_xp = (self.level == 0 and 0) or (self.level == 1 and 2) or (self.level == 2 and 3) or (self.level == 3 and 0)
if self.level == 2 then spawn_mark1:play{pitch = 1, volume = 0.6} end
if self.level == 3 then
spawn_mark1:play{pitch = 1.2, volume = 0.6}
level_up1:play{pitch = 1, volume = 0.5}
end
end
self:create_info_text()
self.selected = true
self.spring:pull(0.2, 200, 10)
gold = gold - 5
for _, passive in ipairs(passives) do
if passive.passive == self.passive then
passive.level = self.level
passive.xp = self.xp
end
end
self.parent.shop_text:set_text{{text = '[wavy_mid, fg]shop [fg]- [fg, nudge_down]gold: [yellow, nudge_down]' .. gold, font = pixul_font, alignment = 'center'}}
self.text = Text({{text = '[bg10]' .. tostring(self.parent.shop_level), font = pixul_font, alignment = 'center'}}, global_text_tags)
system.save_run(self.parent.level, gold, self.parent.units, passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool, locked_state)
end
end
end end
@ -1374,20 +1418,50 @@ function ItemCard:draw()
graphics.rectangle(self.x, self.y, self.w, self.h, 6, 6, bg[-1]) graphics.rectangle(self.x, self.y, self.w, self.h, 6, 6, bg[-1])
end end
_G[self.passive]:draw(self.x, self.y, 0, 0.8, 0.7, 0, 0, fg[0]) _G[self.passive]:draw(self.x, self.y, 0, 0.8, 0.7, 0, 0, fg[0])
local x, y = self.x + self.w/2.5, self.y - self.h/2.5
if self.level == 1 then
graphics.rectangle(x - 2, y, 2, 2, nil, nil, self.xp >= 1 and fg[0] or bg[5])
graphics.rectangle(x + 2, y, 2, 2, nil, nil, bg[5])
elseif self.level == 2 then
graphics.rectangle(x - 4, y, 2, 2, nil, nil, self.xp >= 1 and fg[0] or bg[5])
graphics.rectangle(x, y, 2, 2, nil, nil, self.xp >= 2 and fg[0] or bg[5])
graphics.rectangle(x + 4, y, 2, 2, nil, nil, bg[5])
end
graphics.pop() graphics.pop()
end end
function ItemCard:create_info_text()
if self.info_text then
self.info_text:deactivate()
self.info_text.dead = true
end
self.info_text = nil
if self.level == 3 then
self.info_text = InfoText{group = main.current.ui, force_update = true}
self.info_text:activate({
{text = '[fg]' .. passive_names[self.passive] .. ', [yellow]Lv.' .. self.level, font = pixul_font, alignment = 'center',
height_multiplier = 1.25},
{text = passive_descriptions_level[self.passive](self.level), font = pixul_font, alignment = 'center', height_multiplier = 1.25},
}, nil, nil, nil, nil, 16, 4, nil, 2)
self.info_text.x, self.info_text.y = gw/2, gh/2 + 10
else
self.info_text = InfoText{group = main.current.ui, force_update = true}
self.info_text:activate({
{text = '[fg]' .. passive_names[self.passive] .. ', [yellow]Lv.' .. self.level .. '[fg], XP: [yellow]' .. self.xp .. '/' .. self.max_xp .. '[fg], +1 XP cost: [yellow]5', font = pixul_font, alignment = 'center',
height_multiplier = 1.25},
{text = passive_descriptions_level[self.passive](self.level), font = pixul_font, alignment = 'center', height_multiplier = 1.25},
}, nil, nil, nil, nil, 16, 4, nil, 2)
self.info_text.x, self.info_text.y = gw/2, gh/2 + 10
end
end
function ItemCard:on_mouse_enter() function ItemCard:on_mouse_enter()
self.selected = true self.selected = true
ui_hover1:play{pitch = random:float(1.3, 1.5), volume = 0.5} ui_hover1:play{pitch = random:float(1.3, 1.5), volume = 0.5}
self.spring:pull(0.2, 200, 10) self.spring:pull(0.2, 200, 10)
self.info_text = InfoText{group = main.current.ui, force_update = true} self:create_info_text()
self.info_text:activate({
{text = '[fg]' .. passive_names[self.passive], font = pixul_font, alignment = 'center', height_multiplier = 1.25},
{text = passive_descriptions_level[self.passive](self.level), font = pixul_font, alignment = 'center', height_multiplier = 1.25},
}, nil, nil, nil, nil, 16, 4, nil, 2)
self.info_text.x, self.info_text.y = gw/2, gh/2 + 10
end end

View File

@ -18,6 +18,8 @@ function init()
input:bind('enter', {'space', 'return', 'fleft', 'fdown', 'fright'}) input:bind('enter', {'space', 'return', 'fleft', 'fdown', 'fright'})
local s = {tags = {sfx}} local s = {tags = {sfx}}
level_up1 = Sound('Buff 4.ogg', s)
unlock1 = Sound('Unlock 3.ogg', s)
gambler1 = Sound('Collect 5.ogg', s) gambler1 = Sound('Collect 5.ogg', s)
usurer1 = Sound('Shadow Punch 2.ogg', s) usurer1 = Sound('Shadow Punch 2.ogg', s)
gold1 = Sound('Collect 5.ogg', s) gold1 = Sound('Collect 5.ogg', s)
@ -153,7 +155,7 @@ function init()
crucio = Image('crucio') crucio = Image('crucio')
speed_3 = Image('speed_3') speed_3 = Image('speed_3')
damage_4 = Image('damage_4') damage_4 = Image('damage_4')
level_5 = Image('level_5') shoot_5 = Image('shoot_5')
death_6 = Image('death_6') death_6 = Image('death_6')
lasting_7 = Image('lasting_7') lasting_7 = Image('lasting_7')
defensive_stance = Image('defensive_stance') defensive_stance = Image('defensive_stance')
@ -588,7 +590,7 @@ function init()
['psychic'] = function(lvl) return '[fg]creates a small area that deals [yellow]' .. get_character_stat('psychic', lvl, 'dmg') .. ' AoE[fg] damage' end, ['psychic'] = function(lvl) return '[fg]creates a small area that deals [yellow]' .. get_character_stat('psychic', lvl, 'dmg') .. ' AoE[fg] damage' end,
['miner'] = function(lvl) return '[fg]picking up gold releases [yellow]4[fg] homing projectiles that each deal [yellow]' .. get_character_stat('miner', lvl, 'dmg') .. ' [fg]damage' end, ['miner'] = function(lvl) return '[fg]picking up gold releases [yellow]4[fg] homing projectiles that each deal [yellow]' .. get_character_stat('miner', lvl, 'dmg') .. ' [fg]damage' end,
['merchant'] = function(lvl) return '[fg]gain [yellow]+1[fg] interest for every [yellow]10[fg] gold' end, ['merchant'] = function(lvl) return '[fg]gain [yellow]+1[fg] interest for every [yellow]10[fg] gold' end,
['usurer'] = function(lvl) return '[fg]curses [yellow]3[fg] nearby enemies indefinitely with [yellow]debt[fg], dealing [yellow]' .. get_character_stat('usurer', lvl, 'dmg') .. '[fg] damage per second' end, ['usurer'] = function(lvl) return '[fg]curses [yellow]3[fg] nearby enemies indefinitely with debt, dealing [yellow]' .. get_character_stat('usurer', lvl, 'dmg') .. '[fg] damage per second' end,
['gambler'] = function(lvl) return '[fg]deal [yellow]2X[fg] damage to a single random enemy where X is how much gold you have' end, ['gambler'] = function(lvl) return '[fg]deal [yellow]2X[fg] damage to a single random enemy where X is how much gold you have' end,
['thief'] = function(lvl) return '[fg]throws a knife that deals [yellow]' .. 2*get_character_stat('thief', lvl, 'dmg') .. '[fg] damage and chains [yellow]5[fg] times' end, ['thief'] = function(lvl) return '[fg]throws a knife that deals [yellow]' .. 2*get_character_stat('thief', lvl, 'dmg') .. '[fg] damage and chains [yellow]5[fg] times' end,
} }
@ -725,7 +727,7 @@ function init()
['cannoneer'] = function() return '[fg]showers the hit area in [yellow]7[fg] additional cannon shots that deal [yellow]' .. get_character_stat('cannoneer', 3, 'dmg')/2 .. '[fg] AoE damage' end, ['cannoneer'] = function() return '[fg]showers the hit area in [yellow]7[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, ['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, ['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, ['chronomancer'] = function() return '[fg]enemies take damage over time [yellow]50%[fg] faster' end,
['spellblade'] = function() return '[fg]faster projectile speed and tighter turns' 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 at [yellow]double[fg] value' end, ['psykeeper'] = function() return '[fg]also redistributes damage taken as damage to all enemies at [yellow]double[fg] value' end,
['engineer'] = function() return '[fg]drops [yellow]2[fg] additional turrets and grants all turrets [yellow]+50%[fg] damage and attack speed' end, ['engineer'] = function() return '[fg]drops [yellow]2[fg] additional turrets and grants all turrets [yellow]+50%[fg] damage and attack speed' end,
@ -782,7 +784,7 @@ function init()
['cannoneer'] = function() return '[light_bg]showers the hit area in 7 additional cannon shots that deal ' .. get_character_stat('cannoneer', 3, 'dmg')/2 .. ' AoE damage' end, ['cannoneer'] = function() return '[light_bg]showers the hit area in 7 additional cannon shots that deal ' .. get_character_stat('cannoneer', 3, 'dmg')/2 .. ' AoE damage' end,
['dual_gunner'] = function() return '[light_bg]every 5th attack shoot in rapid succession for 2 seconds' end, ['dual_gunner'] = function() return '[light_bg]every 5th attack shoot in rapid succession for 2 seconds' end,
['hunter'] = function() return '[light_bg]summons 3 pets and the pets ricochet off walls once' end, ['hunter'] = function() return '[light_bg]summons 3 pets and the pets ricochet off walls once' end,
['chronomancer'] = function() return '[light_bg]enemies take damave over time 50% faster' end, ['chronomancer'] = function() return '[light_bg]enemies take damage over time 50% faster' end,
['spellblade'] = function() return '[light_bg]faster projectile speed and tighter turns' end, ['spellblade'] = function() return '[light_bg]faster projectile speed and tighter turns' end,
['psykeeper'] = function() return '[light_bg]also redistributes damage taken as damage to all enemies at double value' end, ['psykeeper'] = function() return '[light_bg]also redistributes damage taken as damage to all enemies at double value' end,
['engineer'] = function() return '[light_bg]drops 2 additional turrets and grants all turrets +50% damage and attack speed' end, ['engineer'] = function() return '[light_bg]drops 2 additional turrets and grants all turrets +50% damage and attack speed' end,
@ -901,13 +903,13 @@ function init()
} }
local ylb1 = function(lvl) local ylb1 = function(lvl)
if lvl == 3 then return 'fg' if lvl == 3 then return 'light_bg'
elseif lvl == 2 then return 'fg' elseif lvl == 2 then return 'light_bg'
elseif lvl == 1 then return 'yellow' elseif lvl == 1 then return 'yellow'
else return 'light_bg' end else return 'light_bg' end
end end
local ylb2 = function(lvl) local ylb2 = function(lvl)
if lvl == 3 then return 'fg' if lvl == 3 then return 'light_bg'
elseif lvl == 2 then return 'yellow' elseif lvl == 2 then return 'yellow'
else return 'light_bg' end else return 'light_bg' end
end end
@ -928,7 +930,7 @@ function init()
['curser'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+25%[light_bg]/[' .. ylb2(lvl) .. ']+50% [fg]curse duration' end, ['curser'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+25%[light_bg]/[' .. ylb2(lvl) .. ']+50% [fg]curse duration' end,
['forcer'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+25%[light_bg]/[' .. ylb2(lvl) .. ']+50% [fg]knockback force to all allies' end, ['forcer'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+25%[light_bg]/[' .. ylb2(lvl) .. ']+50% [fg]knockback force to all allies' end,
['swarmer'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+1[light_bg]/[' .. ylb2(lvl) .. ']+3 [fg]hits to critters' end, ['swarmer'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+1[light_bg]/[' .. ylb2(lvl) .. ']+3 [fg]hits to critters' end,
['voider'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+15%[light_bg]/[' .. ylb2(lvl) .. ']+25% [fg]damage over time to allied voiders' end, ['voider'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+20%[light_bg]/[' .. ylb2(lvl) .. ']+40% [fg]damage over time to allied voiders' end,
['sorcerer'] = function(lvl) ['sorcerer'] = function(lvl)
return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4[light_bg]/[' .. ylb3(lvl) .. ']6 [fg]- sorcerers repeat their attacks once every [' .. return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4[light_bg]/[' .. ylb3(lvl) .. ']6 [fg]- sorcerers repeat their attacks once every [' ..
ylb1(lvl) .. ']4[light_bg]/[' .. ylb2(lvl) .. ']3[light_bg]/[' .. ylb3(lvl) .. ']2[fg] attacks' ylb1(lvl) .. ']4[light_bg]/[' .. ylb2(lvl) .. ']3[light_bg]/[' .. ylb3(lvl) .. ']2[fg] attacks'
@ -1003,6 +1005,12 @@ function init()
['thief'] = 4, ['thief'] = 4,
} }
launches_projectiles = function(character)
local classes = {'vagrant', 'archer', 'scout', 'outlaw', 'blade', 'wizard', 'cannoneer', 'dual_gunner', 'hunter', 'spellblade', 'engineer', 'corruptor', 'beastmaster', 'jester', 'assassin', 'barrager',
'arcanist', 'illusionist', 'miner', 'thief'}
return table.any(classes, function(v) return v == character end)
end
get_number_of_units_per_class = function(units) get_number_of_units_per_class = function(units)
local rangers = 0 local rangers = 0
local warriors = 0 local warriors = 0
@ -1116,7 +1124,7 @@ function init()
['crucio'] = 'Crucio', ['crucio'] = 'Crucio',
['speed_3'] = 'Speed 3', ['speed_3'] = 'Speed 3',
['damage_4'] = 'Damage 4', ['damage_4'] = 'Damage 4',
['level_5'] = 'Level 5', ['shoot_5'] = 'Shoot 5',
['death_6'] = 'Death 6', ['death_6'] = 'Death 6',
['lasting_7'] = 'Lasting 7', ['lasting_7'] = 'Lasting 7',
['defensive_stance'] = 'Defensive Stance', ['defensive_stance'] = 'Defensive Stance',
@ -1173,13 +1181,13 @@ function init()
['crucio'] = '[fg]taking damage also shares that across all enemies at [yellow]20/30/40%[fg] its value', ['crucio'] = '[fg]taking damage also shares that across all enemies at [yellow]20/30/40%[fg] its value',
['speed_3'] = '[fg]position [yellow]3[fg] has [yellow]+50%[fg] attack speed', ['speed_3'] = '[fg]position [yellow]3[fg] has [yellow]+50%[fg] attack speed',
['damage_4'] = '[fg]position [yellow]4[fg] has [yellow]+30%[fg] damage', ['damage_4'] = '[fg]position [yellow]4[fg] has [yellow]+30%[fg] damage',
['level_5'] = '[fg]position [yellow]5[fg] is [yellow]1[fg] level higher', ['shoot_5'] = '[fg]position [yellow]5[fg] shoots [yellow]3[fg] projectiles per second',
['death_6'] = '[fg]position [yellow]6[fg] takes [yellow]10%[fg] of its health as damage every [yellow]3[fg] seconds', ['death_6'] = '[fg]position [yellow]6[fg] takes [yellow]10%[fg] of its health as damage every [yellow]3[fg] seconds',
['lasting_7'] = '[fg]position [yellow]7[fg] will stay alive for [yellow]10[fg] seconds after dying', ['lasting_7'] = '[fg]position [yellow]7[fg] will stay alive for [yellow]10[fg] seconds after dying',
['defensive_stance'] = '[fg]first and last positions have [yellow]+10/20/30%[fg] defense', ['defensive_stance'] = '[fg]first and last positions have [yellow]+10/20/30%[fg] defense',
['offensive_stance'] = '[fg]first and last positions have [yellow]+10/20/30%[fg] damage', ['offensive_stance'] = '[fg]first and last positions have [yellow]+10/20/30%[fg] damage',
['kinetic_bomb'] = '[fg]when a unit dies it explodes, launching enemies away', ['kinetic_bomb'] = '[fg]when an ally dies it explodes, launching enemies away',
['porcupine_technique'] = '[fg]when a unit dies it explodes, releasing piercing projectiles', ['porcupine_technique'] = '[fg]when an ally dies it explodes, releasing piercing and ricocheting projectiles',
['last_stand'] = '[fg]the last unit alive is fully healed and receives a [yellow]+20%[fg] bonus to all stats', ['last_stand'] = '[fg]the last unit alive is fully healed and receives a [yellow]+20%[fg] bonus to all stats',
['seeping'] = '[fg]enemies taking DoT damage take [yellow]+15/20/25%[fg] damage for [yellow]6[fg] seconds', ['seeping'] = '[fg]enemies taking DoT damage take [yellow]+15/20/25%[fg] damage for [yellow]6[fg] seconds',
['deceleration'] = '[fg]enemies damaged by voiders have their movement speed reduced by [yellow]15/20/25%', ['deceleration'] = '[fg]enemies damaged by voiders have their movement speed reduced by [yellow]15/20/25%',
@ -1231,13 +1239,13 @@ function init()
['crucio'] = function(lvl) return '[fg]taking damage also shares that across all enemies at ' .. ts(lvl, '20%', '30%', '40%') .. ' its value' end, ['crucio'] = function(lvl) return '[fg]taking damage also shares that across all enemies at ' .. ts(lvl, '20%', '30%', '40%') .. ' its value' end,
['speed_3'] = function(lvl) return '[fg]position [yellow]3[fg] has [yellow]+50%[fg] attack speed' end, ['speed_3'] = function(lvl) return '[fg]position [yellow]3[fg] has [yellow]+50%[fg] attack speed' end,
['damage_4'] = function(lvl) return '[fg]position [yellow]4[fg] has [yellow]+30%[fg] damage' end, ['damage_4'] = function(lvl) return '[fg]position [yellow]4[fg] has [yellow]+30%[fg] damage' end,
['level_5'] = function(lvl) return '[fg]position [yellow]5[fg] is [yellow]1[fg] level higher' end, ['shoot_5'] = function(lvl) return '[fg]position [yellow]5[fg] shoots [yellow]3[fg] projectiles per second' end,
['death_6'] = function(lvl) return '[fg]position [yellow]6[fg] takes [yellow]10%[fg] of its health as damage every [yellow]3[fg] seconds' end, ['death_6'] = function(lvl) return '[fg]position [yellow]6[fg] takes [yellow]10%[fg] of its health as damage every [yellow]3[fg] seconds' end,
['lasting_7'] = function(lvl) return '[fg]position [yellow]7[fg] will stay alive for [yellow]10[fg] seconds after dying' end, ['lasting_7'] = function(lvl) return '[fg]position [yellow]7[fg] will stay alive for [yellow]10[fg] seconds after dying' end,
['defensive_stance'] = function(lvl) return '[fg]first and last positions have ' .. ts(lvl, '+10%', '20%', '30%') .. ' defense' end, ['defensive_stance'] = function(lvl) return '[fg]first and last positions have ' .. ts(lvl, '+10%', '20%', '30%') .. ' defense' end,
['offensive_stance'] = function(lvl) return '[fg]first and last positions have ' .. ts(lvl, '+10%', '20%', '30%') .. ' damage' end, ['offensive_stance'] = function(lvl) return '[fg]first and last positions have ' .. ts(lvl, '+10%', '20%', '30%') .. ' damage' end,
['kinetic_bomb'] = function(lvl) return '[fg]when a unit dies it explodes, launching enemies away' end, ['kinetic_bomb'] = function(lvl) return '[fg]when an ally dies it explodes, launching enemies away' end,
['porcupine_technique'] = function(lvl) return '[fg]when a unit dies it explodes, releasing piercing projectiles' end, ['porcupine_technique'] = function(lvl) return '[fg]when an ally dies it explodes, releasing piercing projectiles' end,
['last_stand'] = function(lvl) return '[fg]the last unit alive is fully healed and receives a [yellow]+20%[fg] bonus to all stats' end, ['last_stand'] = function(lvl) return '[fg]the last unit alive is fully healed and receives a [yellow]+20%[fg] bonus to all stats' end,
['seeping'] = function(lvl) return '[fg]enemies taking DoT damage take ' .. ts(lvl, '+15%', '20%', '25%') .. ' damage for [yellow]6[fg] seconds' end, ['seeping'] = function(lvl) return '[fg]enemies taking DoT damage take ' .. ts(lvl, '+15%', '20%', '25%') .. ' damage for [yellow]6[fg] seconds' end,
['deceleration'] = function(lvl) return '[fg]enemies damaged by voiders have their movement speed reduced by ' .. ts(lvl, '15%', '20%', '25%') end, ['deceleration'] = function(lvl) return '[fg]enemies damaged by voiders have their movement speed reduced by ' .. ts(lvl, '15%', '20%', '25%') end,
@ -1461,7 +1469,7 @@ function init()
local run = system.load_run() local run = system.load_run()
run_passive_pool = run.run_passive_pool or { run_passive_pool = run.run_passive_pool or {
'centipede', 'ouroboros_technique_r', 'ouroboros_technique_l', 'amplify', 'resonance', 'ballista', 'call_of_the_void', 'crucio', 'speed_3', 'damage_4', 'level_5', 'death_6', 'lasting_7', 'centipede', 'ouroboros_technique_r', 'ouroboros_technique_l', 'amplify', 'resonance', 'ballista', 'call_of_the_void', 'crucio', 'speed_3', 'damage_4', 'shoot_5', 'death_6', 'lasting_7',
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'pandemic', 'whispers_of_doom', 'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'pandemic', 'whispers_of_doom',
'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment', 'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment',
'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism', 'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism',
@ -1490,19 +1498,15 @@ function init()
--[[ --[[
main:add(Arena'arena') main:add(Arena'arena')
main:go_to('arena', 25, { main:go_to('arena', 13, {
{character = 'swordsman', level = 3}, {character = 'witch', level = 1},
{character = 'scout', level = 3}, {character = 'stormweaver', level = 1},
{character = 'thief', level = 3}, {character = 'chronomancer', level = 1},
{character = 'blade', level = 3}, {character = 'miner', level = 1},
{character = 'dual_gunner', level = 3}, {character = 'merchant', level = 1},
{character = 'saboteur', level = 3}, {character = 'sage', level = 1},
{character = 'spellblade', level = 3}, {character = 'magician', level = 1},
{character = 'jester', level = 3}, }, {{passive = 'last_stand', level = 1}})
{character = 'assassin', level = 3},
{character = 'barrager', level = 3},
{character = 'cannoneer', level = 3},
}, passives)
]]-- ]]--
--[[ --[[

View File

@ -805,8 +805,8 @@ function Player:init(args)
if self.ouroboros_technique_r then if self.ouroboros_technique_r then
self.t:after(0.01, function() self.t:after(0.01, function()
self.t:every(0.4 - (0.02*#self:get_all_units()), function() self.t:every((self.ouroboros_technique_r == 1 and 0.5) or (self.ouroboros_technique_r == 2 and 0.33) or (self.ouroboros_technique_r == 3 and 0.25), function()
if self.move_right_pressed and love.timer.getTime() - self.move_right_pressed > 1 then if self.leader and (state.mouse_control and table.all(self.mouse_control_v_buffer, function(v) return v >= 0.5 end)) or (self.move_right_pressed and love.timer.getTime() - self.move_right_pressed > 1) then
local target = self:get_closest_object_in_shape(Circle(self.x, self.y, 96), main.current.enemies) local target = self:get_closest_object_in_shape(Circle(self.x, self.y, 96), main.current.enemies)
if target then if target then
local units = self:get_all_units() local units = self:get_all_units()
@ -829,20 +829,11 @@ function Player:init(args)
end) end)
end end
if self.centipede then self.centipede_mvspd_m = 1.2 end if self.centipede then self.centipede_mvspd_m = (self.centipede == 1 and 1.1) or (self.centipede == 2 and 1.2) or (self.centipede == 3 and 1.3) end
if self.amplify then self.amplify_area_dmg_m = 1.25 end if self.amplify then self.amplify_area_dmg_m = (self.amplify == 1 and 1.2) or (self.amplify == 2 and 1.35) or (self.amplify == 3 and 1.5) end
if self.amplify_x then self.amplify_x_area_dmg_m = 1.5 end
if self.ballista then if self.ballista and launches_projectiles(self.character) then
if table.any(self.classes, function(v) return v == 'ranger' end) or table.any(self.classes, function(v) return v == 'rogue' end) then self.ballista_dmg_m = (self.ballista == 1 and 1.2) or (self.ballista == 2 and 1.35) or (self.ballista == 3 and 1.5)
self.ballista_dmg_m = 1.25
end
end
if self.ballista_x then
if table.any(self.classes, function(v) return v == 'ranger' end) or table.any(self.classes, function(v) return v == 'rogue' end) then
self.ballista_x_dmg_m = 1.5
end
end end
if self.chronomancy then if self.chronomancy then
@ -956,6 +947,39 @@ function Player:init(args)
end end
end) end)
end end
if self.leader and self.shoot_5 then
main.current.t:after(0.1, function()
self.t:every(0.33, function()
local units = self:get_all_units()
local unit = units[5]
if unit then
local target = unit:get_closest_object_in_shape(Circle(unit.x, unit.y, 96), main.current.enemies)
if target then
unit:barrage(unit:angle_to_object(target), 1)
else
unit:barrage(random:float(0, 2*math.pi), 1)
end
end
end)
end)
end
if self.leader and self.death_6 then
main.current.t:after(0.1, function()
self.t:every(3, function()
flagellant1:play{pitch = random:float(0.95, 1.05), volume = 0.4}
local units = self:get_all_units()
local unit = units[6]
if unit then
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.4}
unit:hit(0.1*unit.max_hp)
end
end)
end)
end
self.mouse_control_v_buffer = {}
end end
@ -1084,17 +1108,17 @@ function Player:update(dt)
if self.force_push then self.knockback_m = self.knockback_m*1.25 end if self.force_push then self.knockback_m = self.knockback_m*1.25 end
if table.any(self.classes, function(v) return v == 'voider' end) then if table.any(self.classes, function(v) return v == 'voider' end) then
if main.current.voider_level == 2 then self.dot_dmg_m = 1.25 if main.current.voider_level == 2 then self.dot_dmg_m = 1.4
elseif main.current.voider_level == 1 then self.dot_dmg_m = 1.15 elseif main.current.voider_level == 1 then self.dot_dmg_m = 1.2
else self.dot_dmg_m = 1 end else self.dot_dmg_m = 1 end
end end
if self.call_of_the_void then self.dot_dmg_m = (self.dot_dmg_m or 1)*1.25 end if self.call_of_the_void then self.dot_dmg_m = (self.dot_dmg_m or 1)*((self.call_of_the_void == 1 and 1.3) or (self.call_of_the_void == 2 and 1.6) or (self.call_of_the_void == 3 and 1.9) or 1) end
if self.ouroboros_technique_l and self.leader then if self.ouroboros_technique_l and self.leader then
local units = self:get_all_units() local units = self:get_all_units()
if self.move_left_pressed and love.timer.getTime() - self.move_left_pressed > 1 then if (state.mouse_control and table.all(self.mouse_control_v_buffer, function(v) return v <= -0.5 end)) or (self.move_left_pressed and love.timer.getTime() - self.move_left_pressed > 1) then
for _, unit in ipairs(units) do for _, unit in ipairs(units) do
unit.ouroboros_def_m = 1.25 unit.ouroboros_def_m = (self.ouroboros_technique_l == 1 and 1.15) or (self.ouroboros_technique_l == 2 and 1.25) or (self.ouroboros_technique_l == 3 and 1.35)
end end
else else
for _, unit in ipairs(units) do for _, unit in ipairs(units) do
@ -1107,13 +1131,46 @@ function Player:update(dt)
self.berserking_aspd_m = math.remap(self.hp/self.max_hp, 0, 1, 1.5, 1) self.berserking_aspd_m = math.remap(self.hp/self.max_hp, 0, 1, 1.5, 1)
end end
if self.speed_3 and self.follower_index == 2 then
self.speed_3_aspd_m = 1.5
end
if self.damage_4 and self.follower_index == 3 then
self.damage_4_dmg_m = 1.3
end
if self.defensive_stance and self.leader then
self.defensive_stance_def_m = (self.defensive_stance == 1 and 1.1) or (self.defensive_stance == 2 and 1.2) or (self.defensive_stance == 3 and 1.3)
end
if self.defensive_stance and not self.leader and self.follower_index == #self.parent.followers then
self.defensive_stance_def_m = (self.defensive_stance == 1 and 1.1) or (self.defensive_stance == 2 and 1.2) or (self.defensive_stance == 3 and 1.3)
end
if self.offensive_stance and self.leader then
self.offensive_stance_dmg_m = (self.offensive_stance == 1 and 1.1) or (self.offensive_stance == 2 and 1.2) or (self.offensive_stance == 3 and 1.3)
end
if self.offensive_stance and not self.leader and self.follower_index == #self.parent.followers then
self.offensive_stance_dmg_m = (self.offensive_stance == 1 and 1.1) or (self.offensive_stance == 2 and 1.2) or (self.offensive_stance == 3 and 1.3)
end
if self.leader and #self.followers == 0 and self.last_stand then
self.last_stand_dmg_m = 1.2
self.last_stand_def_m = 1.2
self.last_stand_aspd_m = 1.2
self.last_stand_area_size_m = 1.2
self.last_stand_area_dmg_m = 1.2
self.last_stand_mvspd_m = 1.2
end
self.buff_def_a = (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.vagrant_aspd_m or 1)*(self.outlaw_aspd_m or 1)*(self.fairy_aspd_m or 1)*(self.psyker_aspd_m or 1)*(self.chronomancy_aspd_m or 1)*(self.awakening_aspd_m or 1)*(self.berserking_aspd_m or 1)*(self.reinforce_aspd_m or 1)*(self.squire_aspd_m or 1) self.buff_aspd_m = (self.chronomancer_aspd_m or 1)*(self.vagrant_aspd_m or 1)*(self.outlaw_aspd_m or 1)*(self.fairy_aspd_m or 1)*(self.psyker_aspd_m or 1)*(self.chronomancy_aspd_m or 1)*(self.awakening_aspd_m or 1)*(self.berserking_aspd_m or 1)*(self.reinforce_aspd_m or 1)*(self.squire_aspd_m or 1)*(self.speed_3_aspd_m or 1)*(self.last_stand_aspd_m or 1)
self.buff_dmg_m = (self.squire_dmg_m or 1)*(self.vagrant_dmg_m or 1)*(self.enchanter_dmg_m or 1)*(self.swordsman_dmg_m or 1)*(self.flagellant_dmg_m or 1)*(self.psyker_dmg_m or 1)*(self.ballista_dmg_m or 1)*(self.ballista_x_dmg_m or 1)*(self.awakening_dmg_m or 1)*(self.reinforce_dmg_m or 1)*(self.payback_dmg_m or 1)*(self.immolation_dmg_m or 1) self.buff_dmg_m = (self.squire_dmg_m or 1)*(self.vagrant_dmg_m or 1)*(self.enchanter_dmg_m or 1)*(self.swordsman_dmg_m or 1)*(self.flagellant_dmg_m or 1)*(self.psyker_dmg_m or 1)*(self.ballista_dmg_m or 1)*(self.awakening_dmg_m or 1)*(self.reinforce_dmg_m or 1)*(self.payback_dmg_m or 1)*(self.immolation_dmg_m or 1)*(self.damage_4_dmg_m or 1)*(self.offensive_stance_dmg_m or 1)*(self.last_stand_dmg_m or 1)
self.buff_def_m = (self.squire_def_m or 1)*(self.ouroboros_def_m or 1)*(self.unwavering_stance_def_m or 1)*(self.reinforce_def_m or 1) self.buff_def_m = (self.squire_def_m or 1)*(self.ouroboros_def_m or 1)*(self.unwavering_stance_def_m or 1)*(self.reinforce_def_m or 1)*(self.defensive_stance_def_m or 1)*(self.last_stand_def_m or 1)
self.buff_area_size_m = (self.nuker_area_size_m or 1)*(self.magnify_area_size_m or 1)*(self.unleash_area_size_m or 1) self.buff_area_size_m = (self.nuker_area_size_m or 1)*(self.magnify_area_size_m or 1)*(self.unleash_area_size_m or 1)*(self.last_stand_area_size_m or 1)
self.buff_area_dmg_m = (self.nuker_area_dmg_m or 1)*(self.amplify_area_dmg_m or 1)*(self.amplify_x_area_dmg_m or 1)*(self.unleash_area_dmg_m or 1) self.buff_area_dmg_m = (self.nuker_area_dmg_m or 1)*(self.amplify_area_dmg_m or 1)*(self.unleash_area_dmg_m or 1)*(self.last_stand_area_dmg_m or 1)
self.buff_mvspd_m = (self.wall_rider_mvspd_m or 1)*(self.centipede_mvspd_m or 1)*(self.squire_mvspd_m or 1) self.buff_mvspd_m = (self.wall_rider_mvspd_m or 1)*(self.centipede_mvspd_m or 1)*(self.squire_mvspd_m or 1)*(self.last_stand_mvspd_m or 1)
self:calculate_stats() self:calculate_stats()
if self.attack_sensor then self.attack_sensor:move_to(self.x, self.y) end if self.attack_sensor then self.attack_sensor:move_to(self.x, self.y) end
@ -1129,8 +1186,10 @@ function Player:update(dt)
if input.move_right.released then self.move_right_pressed = nil end if input.move_right.released then self.move_right_pressed = nil end
if state.mouse_control then if state.mouse_control then
local v = Vector(math.cos(self.r), math.sin(self.r)):perpendicular():dot(Vector(math.cos(self:angle_to_mouse()), math.sin(self:angle_to_mouse()))) self.mouse_control_v = Vector(math.cos(self.r), math.sin(self.r)):perpendicular():dot(Vector(math.cos(self:angle_to_mouse()), math.sin(self:angle_to_mouse())))
self.r = self.r + math.sign(v)*1.66*math.pi*dt self.r = self.r + math.sign(self.mouse_control_v)*1.66*math.pi*dt
table.insert(self.mouse_control_v_buffer, 1, self.mouse_control_v)
if #self.mouse_control_v_buffer > 64 then self.mouse_control_v_buffer[65] = nil end
else else
if input.move_left.down then self.r = self.r - 1.66*math.pi*dt end 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 if input.move_right.down then self.r = self.r + 1.66*math.pi*dt end
@ -1199,6 +1258,8 @@ function Player:draw()
if self.visual_shape == 'rectangle' then if self.visual_shape == 'rectangle' then
if self.magician_invulnerable then if self.magician_invulnerable then
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 3, 3, blue_transparent) graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 3, 3, blue_transparent)
elseif self.undead then
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 3, 3, self.color, 1)
else else
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 3, 3, (self.hfx.hit.f or self.hfx.shoot.f) and fg[0] or self.color) graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 3, 3, (self.hfx.hit.f or self.hfx.shoot.f) and fg[0] or self.color)
end end
@ -1208,6 +1269,10 @@ function Player:draw()
graphics.line(x + 3, y, x, y - 3, character_colors[self.character], 1) graphics.line(x + 3, y, x, y - 3, character_colors[self.character], 1)
graphics.line(x + 3, y, x, y + 3, character_colors[self.character], 1) graphics.line(x + 3, y, x, y + 3, character_colors[self.character], 1)
end end
if self.ouroboros_def_m and self.ouroboros_def_m > 1 then
graphics.rectangle(self.x, self.y, 1.25*self.shape.w, 1.25*self.shape.h, 3, 3, yellow_transparent)
end
end end
graphics.pop() graphics.pop()
end end
@ -1271,9 +1336,10 @@ function Player:on_collision_enter(other, contact)
end end
function Player:hit(damage) function Player:hit(damage, from_undead)
if self.dead then return end if self.dead then return end
if self.magician_invulnerable then return end if self.magician_invulnerable then return end
if self.undead and not from_undead then return end
self.hfx:use('hit', 0.25, 200, 10) self.hfx:use('hit', 0.25, 200, 10)
self:show_hp() self:show_hp()
@ -1299,7 +1365,7 @@ function Player:hit(damage)
if self.crucio then if self.crucio then
local enemies = main.current.main:get_objects_by_classes(main.current.enemies) local enemies = main.current.main:get_objects_by_classes(main.current.enemies)
for _, enemy in ipairs(enemies) do for _, enemy in ipairs(enemies) do
enemy:hit(0.25*actual_damage) enemy:hit(((self.crucio == 1 and 0.2) or (self.crucio == 2 and 0.3) or (self.crucio == 3 and 0.4))*actual_damage)
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = fg[0], duration = 0.1} HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = fg[0], duration = 0.1}
end end
end end
@ -1338,6 +1404,10 @@ function Player: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) HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 12}:scale_down(0.3):change_color(0.5, self.color)
self.divined = false self.divined = false
elseif self.lasting_7 and self.follower_index == 6 and not self.undead then
self.undead = true
self.t:after(10, function() self:hit(0, true) end)
else else
hit4:play{pitch = random:float(0.95, 1.05), volume = 0.5} hit4:play{pitch = random:float(0.95, 1.05), volume = 0.5}
slow(0.25, 1) slow(0.25, 1)
@ -1353,6 +1423,33 @@ function Player:hit(damage)
self.dead = true self.dead = true
if self.leader then self:recalculate_followers() if self.leader then self:recalculate_followers()
else self.parent:recalculate_followers() end else self.parent:recalculate_followers() end
if #main.current.player.followers == 0 and main.current.player.last_stand then
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
buff1:play{pitch == random:float(0.9, 1.1), volume = 0.5}
main.current.player:heal(10000)
end
end
if self.kinetic_bomb then
elementor1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
local enemies = self:get_objects_in_shape(Circle(self.x, self.y, 96), main.current.enemies)
for _, enemy in ipairs(enemies) do
enemy:push(random:float(30, 50)*(self.knockback_m or 1), self:angle_to_object(enemy))
end
end
if self.porcupine_technique then
main.current.t:after(0.01, function()
local r = 0
for i = 1, 8 do
archer1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
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,
parent = self, character = 'barrage', level = self.level, pierce = 1000, ricochet = 2}
Projectile(table.merge(t, mods or {}))
r = r + math.pi/4
end
end)
end end
if self.dot_area then self.dot_area.dead = true; self.dot_area = nil end if self.dot_area then self.dot_area.dead = true; self.dot_area = nil end
@ -1416,6 +1513,7 @@ function Player:recalculate_followers()
follower.parent = new_leader follower.parent = new_leader
follower.follower_index = i follower.follower_index = i
end end
else else
for i = #self.followers, 1, -1 do for i = #self.followers, 1, -1 do
if self.followers[i].dead then if self.followers[i].dead then
@ -1590,7 +1688,7 @@ function Player:dot_attack(area, mods)
mods = mods or {} mods = mods or {}
camera:shake(2, 0.5) camera:shake(2, 0.5)
self.hfx:use('shoot', 0.25) 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, 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*(self.dot_dmg_m or 1),
character = self.character, level = self.level, parent = self} character = self.character, level = self.level, parent = self}
DotArea(table.merge(t, mods)) DotArea(table.merge(t, mods))
@ -1598,14 +1696,14 @@ function Player:dot_attack(area, mods)
end end
function Player:barrage(r, n) function Player:barrage(r, n, pierce)
n = n or 8 n = n or 8
for i = 1, n do for i = 1, n do
self.t:after((i-1)*0.075, function() self.t:after((i-1)*0.075, function()
archer1:play{pitch = random:float(0.95, 1.05), volume = 0.35} archer1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
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} 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 + random:float(-math.pi/16, math.pi/16), color = self.color, dmg = self.dmg, 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 + random:float(-math.pi/16, math.pi/16), color = self.color, dmg = self.dmg,
parent = self, character = 'barrage', level = self.level} parent = self, character = 'barrage', level = self.level, pierce = pierce or 0}
Projectile(table.merge(t, mods or {})) Projectile(table.merge(t, mods or {}))
end) end)
end end
@ -2037,26 +2135,27 @@ function Area:init(args)
local enemies = main.current.main:get_objects_in_shape(self.shape, main.current.enemies) local enemies = main.current.main:get_objects_in_shape(self.shape, main.current.enemies)
for _, enemy in ipairs(enemies) do for _, enemy in ipairs(enemies) do
local resonance_dmg = 0 local resonance_dmg = 0
local resonance_m = (self.parent.resonance == 1 and 0.03) or (self.parent.resonance == 2 and 0.05) or (self.parent.resonance == 3 and 0.07) or 0
if self.character == 'elementor' then if self.character == 'elementor' then
if self.parent.resonance then resonance_dmg = 2*self.dmg*0.05*#enemies end if self.parent.resonance then resonance_dmg = 2*self.dmg*resonance_m*#enemies end
enemy:hit(2*self.dmg + resonance_dmg, self) enemy:hit(2*self.dmg + resonance_dmg, self)
if self.level == 3 then if self.level == 3 then
enemy:slow(0.4, 6) enemy:slow(0.4, 6)
end end
elseif self.character == 'swordsman' then elseif self.character == 'swordsman' then
if self.parent.resonance then resonance_dmg = (self.dmg + self.dmg*0.15*#enemies)*0.05*#enemies end if self.parent.resonance then resonance_dmg = (self.dmg + self.dmg*0.15*#enemies)*resonance_m*#enemies end
enemy:hit(self.dmg + self.dmg*0.15*#enemies + resonance_dmg, self) enemy:hit(self.dmg + self.dmg*0.15*#enemies + resonance_dmg, self)
elseif self.character == 'blade' and self.level == 3 then elseif self.character == 'blade' and self.level == 3 then
if self.parent.resonance then resonance_dmg = (self.dmg + self.dmg*0.33*#enemies)*0.05*#enemies end if self.parent.resonance then resonance_dmg = (self.dmg + self.dmg*0.33*#enemies)*resonance_m*#enemies end
enemy:hit(self.dmg + self.dmg*0.33*#enemies + resonance_dmg, self) enemy:hit(self.dmg + self.dmg*0.33*#enemies + resonance_dmg, self)
elseif self.character == 'highlander' then elseif self.character == 'highlander' then
if self.parent.resonance then resonance_dmg = 6*self.dmg*0.05*#enemies end if self.parent.resonance then resonance_dmg = 6*self.dmg*resonance_m*#enemies end
enemy:hit(6*self.dmg + resonance_dmg, self) enemy:hit(6*self.dmg + resonance_dmg, self)
elseif self.character == 'launcher' then elseif self.character == 'launcher' then
if self.parent.resonance then resonance_dmg = (self.level == 3 and 6*self.dmg*0.05*#enemies or 2*self.dmg*0.05*#enemies) end if self.parent.resonance then resonance_dmg = (self.level == 3 and 6*self.dmg*0.05*#enemies or 2*self.dmg*0.05*#enemies) end
enemy:curse('launcher', 4*(self.hex_duration_m or 1), (self.level == 3 and 6*self.dmg or 2*self.dmg) + resonance_dmg, self.parent) enemy:curse('launcher', 4*(self.hex_duration_m or 1), (self.level == 3 and 6*self.dmg or 2*self.dmg) + resonance_dmg, self.parent)
else else
if self.parent.resonance then resonance_dmg = self.dmg*0.05*#enemies end if self.parent.resonance then resonance_dmg = self.dmg*resonance_m*#enemies end
enemy:hit(self.dmg + resonance_dmg, self) enemy:hit(self.dmg + resonance_dmg, self)
end end
HitCircle{group = main.current.effects, x = enemy.x, y = enemy.y, rs = 6, color = fg[0], duration = 0.1} HitCircle{group = main.current.effects, x = enemy.x, y = enemy.y, rs = 6, color = fg[0], duration = 0.1}

67
todo
View File

@ -1,33 +1,35 @@
Item Update Item Update
New mechanics New mechanics
Spend gold to level items up * Spend gold to level items up
Block levelling for unlevellable items
Items Items
General: General:
vt Centipede - +10/20/30% movement speed * Centipede - +10/20/30% movement speed
vt Ouroboros Technique R - rotating around yourself to the right releases 2/3/4 projectiles per second * Ouroboros Technique R - rotating around yourself to the right releases 2/3/4 projectiles per second
vt Ouroboros Technique L - rotating around yourself to the left grants +15/25/35% defense to all units * Ouroboros Technique L - rotating around yourself to the left grants +15/25/35% defense to all units
vt Amplify - +20/35/50% AoE damage * Amplify - +20/35/50% AoE damage
vt Resonance - all AoE attacks deal +3/5/7% damage per unit hit * Resonance - all AoE attacks deal +3/5/7% damage per unit hit
vt Ballista - +20/35/50% projectile damage * Ballista - +20/35/50% projectile damage
vt Call of the Void - +30/60/90% DoT damage * Call of the Void - +30/60/90% DoT damage
vt Crucio - taking damage also shares that damage across all enemies at 20/30/40% its value * Crucio - taking damage also shares that damage across all enemies at 20/30/40% its value
Position: Position:
vt Speed 3 - position 3 has +20/35/50% attack speed * Speed 3 - position 3 has +50% attack speed
vt Damage 4 - position 4 has +20/30/40% damage * Damage 4 - position 4 has +30% damage
vt Level 5 - position 5 is 1 level higher * Level 5 - position 5 is 1 level higher
vt Death 6 - position 6 takes 15% of its health as damage every 3 seconds * Death 6 - position 6 takes 15% of its health as damage every 3 seconds
vt Lasting 7 - position 7 will stay alive for 10 seconds after dying * Lasting 7 - position 7 will stay alive for 10 seconds after dying
vt Defense Stance - first and last positions have +10/20/30% defense * Defense Stance - first and last positions have +10/20/30% defense
vt Offensive Stance - first and last positions have +10/20/30% damage * Offensive Stance - first and last positions have +10/20/30% damage
Death: Death:
vt Kinetic Bomb - when a unit dies it explodes, launching enemies away * Kinetic Bomb - when a unit dies it explodes, launching enemies away
vt Porcupine Technique - when a unit dies it explodes, releasing piercing projectiles * Porcupine Technique - when a unit dies it explodes, releasing piercing projectiles
vt Last Stand - the last unit alive is fully healed and receives a +20/30/40% bonus to all stats * Last Stand - the last unit alive is fully healed and receives a +20% bonus to all stats
Voider: Voider:
vt Seeping - enemies taking DoT damage take +15/20/25% damage from all sources for 6 seconds vt Seeping - enemies taking DoT damage take +15/20/25% damage from all sources for 6 seconds
vt Deceleration - enemies damaged by voiders have their movement speed reduced by 15/20/25% vt Deceleration - enemies damaged by voiders have their movement speed reduced by 15/20/25%
vt Annihilation - when a voider dies deal its DoT damage to all enemies for 3 seconds vt Annihilation - when a voider dies deal its DoT damage to all enemies for 3 seconds
Curser: Curser:
change one of these for +1/3/5 curse targets
vt Malediction - cursed enemies take 15/25/35% more damage and deal 15/25/35% less damage vt Malediction - cursed enemies take 15/25/35% more damage and deal 15/25/35% less damage
vt Pandemic - when a cursed enemy dies its curse spreads vt Pandemic - when a cursed enemy dies its curse spreads
vt Whispers of Doom - curses apply doom, when 4/3/2 doom instances are reached they deal 100/150/200 vt Whispers of Doom - curses apply doom, when 4/3/2 doom instances are reached they deal 100/150/200
@ -78,12 +80,12 @@ Item Update
* Longshot * Longshot
* Hex Master * Hex Master
* Force Push * Force Push
* Call of the Void
* Spawning Pool * Spawning Pool
* Void Rift * Void Rift
* Blessing * Blessing
* Immolation * Immolation
Balance Balance
* Changed voider DoT damage bonus to 20/40% (from 15/25%)
* Decreased shop reroll cost to 10 * Decreased shop reroll cost to 10
Decrease mercenary gold drop chance to 8/16% (from 10/20%) Decrease mercenary gold drop chance to 8/16% (from 10/20%)
QoL QoL
@ -92,6 +94,7 @@ Item Update
Add visuals for defensive ouroboros, divine intervention, fairy buff Add visuals for defensive ouroboros, divine intervention, fairy buff
Options menu from buy screen Options menu from buy screen
https://i.imgur.com/JJUddT3.png https://i.imgur.com/JJUddT3.png
https://i.imgur.com/R3YgUqk.png
Improve volcano to not look like spawn marker - https://i.imgur.com/HuS15HG.png Improve volcano to not look like spawn marker - https://i.imgur.com/HuS15HG.png
Add option for mouse cursor to always be visible Add option for mouse cursor to always be visible
Add main menu Add main menu
@ -110,14 +113,16 @@ Item Update
Kill enemies that go outside play area - https://i.imgur.com/QPgZbve.png Kill enemies that go outside play area - https://i.imgur.com/QPgZbve.png
https://i.imgur.com/lCdPFZx.png https://i.imgur.com/lCdPFZx.png
https://i.imgur.com/1CwmFYX.png https://i.imgur.com/1CwmFYX.png
Ouroboros doesn't work with mouse controls https://i.imgur.com/qrExpq5.png
https://i.imgur.com/DNHUST1.png
* Fixed ouroboros technique passives not working with mouse controls
* Fixed mouse not showing up on death * Fixed mouse not showing up on death
* Fixed NG+5 achievement not triggering (this happened only between last Sunday night and Monday morning due to a small update I pushed breaking it) * Fixed NG+5 achievement not triggering (this happened only between last Sunday night and Monday morning due to a small update I pushed breaking it)
* Fixed a bug where the nuker class was not counting towards Vagrant's and Psyker's active set bonus * Fixed a bug where the nuker class was not counting towards Vagrant's and Psyker's active set bonus
* Fixed a bug where passives would sometimes disappear from a run? * Fixed a bug where passives would sometimes disappear from a run?
* Fixed a bug where clicking "window size-" too many times could bug out the game * Fixed a bug where clicking "window size-" too many times could bug out the game
* Fixed a bug where the shop would be rerolled after quitting in the arena
* Fixed multiple bugs related to locking the shop and quitting * Fixed multiple bugs related to locking the shop and quitting
* Fixed a bug where the shop would be rerolled after quitting in the arena
* Fixed a bug where units could be duplicated in the shop by locking and quitting the game at certain steps * Fixed a bug where units could be duplicated in the shop by locking and quitting the game at certain steps
* Fixed a bug where quitting on level 2 would go back to level 1 shop (again) * Fixed a bug where quitting on level 2 would go back to level 1 shop (again)
* Fixed a bug where mouse cursor wasn't visible on death * Fixed a bug where mouse cursor wasn't visible on death
@ -172,7 +177,9 @@ https://steamcommunity.com/app/915310/discussions/0/4658391921156325745/ - math
Roguelite update: Roguelite update:
Technical improvements: Technical improvements:
Spawn tech: spawn every entity in a grid, before spawning check to see if grid position is clear, this will prevent any issues due to entities spawning inside one another Spawn tech: spawn every entity in a grid, before spawning check to see if grid position is clear, this will prevent any issues due to entities spawning inside one another
Battle stats: DPS, damage taken, etc Battle stats: DPS, damage taken, etc (check Underlords)
Tag system: similar to PoE
Keyword explanations: similar to StS or Artifact, simply create additional text windows for keywords and what they mean
Key rebinding (for non-QWERTY keyboards) Key rebinding (for non-QWERTY keyboards)
StS-like map with nodes, node types: StS-like map with nodes, node types:
Arena Arena
@ -193,12 +200,16 @@ Roguelite update:
This unit's projectiles pierce/chain/fork/seek/split/stun/etc This unit's projectiles pierce/chain/fork/seek/split/stun/etc
This unit is a [class] This unit is a [class]
New stat system: New stat system:
All stats are values from 1 to 10 (can be lower than 1 or higher than 10 due to debuffs/buffs only) that represent consistent internal values between all units All stats are values from 1 to 10 (can be lower than 1 or higher than 10 due to debuffs/buffs) that represent consistent internal values between all units
i.e. 3 attack speed means the same internal attack rate value (like say 6 seconds) for the entire game i.e. 3 attack speed means the same internal attack rate value (like say 6 seconds) for the entire game
In general it's better if units don't have hidden internal multipliers on these stats, although sometimes that may be inevitable In general it's better if units don't have hidden internal multipliers on these stats, although sometimes that may be inevitable
Damage: Damage:
Crash - damage dealt when bumping into enemies Damage type:
Projectile - damage dealt by projectiles Attack - physical attacks, decreased by the enemy's armor
AoE - damage dealt in an area Spell - magical attacks, decreased by the enemy's magic resistance
DoT - damage dealt over time Attack type:
Crash - damage dealt when bumping into enemies
Projectile - damage dealt by projectiles
AoE - damage dealt in an area
DoT - damage dealt over time