Shop update 3/5
parent
f808b0452f
commit
8f2caf7109
54
arena.lua
54
arena.lua
|
@ -24,7 +24,7 @@ function Arena:on_enter(from, level, units, passives)
|
||||||
steam.friends.setRichPresence('text', 'Arena - Level ' .. self.level)
|
steam.friends.setRichPresence('text', 'Arena - Level ' .. self.level)
|
||||||
|
|
||||||
self.floor = Group()
|
self.floor = Group()
|
||||||
self.main = Group():set_as_physics_world(32, 0, 0, {'player', 'enemy', 'projectile', 'enemy_projectile', 'force_field'})
|
self.main = Group():set_as_physics_world(32, 0, 0, {'player', 'enemy', 'projectile', 'enemy_projectile', 'force_field', 'ghost'})
|
||||||
self.post_main = Group()
|
self.post_main = Group()
|
||||||
self.effects = Group()
|
self.effects = Group()
|
||||||
self.ui = Group()
|
self.ui = Group()
|
||||||
|
@ -39,10 +39,19 @@ function Arena:on_enter(from, level, units, passives)
|
||||||
self.main:disable_collision_between('enemy_projectile', 'enemy_projectile')
|
self.main:disable_collision_between('enemy_projectile', 'enemy_projectile')
|
||||||
self.main:disable_collision_between('player', 'force_field')
|
self.main:disable_collision_between('player', 'force_field')
|
||||||
self.main:disable_collision_between('projectile', 'force_field')
|
self.main:disable_collision_between('projectile', 'force_field')
|
||||||
|
self.main:disable_collision_between('ghost', 'player')
|
||||||
|
self.main:disable_collision_between('ghost', 'projectile')
|
||||||
|
self.main:disable_collision_between('ghost', 'enemy')
|
||||||
|
self.main:disable_collision_between('ghost', 'enemy_projectile')
|
||||||
|
self.main:disable_collision_between('ghost', 'ghost')
|
||||||
|
self.main:disable_collision_between('ghost', 'force_field')
|
||||||
self.main:enable_trigger_between('projectile', 'enemy')
|
self.main:enable_trigger_between('projectile', 'enemy')
|
||||||
self.main:enable_trigger_between('enemy_projectile', 'player')
|
self.main:enable_trigger_between('enemy_projectile', 'player')
|
||||||
self.main:enable_trigger_between('player', 'enemy_projectile')
|
self.main:enable_trigger_between('player', 'enemy_projectile')
|
||||||
|
self.main:enable_trigger_between('player', 'ghost')
|
||||||
|
self.main:enable_trigger_between('ghost', 'player')
|
||||||
|
|
||||||
|
self.gold_picked_up = 0
|
||||||
self.damage_dealt = 0
|
self.damage_dealt = 0
|
||||||
self.damage_taken = 0
|
self.damage_taken = 0
|
||||||
self.main_slow_amount = 1
|
self.main_slow_amount = 1
|
||||||
|
@ -257,6 +266,7 @@ function Arena:on_enter(from, level, units, passives)
|
||||||
self.psyker_level = class_levels.psyker
|
self.psyker_level = class_levels.psyker
|
||||||
self.conjurer_level = class_levels.conjurer
|
self.conjurer_level = class_levels.conjurer
|
||||||
self.sorcerer_level = class_levels.sorcerer
|
self.sorcerer_level = class_levels.sorcerer
|
||||||
|
self.mercenary_level = class_levels.mercenary
|
||||||
|
|
||||||
self.t:every(0.375, function()
|
self.t:every(0.375, function()
|
||||||
local p = random:table(star_positions)
|
local p = random:table(star_positions)
|
||||||
|
@ -348,12 +358,9 @@ function Arena:update(dt)
|
||||||
trigger:tween(0.25, _G, {slow_amount = 1}, math.linear, function()
|
trigger:tween(0.25, _G, {slow_amount = 1}, math.linear, function()
|
||||||
slow_amount = 1
|
slow_amount = 1
|
||||||
self.paused = false
|
self.paused = false
|
||||||
self.paused_t1.dead = true
|
if self.paused_t1 then self.paused_t1.dead = true; self.paused_t1 = nil end
|
||||||
self.paused_t2.dead = true
|
if self.paused_t2 then self.paused_t2.dead = true; self.paused_t2 = nil end
|
||||||
self.paused_t1 = nil
|
if self.ng_t then self.ng_t.dead = true; self.ng_t = nil end
|
||||||
self.paused_t2 = nil
|
|
||||||
self.ng_t.dead = true
|
|
||||||
self.ng_t = nil
|
|
||||||
if self.resume_button then self.resume_button.dead = true; self.resume_button = nil end
|
if self.resume_button then self.resume_button.dead = true; self.resume_button = nil end
|
||||||
if self.restart_button then self.restart_button.dead = true; self.restart_button = nil end
|
if self.restart_button then self.restart_button.dead = true; self.restart_button = nil end
|
||||||
if self.mouse_button then self.mouse_button.dead = true; self.mouse_button = nil end
|
if self.mouse_button then self.mouse_button.dead = true; self.mouse_button = nil end
|
||||||
|
@ -527,12 +534,9 @@ function Arena:update(dt)
|
||||||
trigger:tween(0.25, _G, {slow_amount = 1}, math.linear, function()
|
trigger:tween(0.25, _G, {slow_amount = 1}, math.linear, function()
|
||||||
slow_amount = 1
|
slow_amount = 1
|
||||||
self.paused = false
|
self.paused = false
|
||||||
self.paused_t1.dead = true
|
if self.paused_t1 then self.paused_t1.dead = true; self.paused_t1 = nil end
|
||||||
self.paused_t2.dead = true
|
if self.paused_t2 then self.paused_t2.dead = true; self.paused_t2 = nil end
|
||||||
self.paused_t1 = nil
|
if self.ng_t then self.ng_t.dead = true; self.ng_t = nil end
|
||||||
self.paused_t2 = nil
|
|
||||||
self.ng_t.dead = true
|
|
||||||
self.ng_t = nil
|
|
||||||
if self.resume_button then self.resume_button.dead = true; self.resume_button = nil end
|
if self.resume_button then self.resume_button.dead = true; self.resume_button = nil end
|
||||||
if self.restart_button then self.restart_button.dead = true; self.restart_button = nil end
|
if self.restart_button then self.restart_button.dead = true; self.restart_button = nil end
|
||||||
if self.mouse_button then self.mouse_button.dead = true; self.mouse_button = nil end
|
if self.mouse_button then self.mouse_button.dead = true; self.mouse_button = nil end
|
||||||
|
@ -608,6 +612,7 @@ function Arena:quit()
|
||||||
self.quitting = true
|
self.quitting = true
|
||||||
if self.level == 25 then
|
if self.level == 25 then
|
||||||
if not self.win_text and not self.win_text2 then
|
if not self.win_text and not self.win_text2 then
|
||||||
|
input:set_mouse_visible(true)
|
||||||
self.won = true
|
self.won = true
|
||||||
locked_state = nil
|
locked_state = nil
|
||||||
system.save_run()
|
system.save_run()
|
||||||
|
@ -800,6 +805,13 @@ function Arena:quit()
|
||||||
steam.userStats.storeStats()
|
steam.userStats.storeStats()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if self.mercenary_level >= 2 then
|
||||||
|
state.achievement_mercenaries_win = true
|
||||||
|
system.save_state()
|
||||||
|
steam.userStats.setAchievement('MERCENARIES_WIN')
|
||||||
|
steam.userStats.storeStats()
|
||||||
|
end
|
||||||
|
|
||||||
local units = self.player:get_all_units()
|
local units = self.player:get_all_units()
|
||||||
local all_units_level_2 = true
|
local all_units_level_2 = true
|
||||||
for _, unit in ipairs(units) do
|
for _, unit in ipairs(units) do
|
||||||
|
@ -836,6 +848,7 @@ function Arena:quit()
|
||||||
self:gain_gold()
|
self:gain_gold()
|
||||||
self.t:after(3, function()
|
self.t:after(3, function()
|
||||||
if self.level % 3 == 0 then
|
if self.level % 3 == 0 then
|
||||||
|
input:set_mouse_visible(true)
|
||||||
self.arena_clear_text.dead = true
|
self.arena_clear_text.dead = true
|
||||||
trigger:tween(1, _G, {slow_amount = 0}, math.linear, function() slow_amount = 0 end, 'slow_amount')
|
trigger:tween(1, _G, {slow_amount = 0}, math.linear, function() slow_amount = 0 end, 'slow_amount')
|
||||||
trigger:tween(4, camera, {x = gw/2, y = gh/2, r = 0}, math.linear, function() camera.x, camera.y, camera.r = gw/2, gh/2, 0 end)
|
trigger:tween(4, camera, {x = gw/2, y = gh/2, r = 0}, math.linear, function() camera.x, camera.y, camera.r = gw/2, gh/2, 0 end)
|
||||||
|
@ -1058,9 +1071,10 @@ end
|
||||||
|
|
||||||
|
|
||||||
function Arena:gain_gold()
|
function Arena:gain_gold()
|
||||||
|
local merchant = self.player:get_unit'merchant'
|
||||||
self.gold_gained = random:int(level_to_gold_gained[self.level][1], level_to_gold_gained[self.level][2])
|
self.gold_gained = random:int(level_to_gold_gained[self.level][1], level_to_gold_gained[self.level][2])
|
||||||
self.interest = math.min(math.floor(gold/5), 5)
|
self.interest = math.min(math.floor(gold/5), 5) + (merchant and math.floor(gold/10) or 0)
|
||||||
gold = gold + self.gold_gained + self.interest
|
gold = gold + self.gold_gained + self.gold_picked_up + self.interest
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -1074,30 +1088,30 @@ function Arena:transition()
|
||||||
main:go_to('buy_screen', self.level, self.units, self.passives)
|
main:go_to('buy_screen', self.level, self.units, self.passives)
|
||||||
t.t:after(0.1, function()
|
t.t:after(0.1, function()
|
||||||
t.text:set_text({
|
t.text:set_text({
|
||||||
{text = '[nudge_down, bg]gold gained: ' .. tostring(self.gold_gained or 0), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
{text = '[nudge_down, bg]gold gained: ' .. tostring(self.gold_gained or 0) .. ' + ' .. tostring(self.gold_picked_up or 0), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||||
{text = '[wavy_lower, bg]interest: 0', font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
{text = '[wavy_lower, bg]interest: 0', font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||||
{text = '[wavy_lower, bg]total: 0', font = pixul_font, alignment = 'center'}
|
{text = '[wavy_lower, bg]total: 0', font = pixul_font, alignment = 'center'}
|
||||||
})
|
})
|
||||||
_G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
_G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||||
t.t:after(0.2, function()
|
t.t:after(0.2, function()
|
||||||
t.text:set_text({
|
t.text:set_text({
|
||||||
{text = '[wavy_lower, bg]gold gained: ' .. tostring(self.gold_gained or 0), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
{text = '[wavy_lower, bg]gold gained: ' .. tostring(self.gold_gained or 0) .. ' + ' .. tostring(self.gold_picked_up or 0), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||||
{text = '[nudge_down, bg]interest: ' .. tostring(self.interest or 0), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
{text = '[nudge_down, bg]interest: ' .. tostring(self.interest or 0), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||||
{text = '[wavy_lower, bg]total: 0', font = pixul_font, alignment = 'center'}
|
{text = '[wavy_lower, bg]total: 0', font = pixul_font, alignment = 'center'}
|
||||||
})
|
})
|
||||||
_G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
_G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||||
t.t:after(0.2, function()
|
t.t:after(0.2, function()
|
||||||
t.text:set_text({
|
t.text:set_text({
|
||||||
{text = '[wavy_lower, bg]gold gained: ' .. tostring(self.gold_gained or 0), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
{text = '[wavy_lower, bg]gold gained: ' .. tostring(self.gold_gained or 0) .. ' + ' .. tostring(self.gold_picked_up or 0), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||||
{text = '[wavy_lower, bg]interest: ' .. tostring(self.interest or 0), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
{text = '[wavy_lower, bg]interest: ' .. tostring(self.interest or 0), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||||
{text = '[nudge_down, bg]total: ' .. tostring((self.gold_gained or 0) + (self.interest or 0)), font = pixul_font, alignment = 'center'}
|
{text = '[nudge_down, bg]total: ' .. tostring((self.gold_gained or 0) + (self.interest or 0) + (self.gold_picked_up or 0)), font = pixul_font, alignment = 'center'}
|
||||||
})
|
})
|
||||||
_G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
_G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
end, text = Text({
|
end, text = Text({
|
||||||
{text = '[wavy_lower, bg]gold gained: 0', font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
{text = '[wavy_lower, bg]gold gained: 0 + 0', font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||||
{text = '[wavy_lower, bg]interest: 0', font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
{text = '[wavy_lower, bg]interest: 0', font = pixul_font, alignment = 'center', height_multiplier = 1.5},
|
||||||
{text = '[wavy_lower, bg]total: 0', font = pixul_font, alignment = 'center'}
|
{text = '[wavy_lower, bg]total: 0', font = pixul_font, alignment = 'center'}
|
||||||
}, global_text_tags)}
|
}, global_text_tags)}
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 434 B |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -781,7 +781,8 @@ function RerollButton:init(args)
|
||||||
self.text = Text({{text = '[bg10]reroll: [yellow]2', font = pixul_font, alignment = 'center'}}, global_text_tags)
|
self.text = Text({{text = '[bg10]reroll: [yellow]2', font = pixul_font, alignment = 'center'}}, global_text_tags)
|
||||||
elseif self.parent:is(Arena) then
|
elseif self.parent:is(Arena) then
|
||||||
self.shape = Rectangle(self.x, self.y, 60, 16)
|
self.shape = Rectangle(self.x, self.y, 60, 16)
|
||||||
if self.parent.level == 3 then
|
local merchant = self.parent.player:get_unit'merchant'
|
||||||
|
if self.parent.level == 3 or (merchant and merchant.level == 3) then
|
||||||
self.free_reroll = true
|
self.free_reroll = true
|
||||||
self.text = Text({{text = '[bg10]reroll: [yellow]0', font = pixul_font, alignment = 'center'}}, global_text_tags)
|
self.text = Text({{text = '[bg10]reroll: [yellow]0', font = pixul_font, alignment = 'center'}}, global_text_tags)
|
||||||
else
|
else
|
||||||
|
@ -847,7 +848,11 @@ end
|
||||||
|
|
||||||
function RerollButton:draw()
|
function RerollButton:draw()
|
||||||
graphics.push(self.x, self.y, 0, self.spring.x, self.spring.y)
|
graphics.push(self.x, self.y, 0, self.spring.x, self.spring.y)
|
||||||
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 4, 4, self.selected and fg[0] or bg[1])
|
if self.parent:is(Arena) then
|
||||||
|
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 4, 4, self.selected and fg[0] or bg[-2])
|
||||||
|
else
|
||||||
|
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 4, 4, self.selected and fg[0] or bg[1])
|
||||||
|
end
|
||||||
self.text:draw(self.x, self.y + 1)
|
self.text:draw(self.x, self.y + 1)
|
||||||
graphics.pop()
|
graphics.pop()
|
||||||
end
|
end
|
||||||
|
@ -1077,6 +1082,7 @@ end
|
||||||
|
|
||||||
|
|
||||||
function CharacterPart:get_sale_price()
|
function CharacterPart:get_sale_price()
|
||||||
|
if not character_tiers[self.character] then return 0 end
|
||||||
local total = 0
|
local total = 0
|
||||||
total = total + ((self.level == 1 and character_tiers[self.character]) or (self.level == 2 and 2*character_tiers[self.character]) or (self.level == 3 and 6*character_tiers[self.character]) or 0)
|
total = total + ((self.level == 1 and character_tiers[self.character]) or (self.level == 2 and 2*character_tiers[self.character]) or (self.level == 3 and 6*character_tiers[self.character]) or 0)
|
||||||
if self.reserve then
|
if self.reserve then
|
||||||
|
|
30
enemies.lua
30
enemies.lua
|
@ -253,6 +253,8 @@ function Seeker:init(args)
|
||||||
if player and player.temporal_chains then
|
if player and player.temporal_chains then
|
||||||
self.temporal_chains_mvspd_m = 0.8
|
self.temporal_chains_mvspd_m = 0.8
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.usurer_count = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -435,6 +437,14 @@ function Seeker:hit(damage, projectile)
|
||||||
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)
|
||||||
_G[random:table{'enemy_die1', 'enemy_die2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
_G[random:table{'enemy_die1', 'enemy_die2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
||||||
|
|
||||||
|
if main.current.mercenary_level > 0 then
|
||||||
|
if random:bool((main.current.mercenary_level == 2 and 20) or (main.current.mercenary_level == 1 and 10) or 0) then
|
||||||
|
trigger:after(0.01, function()
|
||||||
|
Gold{group = main.current.main, x = self.x, y = self.y}
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if self.boss then
|
if self.boss then
|
||||||
slow(0.25, 1)
|
slow(0.25, 1)
|
||||||
magic_die1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
magic_die1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||||
|
@ -594,6 +604,17 @@ function Seeker:curse(curse, duration, arg1, arg2, arg3)
|
||||||
elseif curse == 'silencer' then
|
elseif curse == 'silencer' then
|
||||||
self.silenced = true
|
self.silenced = true
|
||||||
self.t:after(duration*curse_m, function() self.silenced = false end, 'silencer_curse')
|
self.t:after(duration*curse_m, function() self.silenced = false end, 'silencer_curse')
|
||||||
|
elseif curse == 'usurer' then
|
||||||
|
if arg1 then
|
||||||
|
self.usurer_count = self.usurer_count + 1
|
||||||
|
if self.usurer_count == 3 then
|
||||||
|
usurer1:play{pitch = random:float(0.95, 1.05), volume = 1}
|
||||||
|
rogue_crit1:play{pitch = random:float(0.95, 1.05), volume = 1}
|
||||||
|
camera:shake(4, 0.4)
|
||||||
|
self.usurer_count = 0
|
||||||
|
self:hit(50*arg2.dmg)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -628,6 +649,7 @@ function EnemyCritter:init(args)
|
||||||
self:push(args.v, args.r)
|
self:push(args.v, args.r)
|
||||||
self.invulnerable_to = args.projectile
|
self.invulnerable_to = args.projectile
|
||||||
self.t:after(0.5, function() self.invulnerable_to = false end)
|
self.t:after(0.5, function() self.invulnerable_to = false end)
|
||||||
|
self.usurer_count = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -778,6 +800,14 @@ function EnemyCritter:curse(curse, duration, arg1, arg2, arg3)
|
||||||
elseif curse == 'silencer' then
|
elseif curse == 'silencer' then
|
||||||
self.silenced = true
|
self.silenced = true
|
||||||
self.t:after(duration*curse_m, function() self.silenced = false end, 'silencer_curse')
|
self.t:after(duration*curse_m, function() self.silenced = false end, 'silencer_curse')
|
||||||
|
elseif curse == 'usurer' then
|
||||||
|
if arg1 then
|
||||||
|
self.usurer_count = self.usurer_count + 1
|
||||||
|
if self.usurer_count == 3 then
|
||||||
|
self.usurer_count = 0
|
||||||
|
self:hit(10*arg2.dmg)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -418,6 +418,16 @@ function table.first(t, n)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function table.first2(t, n)
|
||||||
|
if n == 1 then return {t[1]} end
|
||||||
|
local out = {}
|
||||||
|
for i = 1, (n or 1) do
|
||||||
|
table.push(out, t[i])
|
||||||
|
end
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Returns the last n values, same as tail
|
-- Returns the last n values, same as tail
|
||||||
-- t = {4, 3, 2, 1}
|
-- t = {4, 3, 2, 1}
|
||||||
-- table.last(t) -> 1
|
-- table.last(t) -> 1
|
||||||
|
|
120
main.lua
120
main.lua
|
@ -9,7 +9,6 @@ require 'media'
|
||||||
|
|
||||||
|
|
||||||
function init()
|
function init()
|
||||||
print('Initializing engine...')
|
|
||||||
shared_init()
|
shared_init()
|
||||||
|
|
||||||
input:bind('move_left', {'a', 'left', 'dpleft', 'm1'})
|
input:bind('move_left', {'a', 'left', 'dpleft', 'm1'})
|
||||||
|
@ -18,8 +17,11 @@ function init()
|
||||||
input:bind('move_down', {'s', 'down', 'dpdown'})
|
input:bind('move_down', {'s', 'down', 'dpdown'})
|
||||||
input:bind('enter', {'space', 'return', 'fleft', 'fdown', 'fright'})
|
input:bind('enter', {'space', 'return', 'fleft', 'fdown', 'fright'})
|
||||||
|
|
||||||
print('Loading sounds...')
|
|
||||||
local s = {tags = {sfx}}
|
local s = {tags = {sfx}}
|
||||||
|
gambler1 = Sound('Collect 5.ogg', s)
|
||||||
|
usurer1 = Sound('Shadow Punch 2.ogg', s)
|
||||||
|
gold1 = Sound('Collect 5.ogg', s)
|
||||||
|
gold2 = Sound('Coins - Gears - Slot.ogg', s)
|
||||||
psychic1 = Sound('Magical Impact 13.ogg', s)
|
psychic1 = Sound('Magical Impact 13.ogg', s)
|
||||||
fire1 = Sound('Fire bolt 3.ogg', s)
|
fire1 = Sound('Fire bolt 3.ogg', s)
|
||||||
fire2 = Sound('Fire bolt 5.ogg', s)
|
fire2 = Sound('Fire bolt 5.ogg', s)
|
||||||
|
@ -111,7 +113,6 @@ function init()
|
||||||
rogue_crit1 = Sound('Dagger Stab (Flesh) 4.ogg', s)
|
rogue_crit1 = Sound('Dagger Stab (Flesh) 4.ogg', s)
|
||||||
rogue_crit2 = Sound('Sword hits another sword 6.ogg', s)
|
rogue_crit2 = Sound('Sword hits another sword 6.ogg', s)
|
||||||
|
|
||||||
print('Loading songs...')
|
|
||||||
song1 = Sound('Kubbi - Ember - 01 Pathfinder.ogg', {tags = {music}})
|
song1 = Sound('Kubbi - Ember - 01 Pathfinder.ogg', {tags = {music}})
|
||||||
song2 = Sound('Kubbi - Ember - 02 Ember.ogg', {tags = {music}})
|
song2 = Sound('Kubbi - Ember - 02 Ember.ogg', {tags = {music}})
|
||||||
song3 = Sound('Kubbi - Ember - 03 Firelight.ogg', {tags = {music}})
|
song3 = Sound('Kubbi - Ember - 03 Firelight.ogg', {tags = {music}})
|
||||||
|
@ -119,7 +120,6 @@ function init()
|
||||||
song5 = Sound('Kubbi - Ember - 05 Compass.ogg', {tags = {music}})
|
song5 = Sound('Kubbi - Ember - 05 Compass.ogg', {tags = {music}})
|
||||||
death_song = Sound('Kubbi - Ember - 09 Formed by Glaciers.ogg', {tags = {music}})
|
death_song = Sound('Kubbi - Ember - 09 Formed by Glaciers.ogg', {tags = {music}})
|
||||||
|
|
||||||
print('Loading images...')
|
|
||||||
lock_image = Image('lock')
|
lock_image = Image('lock')
|
||||||
speed_booster_elite = Image('speed_booster_elite')
|
speed_booster_elite = Image('speed_booster_elite')
|
||||||
exploder_elite = Image('exploder_elite')
|
exploder_elite = Image('exploder_elite')
|
||||||
|
@ -140,6 +140,7 @@ function init()
|
||||||
swarmer = Image('swarmer')
|
swarmer = Image('swarmer')
|
||||||
voider = Image('voider')
|
voider = Image('voider')
|
||||||
sorcerer = Image('sorcerer')
|
sorcerer = Image('sorcerer')
|
||||||
|
mercenary = Image('mercenary')
|
||||||
ouroboros_technique_r = Image('ouroboros_technique_r')
|
ouroboros_technique_r = Image('ouroboros_technique_r')
|
||||||
ouroboros_technique_l = Image('ouroboros_technique_l')
|
ouroboros_technique_l = Image('ouroboros_technique_l')
|
||||||
wall_echo = Image('wall_echo')
|
wall_echo = Image('wall_echo')
|
||||||
|
@ -185,7 +186,6 @@ function init()
|
||||||
star = Image('star')
|
star = Image('star')
|
||||||
arrow = Image('arrow')
|
arrow = Image('arrow')
|
||||||
|
|
||||||
print('Initializing game...')
|
|
||||||
class_colors = {
|
class_colors = {
|
||||||
['warrior'] = yellow[0],
|
['warrior'] = yellow[0],
|
||||||
['ranger'] = green[0],
|
['ranger'] = green[0],
|
||||||
|
@ -201,6 +201,7 @@ function init()
|
||||||
['swarmer'] = orange[0],
|
['swarmer'] = orange[0],
|
||||||
['voider'] = purple[0],
|
['voider'] = purple[0],
|
||||||
['sorcerer'] = blue2[0],
|
['sorcerer'] = blue2[0],
|
||||||
|
['mercenary'] = yellow2[0],
|
||||||
}
|
}
|
||||||
|
|
||||||
class_color_strings = {
|
class_color_strings = {
|
||||||
|
@ -218,6 +219,7 @@ function init()
|
||||||
['swarmer'] = 'orange',
|
['swarmer'] = 'orange',
|
||||||
['voider'] = 'purple',
|
['voider'] = 'purple',
|
||||||
['sorcerer'] = 'blue2',
|
['sorcerer'] = 'blue2',
|
||||||
|
['mercenary'] = 'yellow2',
|
||||||
}
|
}
|
||||||
|
|
||||||
character_names = {
|
character_names = {
|
||||||
|
@ -270,6 +272,11 @@ function init()
|
||||||
['vulcanist'] = 'Vulcanist',
|
['vulcanist'] = 'Vulcanist',
|
||||||
['warden'] = 'Warden',
|
['warden'] = 'Warden',
|
||||||
['psychic'] = 'Psychic',
|
['psychic'] = 'Psychic',
|
||||||
|
['treasure_hunter'] = 'Treasure Hunter',
|
||||||
|
['merchant'] = 'Merchant',
|
||||||
|
['usurer'] = 'Usurer',
|
||||||
|
['gambler'] = 'Gambler',
|
||||||
|
['thief'] = 'Thief',
|
||||||
}
|
}
|
||||||
|
|
||||||
character_colors = {
|
character_colors = {
|
||||||
|
@ -322,6 +329,11 @@ function init()
|
||||||
['vulcanist'] = red[0],
|
['vulcanist'] = red[0],
|
||||||
['warden'] = yellow[0],
|
['warden'] = yellow[0],
|
||||||
['psychic'] = fg[0],
|
['psychic'] = fg[0],
|
||||||
|
['treasure_hunter'] = yellow2[0],
|
||||||
|
['merchant'] = yellow2[0],
|
||||||
|
['usurer'] = purple[0],
|
||||||
|
['gambler'] = yellow2[0],
|
||||||
|
['thief'] = red[0],
|
||||||
}
|
}
|
||||||
|
|
||||||
character_color_strings = {
|
character_color_strings = {
|
||||||
|
@ -374,6 +386,11 @@ function init()
|
||||||
['vulcanist'] = 'red',
|
['vulcanist'] = 'red',
|
||||||
['warden'] = 'yellow',
|
['warden'] = 'yellow',
|
||||||
['psychic'] = 'fg',
|
['psychic'] = 'fg',
|
||||||
|
['treasure_hunter'] = 'yellow2',
|
||||||
|
['merchant'] = 'yellow2',
|
||||||
|
['usurer'] = 'purple',
|
||||||
|
['gambler'] = 'yellow2',
|
||||||
|
['thief'] = 'red',
|
||||||
}
|
}
|
||||||
|
|
||||||
character_classes = {
|
character_classes = {
|
||||||
|
@ -426,6 +443,11 @@ function init()
|
||||||
['vulcanist'] = {'sorcerer', 'nuker'},
|
['vulcanist'] = {'sorcerer', 'nuker'},
|
||||||
['warden'] = {'sorcerer', 'forcer'},
|
['warden'] = {'sorcerer', 'forcer'},
|
||||||
['psychic'] = {'sorcerer', 'psyker'},
|
['psychic'] = {'sorcerer', 'psyker'},
|
||||||
|
['treasure_hunter'] = {'mercenary'},
|
||||||
|
['merchant'] = {'mercenary'},
|
||||||
|
['usurer'] = {'curser', 'mercenary', 'voider'},
|
||||||
|
['gambler'] = {'mercenary', 'sorcerer'},
|
||||||
|
['thief'] = {'rogue', 'mercenary'},
|
||||||
}
|
}
|
||||||
|
|
||||||
character_class_strings = {
|
character_class_strings = {
|
||||||
|
@ -478,6 +500,11 @@ function init()
|
||||||
['vulcanist'] = '[blue2]Sorcerer, [red]Nuker',
|
['vulcanist'] = '[blue2]Sorcerer, [red]Nuker',
|
||||||
['warden'] = '[blue2]Sorcerer, [yellow]Forcer',
|
['warden'] = '[blue2]Sorcerer, [yellow]Forcer',
|
||||||
['psychic'] = '[blue2]Sorcerer, [fg]Psyker',
|
['psychic'] = '[blue2]Sorcerer, [fg]Psyker',
|
||||||
|
['treasure_hunter'] = '[yellow2]Mercenary',
|
||||||
|
['merchant'] = '[yellow2]Mercenary',
|
||||||
|
['usurer'] = '[purple]Curser, [yellow2]Mercenary, [purple]Curser',
|
||||||
|
['gambler'] = '[yellow2]Mercenary, [blue2]Sorcerer',
|
||||||
|
['thief'] = '[red]Rogue, [yellow2]Mercenary',
|
||||||
}
|
}
|
||||||
|
|
||||||
get_character_stat_string = function(character, level)
|
get_character_stat_string = function(character, level)
|
||||||
|
@ -547,6 +574,11 @@ function init()
|
||||||
['vulcanist'] = function(lvl) return '[fg]creates a volcano that explodes the nearby area [yellow]4[fg] times, dealing [yellow]' .. get_character_stat('vulcanist', lvl, 'dmg') .. ' AoE [fg]damage' end,
|
['vulcanist'] = function(lvl) return '[fg]creates a volcano that explodes the nearby area [yellow]4[fg] times, dealing [yellow]' .. get_character_stat('vulcanist', lvl, 'dmg') .. ' AoE [fg]damage' end,
|
||||||
['warden'] = function(lvl) return '[fg]creates a force field around a random unit that prevents enemies from entering' end,
|
['warden'] = function(lvl) return '[fg]creates a force field around a random unit that prevents enemies from entering' end,
|
||||||
['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,
|
||||||
|
['treasure_hunter'] = function(lvl) return '[fg]picking up gold releases [yellow]4[fg] homing projectiles that each deal [yellow]' .. get_character_stat('treasure_hunter', lvl, 'dmg') .. ' [fg]damage' 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,
|
||||||
|
['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,
|
||||||
}
|
}
|
||||||
|
|
||||||
character_effect_names = {
|
character_effect_names = {
|
||||||
|
@ -598,7 +630,12 @@ function init()
|
||||||
['silencer'] = '[blue2]Arcane Curse',
|
['silencer'] = '[blue2]Arcane Curse',
|
||||||
['vulcanist'] = '[red]Lava Burst',
|
['vulcanist'] = '[red]Lava Burst',
|
||||||
['warden'] = '[yellow]Magnetic Field',
|
['warden'] = '[yellow]Magnetic Field',
|
||||||
['psychic'] = '[fg]Mental Strike'
|
['psychic'] = '[fg]Mental Strike',
|
||||||
|
['treasure_hunter'] = '[yellow2]Golden Bolts',
|
||||||
|
['merchant'] = '[yellow2]Item Shop',
|
||||||
|
['usurer'] = '[purple]Bankruptcy',
|
||||||
|
['gambler'] = '[yellow2]Multicast',
|
||||||
|
['thief'] = '[red]Ultrakill',
|
||||||
}
|
}
|
||||||
|
|
||||||
character_effect_names_gray = {
|
character_effect_names_gray = {
|
||||||
|
@ -650,7 +687,12 @@ function init()
|
||||||
['silencer'] = '[light_bg]Arcane Curse',
|
['silencer'] = '[light_bg]Arcane Curse',
|
||||||
['vulcanist'] = '[light_bg]Lava Burst',
|
['vulcanist'] = '[light_bg]Lava Burst',
|
||||||
['warden'] = '[light_bg]Magnetic Field',
|
['warden'] = '[light_bg]Magnetic Field',
|
||||||
['psychic'] = '[light_bg]Mental Strike'
|
['psychic'] = '[light_bg]Mental Strike',
|
||||||
|
['treasure_hunter'] = '[light_bg]Golden Bolts',
|
||||||
|
['merchant'] = '[light_bg]Item Shop',
|
||||||
|
['usurer'] = '[light_bg]Bankruptcy',
|
||||||
|
['gambler'] = '[light_bg]Multicast',
|
||||||
|
['thief'] = '[light_bg]Ultrakill',
|
||||||
}
|
}
|
||||||
|
|
||||||
character_effect_descriptions = {
|
character_effect_descriptions = {
|
||||||
|
@ -703,6 +745,11 @@ function init()
|
||||||
['vulcanist'] = function() return '[fg]the number and speed of explosions is [yellow]doubled[fg]' end,
|
['vulcanist'] = function() return '[fg]the number and speed of explosions is [yellow]doubled[fg]' end,
|
||||||
['warden'] = function() return '[fg]creates the force field around [yellow]2[fg] units' end,
|
['warden'] = function() return '[fg]creates the force field around [yellow]2[fg] units' end,
|
||||||
['psychic'] = function() return '[fg]the attack can happen from any distance and repeats once' end,
|
['psychic'] = function() return '[fg]the attack can happen from any distance and repeats once' end,
|
||||||
|
['treasure_hunter'] = function() return '[fg]release [yellow]8[fg] homing projectiles instead and they pierce twice' end,
|
||||||
|
['merchant'] = function() return '[fg]your first item reroll is always free' end,
|
||||||
|
['usurer'] = function() return '[fg]if the same enemy is cursed [yellow]3[fg] times it takes [yellow]' .. 10*get_character_stat('usurer', 3, 'dmg') .. '[fg] damage' end,
|
||||||
|
['gambler'] = function() return '[yellow]60/40/20%[fg] chance to cast the attack [yellow]2/3/4[fg] times' end,
|
||||||
|
['thief'] = function() return '[fg]if the knife crits it deals [yellow]' .. 10*get_character_stat('thief', 3, 'dmg') .. '[fg] damage, chains [yellow]10[fg] times and grants [yellow]1[fg] gold' end,
|
||||||
}
|
}
|
||||||
|
|
||||||
character_effect_descriptions_gray = {
|
character_effect_descriptions_gray = {
|
||||||
|
@ -755,6 +802,11 @@ function init()
|
||||||
['vulcanist'] = function() return '[light_bg]the number and speed of explosions is doubled' end,
|
['vulcanist'] = function() return '[light_bg]the number and speed of explosions is doubled' end,
|
||||||
['warden'] = function() return '[light_bg]creates the force field around 2 units' end,
|
['warden'] = function() return '[light_bg]creates the force field around 2 units' end,
|
||||||
['psychic'] = function() return '[light_bg]the attack can happen from any distance and repeats once' end,
|
['psychic'] = function() return '[light_bg]the attack can happen from any distance and repeats once' end,
|
||||||
|
['treasure_hunter'] = function() return '[light_bg]release 8 homing projectiles instead and they pierce twice' end,
|
||||||
|
['merchant'] = function() return '[light_bg]your first item reroll is always free' end,
|
||||||
|
['usurer'] = function() return '[light_bg]if the same enemy is cursed 3 times it takes ' .. 10*get_character_stat('usurer', 3, 'dmg') .. ' damage' end,
|
||||||
|
['gambler'] = function() return '[light_bg]60/40/20% chance to cast the attack 2/3/4 times' end,
|
||||||
|
['thief'] = function() return '[light_bg]if the coin crits it deals ' .. 10*get_character_stat('thief', 3, 'dmg') .. ' damage, chains 10 times and grants 1 gold' end,
|
||||||
}
|
}
|
||||||
|
|
||||||
character_stats = {
|
character_stats = {
|
||||||
|
@ -807,6 +859,11 @@ function init()
|
||||||
['vulcanist'] = function(lvl) return get_character_stat_string('vulcanist', lvl) end,
|
['vulcanist'] = function(lvl) return get_character_stat_string('vulcanist', lvl) end,
|
||||||
['warden'] = function(lvl) return get_character_stat_string('warden', lvl) end,
|
['warden'] = function(lvl) return get_character_stat_string('warden', lvl) end,
|
||||||
['psychic'] = function(lvl) return get_character_stat_string('psychic', lvl) end,
|
['psychic'] = function(lvl) return get_character_stat_string('psychic', lvl) end,
|
||||||
|
['treasure_hunter'] = function(lvl) return get_character_stat_string('treasure_hunter', lvl) end,
|
||||||
|
['merchant'] = function(lvl) return get_character_stat_string('merchant', lvl) end,
|
||||||
|
['usurer'] = function(lvl) return get_character_stat_string('usurer', lvl) end,
|
||||||
|
['gambler'] = function(lvl) return get_character_stat_string('gambler', lvl) end,
|
||||||
|
['thief'] = function(lvl) return get_character_stat_string('thief', lvl) end,
|
||||||
}
|
}
|
||||||
|
|
||||||
class_stat_multipliers = {
|
class_stat_multipliers = {
|
||||||
|
@ -824,6 +881,7 @@ function init()
|
||||||
['swarmer'] = {hp = 1.2, dmg = 1, aspd = 1.25, area_dmg = 1, area_size = 1, def = 0.75, mvspd = 0.75},
|
['swarmer'] = {hp = 1.2, dmg = 1, aspd = 1.25, area_dmg = 1, area_size = 1, def = 0.75, mvspd = 0.75},
|
||||||
['voider'] = {hp = 0.75, dmg = 1.3, aspd = 1, area_dmg = 0.8, area_size = 0.75, def = 0.6, mvspd = 0.8},
|
['voider'] = {hp = 0.75, dmg = 1.3, aspd = 1, area_dmg = 0.8, area_size = 0.75, def = 0.6, mvspd = 0.8},
|
||||||
['sorcerer'] = {hp = 0.8, dmg = 1.3, aspd = 1, area_dmg = 1.2, area_size = 1, def = 0.8, mvspd = 1},
|
['sorcerer'] = {hp = 0.8, dmg = 1.3, aspd = 1, area_dmg = 1.2, area_size = 1, def = 0.8, mvspd = 1},
|
||||||
|
['mercenary'] = {hp = 1, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 1},
|
||||||
['seeker'] = {hp = 0.5, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 0.3},
|
['seeker'] = {hp = 0.5, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 0.3},
|
||||||
['mini_boss'] = {hp = 1, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 0.3},
|
['mini_boss'] = {hp = 1, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 0.3},
|
||||||
['enemy_critter'] = {hp = 1, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 0.5},
|
['enemy_critter'] = {hp = 1, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 0.5},
|
||||||
|
@ -862,17 +920,18 @@ function init()
|
||||||
['sorcerer'] = function(lvl)
|
['sorcerer'] = function(lvl)
|
||||||
return '[' .. ylb1(lvl) .. ']2[' .. ylb2(lvl) .. ']/4[' .. ylb3(lvl) .. ']/6 [fg]- sorcerers repeat their attacks once every [' .. ylb1(lvl) .. ']4/[' .. ylb2(lvl) .. ']3/[' .. ylb3(lvl) .. ']2[fg] attacks'
|
return '[' .. ylb1(lvl) .. ']2[' .. ylb2(lvl) .. ']/4[' .. ylb3(lvl) .. ']/6 [fg]- sorcerers repeat their attacks once every [' .. ylb1(lvl) .. ']4/[' .. ylb2(lvl) .. ']3/[' .. ylb3(lvl) .. ']2[fg] attacks'
|
||||||
end,
|
end,
|
||||||
|
['mercenary'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[' .. ylb2(lvl) .. ']/4 [fg]- [' .. ylb1(lvl) .. ']+10%[' .. ylb2(lvl) .. ']/+20% [fg]chance for enemies to drop gold on death' end,
|
||||||
}
|
}
|
||||||
|
|
||||||
tier_to_characters = {
|
tier_to_characters = {
|
||||||
[1] = {'vagrant', 'swordsman', 'magician', 'archer', 'scout', 'cleric', 'arcanist'},
|
[1] = {'vagrant', 'swordsman', 'magician', 'archer', 'scout', 'cleric', 'arcanist', 'treasure_hunter'},
|
||||||
[2] = {'wizard', 'saboteur', 'sage', 'squire', 'dual_gunner', 'hunter', 'chronomancer', 'barbarian', 'cryomancer', 'beastmaster', 'launcher', 'jester', 'carver', 'psychic', 'witch', 'silencer', 'outlaw'},
|
[2] = {'wizard', 'saboteur', 'sage', 'squire', 'dual_gunner', 'hunter', 'chronomancer', 'barbarian', 'cryomancer', 'beastmaster', 'launcher', 'jester', 'carver', 'psychic', 'witch', 'silencer', 'outlaw', 'merchant'},
|
||||||
[3] = {'elementor', 'stormweaver', 'spellblade', 'psykeeper', 'engineer', 'juggernaut', 'pyromancer', 'host', 'assassin', 'bane', 'barrager', 'infestor', 'flagellant', 'illusionist'},
|
[3] = {'elementor', 'stormweaver', 'spellblade', 'psykeeper', 'engineer', 'juggernaut', 'pyromancer', 'host', 'assassin', 'bane', 'barrager', 'infestor', 'flagellant', 'illusionist', 'usurer', 'gambler'},
|
||||||
[4] = {'priest', 'highlander', 'psykino', 'fairy', 'blade', 'plague_doctor', 'cannoneer', 'vulcanist', 'warden', 'corruptor'},
|
[4] = {'priest', 'highlander', 'psykino', 'fairy', 'blade', 'plague_doctor', 'cannoneer', 'vulcanist', 'warden', 'corruptor', 'thief'},
|
||||||
}
|
}
|
||||||
|
|
||||||
non_attacking_characters = {'cleric', 'stormweaver', 'squire', 'chronomancer', 'sage', 'psykeeper', 'bane', 'carver', 'fairy', 'priest', 'flagellant'}
|
non_attacking_characters = {'cleric', 'stormweaver', 'squire', 'chronomancer', 'sage', 'psykeeper', 'bane', 'carver', 'fairy', 'priest', 'flagellant', 'merchant', 'treasure_hunter'}
|
||||||
non_cooldown_characters = {'squire', 'chronomancer', 'psykeeper'}
|
non_cooldown_characters = {'squire', 'chronomancer', 'psykeeper', 'merchant', 'treasure_hunter'}
|
||||||
|
|
||||||
character_tiers = {
|
character_tiers = {
|
||||||
['vagrant'] = 1,
|
['vagrant'] = 1,
|
||||||
|
@ -881,7 +940,6 @@ function init()
|
||||||
['archer'] = 1,
|
['archer'] = 1,
|
||||||
['scout'] = 1,
|
['scout'] = 1,
|
||||||
['cleric'] = 1,
|
['cleric'] = 1,
|
||||||
['arcanist'] = 1,
|
|
||||||
['outlaw'] = 2,
|
['outlaw'] = 2,
|
||||||
['blade'] = 4,
|
['blade'] = 4,
|
||||||
['elementor'] = 3,
|
['elementor'] = 3,
|
||||||
|
@ -918,12 +976,18 @@ function init()
|
||||||
['priest'] = 4,
|
['priest'] = 4,
|
||||||
['infestor'] = 3,
|
['infestor'] = 3,
|
||||||
['flagellant'] = 3,
|
['flagellant'] = 3,
|
||||||
['psychic'] = 2,
|
['arcanist'] = 1,
|
||||||
|
['illusionist'] = 3,
|
||||||
['witch'] = 2,
|
['witch'] = 2,
|
||||||
['silencer'] = 2,
|
['silencer'] = 2,
|
||||||
['illusionist'] = 3,
|
|
||||||
['warden'] = 4,
|
|
||||||
['vulcanist'] = 4,
|
['vulcanist'] = 4,
|
||||||
|
['warden'] = 4,
|
||||||
|
['psychic'] = 2,
|
||||||
|
['treasure_hunter'] = 1,
|
||||||
|
['merchant'] = 2,
|
||||||
|
['usurer'] = 3,
|
||||||
|
['gambler'] = 3,
|
||||||
|
['thief'] = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
get_number_of_units_per_class = function(units)
|
get_number_of_units_per_class = function(units)
|
||||||
|
@ -941,6 +1005,7 @@ function init()
|
||||||
local swarmers = 0
|
local swarmers = 0
|
||||||
local voiders = 0
|
local voiders = 0
|
||||||
local sorcerers = 0
|
local sorcerers = 0
|
||||||
|
local mercenaries = 0
|
||||||
for _, unit in ipairs(units) do
|
for _, unit in ipairs(units) do
|
||||||
for _, unit_class in ipairs(character_classes[unit.character]) do
|
for _, unit_class in ipairs(character_classes[unit.character]) do
|
||||||
if unit_class == 'ranger' then rangers = rangers + 1 end
|
if unit_class == 'ranger' then rangers = rangers + 1 end
|
||||||
|
@ -957,10 +1022,11 @@ function init()
|
||||||
if unit_class == 'swarmer' then swarmers = swarmers + 1 end
|
if unit_class == 'swarmer' then swarmers = swarmers + 1 end
|
||||||
if unit_class == 'voider' then voiders = voiders + 1 end
|
if unit_class == 'voider' then voiders = voiders + 1 end
|
||||||
if unit_class == 'sorcerer' then sorcerers = sorcerers + 1 end
|
if unit_class == 'sorcerer' then sorcerers = sorcerers + 1 end
|
||||||
|
if unit_class == 'mercenary' then mercenaries = mercenaries + 1 end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return {ranger = rangers, warrior = warriors, healer = healers, mage = mages, nuker = nukers, conjurer = conjurers, rogue = rogues,
|
return {ranger = rangers, warrior = warriors, healer = healers, mage = mages, nuker = nukers, conjurer = conjurers, rogue = rogues,
|
||||||
enchanter = enchanters, psyker = psykers, curser = cursers, forcer = forcers, swarmer = swarmers, voider = voiders, sorcerer = sorcerers}
|
enchanter = enchanters, psyker = psykers, curser = cursers, forcer = forcers, swarmer = swarmers, voider = voiders, sorcerer = sorcerers, mercenary = mercenaries}
|
||||||
end
|
end
|
||||||
|
|
||||||
get_class_levels = function(units)
|
get_class_levels = function(units)
|
||||||
|
@ -970,7 +1036,7 @@ function init()
|
||||||
if number_of_units >= 6 then return 2
|
if number_of_units >= 6 then return 2
|
||||||
elseif number_of_units >= 3 then return 1
|
elseif number_of_units >= 3 then return 1
|
||||||
else return 0 end
|
else return 0 end
|
||||||
elseif class == 'healer' or class == 'conjurer' or class == 'enchanter' or class == 'psyker' or class == 'curser' or class == 'forcer' or class == 'swarmer' or class == 'voider' then
|
elseif class == 'healer' or class == 'conjurer' or class == 'enchanter' or class == 'psyker' or class == 'curser' or class == 'forcer' or class == 'swarmer' or class == 'voider' or class == 'mercenary' then
|
||||||
if number_of_units >= 4 then return 2
|
if number_of_units >= 4 then return 2
|
||||||
elseif number_of_units >= 2 then return 1
|
elseif number_of_units >= 2 then return 1
|
||||||
else return 0 end
|
else return 0 end
|
||||||
|
@ -996,6 +1062,7 @@ function init()
|
||||||
swarmer = units_to_class_level(units_per_class.swarmer, 'swarmer'),
|
swarmer = units_to_class_level(units_per_class.swarmer, 'swarmer'),
|
||||||
voider = units_to_class_level(units_per_class.voider, 'voider'),
|
voider = units_to_class_level(units_per_class.voider, 'voider'),
|
||||||
sorcerer = units_to_class_level(units_per_class.sorcerer, 'sorcerer'),
|
sorcerer = units_to_class_level(units_per_class.sorcerer, 'sorcerer'),
|
||||||
|
mercenary = units_to_class_level(units_per_class.mercenary, 'mercenary'),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1022,6 +1089,7 @@ function init()
|
||||||
['swarmer'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).swarmer end,
|
['swarmer'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).swarmer end,
|
||||||
['voider'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).voider end,
|
['voider'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).voider end,
|
||||||
['sorcerer'] = function(units) return 2, 4, 6, get_number_of_units_per_class(units).sorcerer end,
|
['sorcerer'] = function(units) return 2, 4, 6, get_number_of_units_per_class(units).sorcerer end,
|
||||||
|
['mercenary'] = function(units) return 2, 4, nil, get_number_of_units_per_class(units).mercenary end,
|
||||||
}
|
}
|
||||||
|
|
||||||
passive_names = {
|
passive_names = {
|
||||||
|
@ -1323,22 +1391,16 @@ function init()
|
||||||
end
|
end
|
||||||
-- main_song_instance = _G[random:table{'song1', 'song2', 'song3', 'song4', 'song5'}]:play{volume = 0.5}
|
-- main_song_instance = _G[random:table{'song1', 'song2', 'song3', 'song4', 'song5'}]:play{volume = 0.5}
|
||||||
|
|
||||||
|
|
||||||
main:add(BuyScreen'buy_screen')
|
main:add(BuyScreen'buy_screen')
|
||||||
main:go_to('buy_screen', run.level or 0, run.units or {}, passives)
|
main:go_to('buy_screen', run.level or 0, run.units or {}, passives)
|
||||||
-- main:go_to('buy_screen', 7, run.units or {}, {'unleash'})
|
-- main:go_to('buy_screen', 7, run.units or {}, {'unleash'})
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
main:add(Arena'arena')
|
main:add(Arena'arena')
|
||||||
main:go_to('arena', 17, {
|
main:go_to('arena', 13, {
|
||||||
{character = 'arcanist', level = 2},
|
{character = 'thief', level = 3},
|
||||||
{character = 'silencer', level = 2},
|
{character = 'scout', level = 1},
|
||||||
{character = 'warden', level = 3},
|
{character = 'beastmaster', level = 1},
|
||||||
{character = 'chronomancer', level = 1},
|
|
||||||
{character = 'witch', level = 3},
|
|
||||||
{character = 'illusionist', level = 3},
|
|
||||||
{character = 'psychic', level = 2},
|
|
||||||
{character = 'vulcanist', level = 3},
|
|
||||||
}, passives)
|
}, passives)
|
||||||
]]--
|
]]--
|
||||||
|
|
||||||
|
|
247
player.lua
247
player.lua
|
@ -47,7 +47,6 @@ function Player:init(args)
|
||||||
self:attack(32, {x = enemy.x, y = enemy.y})
|
self:attack(32, {x = enemy.x, y = enemy.y})
|
||||||
end
|
end
|
||||||
end, nil, nil, 'attack')
|
end, nil, nil, 'attack')
|
||||||
|
|
||||||
if self.level == 3 then
|
if self.level == 3 then
|
||||||
self.t:every(12, function()
|
self.t:every(12, function()
|
||||||
self.magician_invulnerable = true
|
self.magician_invulnerable = true
|
||||||
|
@ -55,6 +54,60 @@ function Player:init(args)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
elseif self.character == 'gambler' then
|
||||||
|
self.sorcerer_count = 0
|
||||||
|
local cast = function(pitch_a)
|
||||||
|
local enemy = table.shuffle(main.current.main:get_objects_by_classes(main.current.enemies))[1]
|
||||||
|
if enemy then
|
||||||
|
gambler1:play{pitch = pitch_a, volume = math.remap(gold, 0, 50, 0, 0.8)}
|
||||||
|
enemy:hit(2*gold)
|
||||||
|
if main.current.sorcerer_level > 0 then
|
||||||
|
self.sorcerer_count = self.sorcerer_count + 1
|
||||||
|
if self.sorcerer_count >= ((main.current.sorcerer_level == 3 and 2) or (main.current.sorcerer_level == 2 and 3) or (main.current.sorcerer_level == 1 and 4)) then
|
||||||
|
self.sorcerer_count = 0
|
||||||
|
self.t:after(0.25, function()
|
||||||
|
local enemy = table.shuffle(main.current.main:get_objects_by_classes(main.current.enemies))[1]
|
||||||
|
if enemy then
|
||||||
|
gambler1:play{pitch = pitch_a + 0.05, volume = math.remap(gold, 0, 50, 0, 0.8)}
|
||||||
|
enemy:hit(2*gold)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.t:every(2, function()
|
||||||
|
cast(1)
|
||||||
|
if self.level == 3 then
|
||||||
|
if random:bool(60) then
|
||||||
|
if random:bool(40) then
|
||||||
|
if random:bool(20) then
|
||||||
|
self.t:after(0.25, function()
|
||||||
|
cast(1.1)
|
||||||
|
self.t:after(0.25, function()
|
||||||
|
cast(1.2)
|
||||||
|
self.t:after(0.25, function()
|
||||||
|
cast(1.3)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
self.t:after(0.25, function()
|
||||||
|
cast(1.1)
|
||||||
|
self.t:after(0.25, function()
|
||||||
|
cast(1.2)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self.t:after(0.25, function()
|
||||||
|
cast(1.1)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end, nil, nil, 'attack')
|
||||||
|
|
||||||
elseif self.character == 'archer' then
|
elseif self.character == 'archer' then
|
||||||
self.attack_sensor = Circle(self.x, self.y, 160)
|
self.attack_sensor = Circle(self.x, self.y, 160)
|
||||||
self.t:cooldown(2, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
self.t:cooldown(2, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||||
|
@ -73,6 +126,15 @@ function Player:init(args)
|
||||||
end
|
end
|
||||||
end, nil, nil, 'shoot')
|
end, nil, nil, 'shoot')
|
||||||
|
|
||||||
|
elseif self.character == 'thief' then
|
||||||
|
self.attack_sensor = Circle(self.x, self.y, 64)
|
||||||
|
self.t:cooldown(2, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||||
|
local closest_enemy = self:get_closest_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||||
|
if closest_enemy then
|
||||||
|
self:shoot(self:angle_to_object(closest_enemy), {chain = (self.level == 3 and 10 or 5)})
|
||||||
|
end
|
||||||
|
end, nil, nil, 'shoot')
|
||||||
|
|
||||||
elseif self.character == 'cleric' then
|
elseif self.character == 'cleric' then
|
||||||
self.t:every(6, function()
|
self.t:every(6, function()
|
||||||
local all_units = self:get_all_units()
|
local all_units = self:get_all_units()
|
||||||
|
@ -261,12 +323,12 @@ function Player:init(args)
|
||||||
if x == 0 and y == 0 then x, y = gw/2, gh/2 end
|
if x == 0 and y == 0 then x, y = gw/2, gh/2 end
|
||||||
x, y = x + self.x, y + self.y
|
x, y = x + self.x, y + self.y
|
||||||
x, y = x/2, y/2
|
x, y = x/2, y/2
|
||||||
trigger:every_immediate(0.1, function()
|
main.current.t:every_immediate(0.1, function()
|
||||||
local check_circle = Circle(x, y, 2)
|
local check_circle = Circle(x, y, 2)
|
||||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Player, Seeker, EnemyCritter, Critter, Illusion, Saboteur, Pet, Turret})
|
local objects = main.current.main:get_objects_in_shape(check_circle, {Player, Seeker, EnemyCritter, Critter, Illusion, Saboteur, Pet, Turret})
|
||||||
if #objects == 0 then
|
if #objects == 0 then
|
||||||
Volcano{group = main.current.main, x = x, y = y, color = self.color, parent = self, rs = 24, level = self.level}
|
Volcano{group = main.current.main, x = x, y = y, color = self.color, parent = self, rs = 24, level = self.level}
|
||||||
trigger:cancel('volcano_spawn')
|
main.current.t:cancel('volcano_spawn')
|
||||||
end
|
end
|
||||||
end, nil, nil, 'volcano_spawn')
|
end, nil, nil, 'volcano_spawn')
|
||||||
end
|
end
|
||||||
|
@ -431,9 +493,10 @@ function Player:init(args)
|
||||||
|
|
||||||
elseif self.character == 'jester' then
|
elseif self.character == 'jester' then
|
||||||
self.attack_sensor = Circle(self.x, self.y, 96)
|
self.attack_sensor = Circle(self.x, self.y, 96)
|
||||||
|
self.wide_attack_sensor = Circle(self.x, self.y, 128)
|
||||||
self.t:cooldown(6, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
self.t:cooldown(6, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||||
buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
||||||
local enemies = table.first(table.shuffle(main.current.main:get_objects_by_classes(main.current.enemies)), 6)
|
local enemies = table.first(table.shuffle(self:get_objects_in_shape(self.wide_attack_sensor, main.current.enemies)), 6)
|
||||||
for _, enemy in ipairs(enemies) do
|
for _, enemy in ipairs(enemies) do
|
||||||
if self:distance_to_object(enemy) < 128 then
|
if self:distance_to_object(enemy) < 128 then
|
||||||
enemy:curse('jester', 6*(self.hex_duration_m or 1), self.level == 3, self)
|
enemy:curse('jester', 6*(self.hex_duration_m or 1), self.level == 3, self)
|
||||||
|
@ -443,26 +506,39 @@ function Player:init(args)
|
||||||
end
|
end
|
||||||
end, nil, nil, 'attack')
|
end, nil, nil, 'attack')
|
||||||
|
|
||||||
|
elseif self.character == 'usurer' then
|
||||||
|
self.attack_sensor = Circle(self.x, self.y, 96)
|
||||||
|
self.wide_attack_sensor = Circle(self.x, self.y, 128)
|
||||||
|
self.t:cooldown(6, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||||
|
buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
||||||
|
local enemies = table.first2(table.shuffle(self:get_objects_in_shape(self.wide_attack_sensor, main.current.enemies)), 3)
|
||||||
|
for _, enemy in ipairs(enemies) do
|
||||||
|
enemy:curse('usurer', 10000, self.level == 3, self)
|
||||||
|
enemy:apply_dot(self.dmg*(self.dot_dmg_m or 1)*(main.current.chronomancer_dot or 1), 10000)
|
||||||
|
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = purple[0], duration = 0.1}
|
||||||
|
LightningLine{group = main.current.effects, src = self, dst = enemy, color = purple[0]}
|
||||||
|
end
|
||||||
|
end, nil, nil, 'attack')
|
||||||
|
|
||||||
elseif self.character == 'silencer' then
|
elseif self.character == 'silencer' then
|
||||||
self.sorcerer_count = 0
|
self.sorcerer_count = 0
|
||||||
self.attack_sensor = Circle(self.x, self.y, 96)
|
self.attack_sensor = Circle(self.x, self.y, 96)
|
||||||
|
self.wide_attack_sensor = Circle(self.x, self.y, 128)
|
||||||
self.t:cooldown(6, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
self.t:cooldown(6, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||||
local curse = function()
|
local curse = function()
|
||||||
buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
||||||
local enemies = table.first(table.shuffle(main.current.main:get_objects_by_classes(main.current.enemies)), 6)
|
local enemies = table.first(table.shuffle(self:get_objects_in_shape(self.wide_attack_sensor, main.current.enemies)), 6)
|
||||||
for _, enemy in ipairs(enemies) do
|
for _, enemy in ipairs(enemies) do
|
||||||
if self:distance_to_object(enemy) < 128 then
|
enemy:curse('silencer', 6*(self.hex_duration_m or 1), self.level == 3, self)
|
||||||
enemy:curse('silencer', 6*(self.hex_duration_m or 1), self.level == 3, self)
|
if self.level == 3 then
|
||||||
if self.level == 3 then
|
local curse_m = 1
|
||||||
local curse_m = 1
|
if main.current.curser_level == 2 then curse_m = 1.5
|
||||||
if main.current.curser_level == 2 then curse_m = 1.5
|
elseif main.current.curser_level == 1 then curse_m = 1.25
|
||||||
elseif main.current.curser_level == 1 then curse_m = 1.25
|
else curse_m = 1 end
|
||||||
else curse_m = 1 end
|
enemy:apply_dot(self.dmg*(self.dot_dmg_m or 1)*(main.current.chronomancer_dot or 1), 6*(self.hex_duration_m or 1)*(curse_m or 1))
|
||||||
enemy:apply_dot(self.dmg*(self.dot_dmg_m or 1)*(main.current.chronomancer_dot or 1), 6*(self.hex_duration_m or 1)*(curse_m or 1))
|
|
||||||
end
|
|
||||||
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = blue2[0], duration = 0.1}
|
|
||||||
LightningLine{group = main.current.effects, src = self, dst = enemy, color = blue2[0]}
|
|
||||||
end
|
end
|
||||||
|
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = blue2[0], duration = 0.1}
|
||||||
|
LightningLine{group = main.current.effects, src = self, dst = enemy, color = blue2[0]}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
curse()
|
curse()
|
||||||
|
@ -508,15 +584,14 @@ function Player:init(args)
|
||||||
|
|
||||||
elseif self.character == 'bane' then
|
elseif self.character == 'bane' then
|
||||||
self.attack_sensor = Circle(self.x, self.y, 96)
|
self.attack_sensor = Circle(self.x, self.y, 96)
|
||||||
|
self.wide_attack_sensor = Circle(self.x, self.y, 128)
|
||||||
self.t:cooldown(6, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
self.t:cooldown(6, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||||
buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
||||||
local enemies = table.first(table.shuffle(main.current.main:get_objects_by_classes(main.current.enemies)), 6)
|
local enemies = table.first(table.shuffle(self:get_objects_in_shape(self.wide_attack_sensor, main.current.enemies)), 6)
|
||||||
for _, enemy in ipairs(enemies) do
|
for _, enemy in ipairs(enemies) do
|
||||||
if self:distance_to_object(enemy) < 128 then
|
enemy:curse('bane', 6*(self.hex_duration_m or 1), self.level == 3, self)
|
||||||
enemy:curse('bane', 6*(self.hex_duration_m or 1), self.level == 3, self)
|
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = purple[0], duration = 0.1}
|
||||||
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = purple[0], duration = 0.1}
|
LightningLine{group = main.current.effects, src = self, dst = enemy, color = purple[0]}
|
||||||
LightningLine{group = main.current.effects, src = self, dst = enemy, color = purple[0]}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end, nil, nil, 'attack')
|
end, nil, nil, 'attack')
|
||||||
|
|
||||||
|
@ -603,24 +678,24 @@ function Player:init(args)
|
||||||
local unit_2 = random:table_remove(units)
|
local unit_2 = random:table_remove(units)
|
||||||
if unit_1 then
|
if unit_1 then
|
||||||
illusion1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
illusion1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||||
trigger:every_immediate(0.1, function()
|
main.current.t:every_immediate(0.1, function()
|
||||||
local check_circle = Circle(unit_1.x, unit_1.y, 6)
|
local check_circle = Circle(unit_1.x, unit_1.y, 6)
|
||||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter})
|
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter})
|
||||||
if #objects == 0 then
|
if #objects == 0 then
|
||||||
ForceField{group = main.current.main, x = unit_1.x, y = unit_1.y, parent = unit_1}
|
ForceField{group = main.current.main, x = unit_1.x, y = unit_1.y, parent = unit_1}
|
||||||
trigger:cancel('warden_force_field_1')
|
main.current.t:cancel('warden_force_field_1')
|
||||||
end
|
end
|
||||||
end, nil, nil, 'warden_force_field_1')
|
end, nil, nil, 'warden_force_field_1')
|
||||||
end
|
end
|
||||||
if unit_2 then
|
if unit_2 then
|
||||||
illusion1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
illusion1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||||
ForceField{group = main.current.main, x = unit_2.x, y = unit_2.y, parent = unit_2}
|
ForceField{group = main.current.main, x = unit_2.x, y = unit_2.y, parent = unit_2}
|
||||||
trigger:every_immediate(0.1, function()
|
main.current.t:every_immediate(0.1, function()
|
||||||
local check_circle = Circle(unit_2.x, unit_2.y, 6)
|
local check_circle = Circle(unit_2.x, unit_2.y, 6)
|
||||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter})
|
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter})
|
||||||
if #objects == 0 then
|
if #objects == 0 then
|
||||||
ForceField{group = main.current.main, x = unit_2.x, y = unit_2.y, parent = unit_2}
|
ForceField{group = main.current.main, x = unit_2.x, y = unit_2.y, parent = unit_2}
|
||||||
trigger:cancel('warden_force_field_2')
|
main.current.t:cancel('warden_force_field_2')
|
||||||
end
|
end
|
||||||
end, nil, nil, 'warden_force_field_2')
|
end, nil, nil, 'warden_force_field_2')
|
||||||
end
|
end
|
||||||
|
@ -628,12 +703,12 @@ function Player:init(args)
|
||||||
local unit = random:table(self:get_all_units())
|
local unit = random:table(self:get_all_units())
|
||||||
if unit then
|
if unit then
|
||||||
illusion1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
illusion1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||||
trigger:every_immediate(0.1, function()
|
main.current.t:every_immediate(0.1, function()
|
||||||
local check_circle = Circle(unit.x, unit.y, 6)
|
local check_circle = Circle(unit.x, unit.y, 6)
|
||||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter})
|
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter})
|
||||||
if #objects == 0 then
|
if #objects == 0 then
|
||||||
ForceField{group = main.current.main, x = unit.x, y = unit.y, parent = unit}
|
ForceField{group = main.current.main, x = unit.x, y = unit.y, parent = unit}
|
||||||
trigger:cancel('warden_force_field_0')
|
main.current.t:cancel('warden_force_field_0')
|
||||||
end
|
end
|
||||||
end, nil, nil, 'warden_force_field_0')
|
end, nil, nil, 'warden_force_field_0')
|
||||||
end
|
end
|
||||||
|
@ -671,16 +746,15 @@ function Player:init(args)
|
||||||
end, nil, nil, 'heal')
|
end, nil, nil, 'heal')
|
||||||
|
|
||||||
elseif self.character == 'infestor' then
|
elseif self.character == 'infestor' then
|
||||||
self.attack_sensor = Circle(self.x, self.y, 128)
|
self.attack_sensor = Circle(self.x, self.y, 96)
|
||||||
|
self.wide_attack_sensor = Circle(self.x, self.y, 128)
|
||||||
self.t:cooldown(6, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
self.t:cooldown(6, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
|
||||||
buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
buff1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
||||||
local enemies = table.first(table.shuffle(main.current.main:get_objects_by_classes(main.current.enemies)), 8)
|
local enemies = table.first(table.shuffle(self:get_objects_in_shape(self.wide_attack_sensor, main.current.enemies)), 8)
|
||||||
for _, enemy in ipairs(enemies) do
|
for _, enemy in ipairs(enemies) do
|
||||||
if self:distance_to_object(enemy) < 128 then
|
enemy:curse('infestor', 6*(self.hex_duration_m or 1), (self.level == 3 and 6 or 2), self.dmg, self)
|
||||||
enemy:curse('infestor', 6*(self.hex_duration_m or 1), (self.level == 3 and 6 or 2), self.dmg, self)
|
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = orange[0], duration = 0.1}
|
||||||
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = orange[0], duration = 0.1}
|
LightningLine{group = main.current.effects, src = self, dst = enemy, color = orange[0]}
|
||||||
LightningLine{group = main.current.effects, src = self, dst = enemy, color = orange[0]}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end, nil, nil, 'attack')
|
end, nil, nil, 'attack')
|
||||||
|
|
||||||
|
@ -923,6 +997,7 @@ function Player:update(dt)
|
||||||
if class_levels.swarmer >= 1 then number_of_active_sets = number_of_active_sets + 1 end
|
if class_levels.swarmer >= 1 then number_of_active_sets = number_of_active_sets + 1 end
|
||||||
if class_levels.voider >= 1 then number_of_active_sets = number_of_active_sets + 1 end
|
if class_levels.voider >= 1 then number_of_active_sets = number_of_active_sets + 1 end
|
||||||
if class_levels.sorcerer >= 1 then number_of_active_sets = number_of_active_sets + 1 end
|
if class_levels.sorcerer >= 1 then number_of_active_sets = number_of_active_sets + 1 end
|
||||||
|
if class_levels.mercenary >= 1 then number_of_active_sets = number_of_active_sets + 1 end
|
||||||
self.vagrant_dmg_m = 1 + 0.1*number_of_active_sets
|
self.vagrant_dmg_m = 1 + 0.1*number_of_active_sets
|
||||||
self.vagrant_aspd_m = 1 + 0.1*number_of_active_sets
|
self.vagrant_aspd_m = 1 + 0.1*number_of_active_sets
|
||||||
end
|
end
|
||||||
|
@ -988,6 +1063,7 @@ function Player:update(dt)
|
||||||
if class_levels.swarmer >= 1 then number_of_active_sets = number_of_active_sets + 1 end
|
if class_levels.swarmer >= 1 then number_of_active_sets = number_of_active_sets + 1 end
|
||||||
if class_levels.voider >= 1 then number_of_active_sets = number_of_active_sets + 1 end
|
if class_levels.voider >= 1 then number_of_active_sets = number_of_active_sets + 1 end
|
||||||
if class_levels.sorcerer >= 1 then number_of_active_sets = number_of_active_sets + 1 end
|
if class_levels.sorcerer >= 1 then number_of_active_sets = number_of_active_sets + 1 end
|
||||||
|
if class_levels.mercenary >= 1 then number_of_active_sets = number_of_active_sets + 1 end
|
||||||
if main.current.psyker_level == 2 then
|
if main.current.psyker_level == 2 then
|
||||||
self.psyker_dmg_m = 1 + 0.2*number_of_active_sets
|
self.psyker_dmg_m = 1 + 0.2*number_of_active_sets
|
||||||
self.psyker_aspd_m = 1 + 0.2*number_of_active_sets
|
self.psyker_aspd_m = 1 + 0.2*number_of_active_sets
|
||||||
|
@ -1039,6 +1115,7 @@ function Player:update(dt)
|
||||||
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
|
||||||
|
if self.wide_attack_sensor then self.wide_attack_sensor:move_to(self.x, self.y) end
|
||||||
if self.gun_kata_sensor then self.gun_kata_sensor:move_to(self.x, self.y) end
|
if self.gun_kata_sensor then self.gun_kata_sensor:move_to(self.x, self.y) end
|
||||||
self.t:set_every_multiplier('shoot', self.aspd_m)
|
self.t:set_every_multiplier('shoot', self.aspd_m)
|
||||||
self.t:set_every_multiplier('attack', self.aspd_m)
|
self.t:set_every_multiplier('attack', self.aspd_m)
|
||||||
|
@ -1371,6 +1448,14 @@ function Player:shoot(r, mods)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if self.character == 'thief' then
|
||||||
|
dmg_m = dmg_m*2
|
||||||
|
if self.level == 3 and crit then
|
||||||
|
dmg_m = dmg_m*10
|
||||||
|
main.current.gold_picked_up = main.current.gold_picked_up + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if crit and mods.spawn_critters_on_crit then
|
if crit and mods.spawn_critters_on_crit then
|
||||||
critter1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
critter1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||||
trigger:after(0.01, function()
|
trigger:after(0.01, function()
|
||||||
|
@ -1450,7 +1535,8 @@ function Player:shoot(r, mods)
|
||||||
archer1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
archer1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||||
elseif self.character == 'wizard' or self.character == 'lich' or self.character == 'arcanist' then
|
elseif self.character == 'wizard' or self.character == 'lich' or self.character == 'arcanist' then
|
||||||
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
|
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
|
||||||
elseif self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' or self.character == 'spellblade' or self.character == 'jester' or self.character == 'assassin' or self.character == 'beastmaster' then
|
elseif self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' or self.character == 'spellblade' or self.character == 'jester' or self.character == 'assassin' or self.character == 'beastmaster' or
|
||||||
|
self.character == 'thief' then
|
||||||
_G[random:table{'scout1', 'scout2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
_G[random:table{'scout1', 'scout2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||||
if self.character == 'spellblade' then
|
if self.character == 'spellblade' then
|
||||||
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
|
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
|
||||||
|
@ -1609,6 +1695,12 @@ function Projectile:init(args)
|
||||||
|
|
||||||
elseif self.character == 'witch' and self.level == 3 then
|
elseif self.character == 'witch' and self.level == 3 then
|
||||||
self.chain = 1
|
self.chain = 1
|
||||||
|
|
||||||
|
elseif self.character == 'treasure_hunter' then
|
||||||
|
self.homing = true
|
||||||
|
if self.level == 3 then
|
||||||
|
self.pierce = 2
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.parent.divine_machine_arrow and table.any(self.parent.classes, function(v) return v == 'ranger' end) then
|
if self.parent.divine_machine_arrow and table.any(self.parent.classes, function(v) return v == 'ranger' end) then
|
||||||
|
@ -1764,7 +1856,8 @@ function Projectile:on_collision_enter(other, contact)
|
||||||
self.ricochet = self.ricochet - 1
|
self.ricochet = self.ricochet - 1
|
||||||
end
|
end
|
||||||
_G[random:table{'arrow_hit_wall1', 'arrow_hit_wall2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.2}
|
_G[random:table{'arrow_hit_wall1', 'arrow_hit_wall2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.2}
|
||||||
elseif self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' or self.character == 'spellblade' or self.character == 'jester' or self.character == 'beastmaster' or self.character == 'witch' then
|
elseif self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' or self.character == 'spellblade' or self.character == 'jester' or self.character == 'beastmaster' or self.character == 'witch' or
|
||||||
|
self.character == 'thief' then
|
||||||
self:die(x, y, r, 0)
|
self:die(x, y, r, 0)
|
||||||
knife_hit_wall1:play{pitch = random:float(0.9, 1.1), volume = 0.2}
|
knife_hit_wall1:play{pitch = random:float(0.9, 1.1), volume = 0.2}
|
||||||
local r = Unit.bounce(self, nx, ny)
|
local r = Unit.bounce(self, nx, ny)
|
||||||
|
@ -1789,7 +1882,7 @@ function Projectile:on_collision_enter(other, contact)
|
||||||
elseif self.character == 'cannoneer' then
|
elseif self.character == 'cannoneer' then
|
||||||
self:die(x, y, r, random:int(2, 3))
|
self:die(x, y, r, random:int(2, 3))
|
||||||
cannon_hit_wall1:play{pitch = random:float(0.95, 1.05), volume = 0.1}
|
cannon_hit_wall1:play{pitch = random:float(0.95, 1.05), volume = 0.1}
|
||||||
elseif self.character == 'engineer' or self.character == 'dual_gunner' then
|
elseif self.character == 'engineer' or self.character == 'dual_gunner' or self.character == 'treasure_hunter' then
|
||||||
self:die(x, y, r, random:int(2, 3))
|
self:die(x, y, r, random:int(2, 3))
|
||||||
_G[random:table{'turret_hit_wall1', 'turret_hit_wall2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.2}
|
_G[random:table{'turret_hit_wall1', 'turret_hit_wall2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.2}
|
||||||
else
|
else
|
||||||
|
@ -1838,7 +1931,7 @@ function Projectile:on_trigger_enter(other, contact)
|
||||||
end
|
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
|
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 == 'jester' or self.character == 'assassin' or self.character == 'barrager' or self.character == 'beastmaster' or self.character == 'witch' then
|
self.character == 'jester' or self.character == 'assassin' or self.character == 'barrager' or self.character == 'beastmaster' or self.character == 'witch' or self.character == 'treasure_hunter' or self.character == 'thief' then
|
||||||
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||||
if self.character == 'spellblade' then
|
if self.character == 'spellblade' then
|
||||||
magic_area1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
|
magic_area1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
|
||||||
|
@ -2427,6 +2520,7 @@ Volcano:implement(GameObject)
|
||||||
Volcano:implement(Physics)
|
Volcano:implement(Physics)
|
||||||
function Volcano:init(args)
|
function Volcano:init(args)
|
||||||
self:init_game_object(args)
|
self:init_game_object(args)
|
||||||
|
if not self.group.world then self.dead = true; return end
|
||||||
self:set_as_rectangle(9, 9, 'static', 'player')
|
self:set_as_rectangle(9, 9, 'static', 'player')
|
||||||
self:set_restitution(0.5)
|
self:set_restitution(0.5)
|
||||||
self.hfx:add('hit', 1)
|
self.hfx:add('hit', 1)
|
||||||
|
@ -2777,6 +2871,81 @@ function Illusion:draw()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
Gold = Object:extend()
|
||||||
|
Gold:implement(GameObject)
|
||||||
|
Gold:implement(Physics)
|
||||||
|
function Gold:init(args)
|
||||||
|
self:init_game_object(args)
|
||||||
|
self:set_as_rectangle(3, 3, 'dynamic', 'ghost')
|
||||||
|
self:set_restitution(0.5)
|
||||||
|
local r = random:float(0, 2*math.pi)
|
||||||
|
local f = random:float(2, 4)
|
||||||
|
self:apply_impulse(f*math.cos(r), f*math.sin(r))
|
||||||
|
self:apply_angular_impulse(random:table{random:float(-6*math.pi, -2*math.pi), random:float(2*math.pi, 6*math.pi)})
|
||||||
|
self:set_damping(2.5)
|
||||||
|
self:set_angular_damping(5)
|
||||||
|
self.color = yellow2[0]
|
||||||
|
self.hfx:add('hit', 1)
|
||||||
|
gold1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function Gold:update(dt)
|
||||||
|
self:update_game_object(dt)
|
||||||
|
self.r = self:get_angle()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function Gold:draw()
|
||||||
|
graphics.push(self.x, self.y, self.r, self.hfx.hit.x, self.hfx.hit.x)
|
||||||
|
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 1, 1, self.hfx.hit.f and fg[0] or self.color)
|
||||||
|
graphics.pop()
|
||||||
|
end
|
||||||
|
|
||||||
|
function Gold:on_trigger_enter(other, contact)
|
||||||
|
if other:is(Player) then
|
||||||
|
main.current.gold_picked_up = main.current.gold_picked_up + 1
|
||||||
|
self.dead = true
|
||||||
|
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 4, color = fg[0], duration = 0.1}
|
||||||
|
for i = 1, 2 do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = self.color} end
|
||||||
|
_G[random:table{'gold2', 'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.9, 1.1), volume = 0.3}
|
||||||
|
|
||||||
|
local units = other:get_all_units()
|
||||||
|
local th
|
||||||
|
for _, unit in ipairs(units) do
|
||||||
|
if unit.character == 'treasure_hunter' then
|
||||||
|
th = unit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if th then
|
||||||
|
if th.level == 3 then
|
||||||
|
trigger:after(0.01, function()
|
||||||
|
_G[random:table{'scout1', 'scout2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||||
|
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6}
|
||||||
|
local r = random:float(0, 2*math.pi)
|
||||||
|
for i = 1, 8 do
|
||||||
|
local t = {group = main.current.main, x = self.x + 8*math.cos(r), y = self.y + 8*math.sin(r), v = 250, r = r, color = yellow2[0], dmg = th.dmg, character = th.character, parent = th, level = th.level}
|
||||||
|
Projectile(table.merge(t, mods or {}))
|
||||||
|
r = r + math.pi/4
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
trigger:after(0.01, function()
|
||||||
|
_G[random:table{'scout1', 'scout2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||||
|
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6}
|
||||||
|
local r = random:float(0, 2*math.pi)
|
||||||
|
for i = 1, 4 do
|
||||||
|
local t = {group = main.current.main, x = self.x + 8*math.cos(r), y = self.y + 8*math.sin(r), v = 250, r = r, color = yellow2[0], dmg = th.dmg, character = th.character, parent = th, level = th.level}
|
||||||
|
Projectile(table.merge(t, mods or {}))
|
||||||
|
r = r + 2*math.pi/4
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Critter = Object:extend()
|
Critter = Object:extend()
|
||||||
|
|
|
@ -13,6 +13,7 @@ function shared_init()
|
||||||
red = ColorRamp(Color'#e91d39', 0.025),
|
red = ColorRamp(Color'#e91d39', 0.025),
|
||||||
purple = ColorRamp(Color'#8e559e', 0.025),
|
purple = ColorRamp(Color'#8e559e', 0.025),
|
||||||
blue2 = ColorRamp(Color'#4778ba', 0.025),
|
blue2 = ColorRamp(Color'#4778ba', 0.025),
|
||||||
|
yellow2 = ColorRamp(Color'#f59f10', 0.025),
|
||||||
}
|
}
|
||||||
for name, color in pairs(colors) do
|
for name, color in pairs(colors) do
|
||||||
_G[name] = color
|
_G[name] = color
|
||||||
|
@ -494,6 +495,7 @@ global_text_tags = {
|
||||||
red = TextTag{draw = function(c, i, text) graphics.set_color(red[0]) end},
|
red = TextTag{draw = function(c, i, text) graphics.set_color(red[0]) end},
|
||||||
orange = TextTag{draw = function(c, i, text) graphics.set_color(orange[0]) end},
|
orange = TextTag{draw = function(c, i, text) graphics.set_color(orange[0]) end},
|
||||||
yellow = TextTag{draw = function(c, i, text) graphics.set_color(yellow[0]) end},
|
yellow = TextTag{draw = function(c, i, text) graphics.set_color(yellow[0]) end},
|
||||||
|
yellow2 = TextTag{draw = function(c, i, text) graphics.set_color(yellow2[0]) end},
|
||||||
green = TextTag{draw = function(c, i, text) graphics.set_color(green[0]) end},
|
green = TextTag{draw = function(c, i, text) graphics.set_color(green[0]) end},
|
||||||
purple = TextTag{draw = function(c, i, text) graphics.set_color(purple[0]) end},
|
purple = TextTag{draw = function(c, i, text) graphics.set_color(purple[0]) end},
|
||||||
blue = TextTag{draw = function(c, i, text) graphics.set_color(blue[0]) end},
|
blue = TextTag{draw = function(c, i, text) graphics.set_color(blue[0]) end},
|
||||||
|
@ -501,6 +503,7 @@ global_text_tags = {
|
||||||
bg = TextTag{draw = function(c, i, text) graphics.set_color(bg[0]) end},
|
bg = TextTag{draw = function(c, i, text) graphics.set_color(bg[0]) end},
|
||||||
bg3 = TextTag{draw = function(c, i, text) graphics.set_color(bg[3]) end},
|
bg3 = TextTag{draw = function(c, i, text) graphics.set_color(bg[3]) end},
|
||||||
bg10 = TextTag{draw = function(c, i, text) graphics.set_color(bg[10]) end},
|
bg10 = TextTag{draw = function(c, i, text) graphics.set_color(bg[10]) end},
|
||||||
|
bgm2 = TextTag{draw = function(c, i, text) graphics.set_color(bg[-2]) end},
|
||||||
light_bg = TextTag{draw = function(c, i, text) graphics.set_color(bg[5]) end},
|
light_bg = TextTag{draw = function(c, i, text) graphics.set_color(bg[5]) end},
|
||||||
fg = TextTag{draw = function(c, i, text) graphics.set_color(fg[0]) end},
|
fg = TextTag{draw = function(c, i, text) graphics.set_color(fg[0]) end},
|
||||||
fgm5 = TextTag{draw = function(c, i, text) graphics.set_color(fg[-5]) end},
|
fgm5 = TextTag{draw = function(c, i, text) graphics.set_color(fg[-5]) end},
|
||||||
|
@ -511,6 +514,8 @@ global_text_tags = {
|
||||||
bluem5 = TextTag{draw = function(c, i, text) graphics.set_color(blue[-5]) end},
|
bluem5 = TextTag{draw = function(c, i, text) graphics.set_color(blue[-5]) end},
|
||||||
blue25 = TextTag{draw = function(c, i, text) graphics.set_color(blue2[5]) end},
|
blue25 = TextTag{draw = function(c, i, text) graphics.set_color(blue2[5]) end},
|
||||||
blue2m5 = TextTag{draw = function(c, i, text) graphics.set_color(blue2[-5]) end},
|
blue2m5 = TextTag{draw = function(c, i, text) graphics.set_color(blue2[-5]) end},
|
||||||
|
yellow25 = TextTag{draw = function(c, i, text) graphics.set_color(yellow2[5]) end},
|
||||||
|
yellow2m5 = TextTag{draw = function(c, i, text) graphics.set_color(yellow2[-5]) end},
|
||||||
redm5 = TextTag{draw = function(c, i, text) graphics.set_color(red[-5]) end},
|
redm5 = TextTag{draw = function(c, i, text) graphics.set_color(red[-5]) end},
|
||||||
orangem5 = TextTag{draw = function(c, i, text) graphics.set_color(orange[-5]) end},
|
orangem5 = TextTag{draw = function(c, i, text) graphics.set_color(orange[-5]) end},
|
||||||
purplem5 = TextTag{draw = function(c, i, text) graphics.set_color(purple[-5]) end},
|
purplem5 = TextTag{draw = function(c, i, text) graphics.set_color(purple[-5]) end},
|
||||||
|
|
96
todo
96
todo
|
@ -1,24 +1,24 @@
|
||||||
Shop Update
|
Shop Update
|
||||||
New units
|
New units
|
||||||
Assists (2/4) - +25/50% assist buff effectiveness
|
* Mercenaries (2/4) - +10/20% chance for enemies to drop gold on death
|
||||||
Ringmaster (tier 4 assist, nuker)
|
* Treasure Hunter (tier 1 mercenary) - picking up gold releases 4 homing projectiles that deal X damage, Lv.3 - release 8 homing projectiles instead and they pierce twice
|
||||||
Absorber (tier 2 assist, warrior)
|
* Merchant (tier 2 mercenary) - gain +1 interest for every 10 gold, Lv.3 - your first item reroll is always free
|
||||||
Pardoner (tier 3 assist, mercenary)
|
* Usurer (tier 3 curser, mercenary, voider) - curses 3 nearby enemies indefinitely with debt, dealing X damage over time, Lv.3 - if the same enemy is cursed 3 times it takes 50X damage
|
||||||
Oracle (tier 1 assist)
|
* Gambler (tier 3 mercenary, sorcerer) - deal 2X damage to a single random enemy where X is how much gold you have, Lv.3 effect - 60%/40%/20% chance to cast the attack 2/3/4 times
|
||||||
Seraph (tier 2 assist, healer)
|
* Thief (tier 4 mercenary, rogue) - throws a knife that deals 2X damage and chains 5 times, Lv.3 - if the knife crits it deals 10X damage, chains 10 times and grants 1 gold
|
||||||
Mercenaries (3/3) - enemies occasionally drop pieces of gold
|
|
||||||
Treasure Hunter (tier 1 mercenary)
|
|
||||||
Merchant (tier 2 mercenary)
|
|
||||||
Pardoner (tier 3 assist, mercenary)
|
|
||||||
Gambler (tier 4 mercenary, rogue)
|
|
||||||
|
|
||||||
Shop changes
|
Shop changes
|
||||||
Owned units highlighted in shop
|
Owned units highlighted in shop
|
||||||
Fix highlight colors and highlight reserve
|
Fix highlight colors and highlight reserve
|
||||||
Shop level up
|
Shop level up
|
||||||
Remove level 3 units from rotation
|
|
||||||
|
|
||||||
Item changes
|
Item changes
|
||||||
|
Sorcerer items
|
||||||
|
Mercenary items
|
||||||
|
|
||||||
|
Unit changes
|
||||||
|
Launcher - remove
|
||||||
|
Beastmaster
|
||||||
|
|
||||||
QoL
|
QoL
|
||||||
* Added sorcerer achievement
|
* Added sorcerer achievement
|
||||||
|
@ -28,7 +28,7 @@ Shop Update
|
||||||
* Added mouse follow control mode
|
* Added mouse follow control mode
|
||||||
* The cursor is now invisible during waves, unless mouse follow mode is enabled
|
* The cursor is now invisible during waves, unless mouse follow mode is enabled
|
||||||
Options menu from buy screen
|
Options menu from buy screen
|
||||||
Add visuals for defensive ouroboros, divine intervention, fairy buff
|
Add visuals for tank attack
|
||||||
|
|
||||||
Balance
|
Balance
|
||||||
* Decreased level 25 boss movement speed
|
* Decreased level 25 boss movement speed
|
||||||
|
@ -38,34 +38,43 @@ Shop Update
|
||||||
* Fixed a bug where enemy critters would sometimes be unkillable
|
* Fixed a bug where enemy critters would sometimes be unkillable
|
||||||
* Fixed a rare crash involving broken enemy critter state
|
* Fixed a rare crash involving broken enemy critter state
|
||||||
* Fixed text for the illusionist's Lv.3 effect going outside the screen
|
* Fixed text for the illusionist's Lv.3 effect going outside the screen
|
||||||
* Fixed a rare crash when hovering over your owned in the shop
|
* Fixed a crash when hovering over the Lich in the shop due to playing with a save before the sorcerer update
|
||||||
* Fixed a crash when warden's force field would spawn on top of enemies
|
* Fixed a crash when warden's force field would spawn on top of enemies
|
||||||
|
* Fixed a crash when a volcano would spawn on top of enemies
|
||||||
* Fixed a crash when a pet would spawn on top of enemies
|
* Fixed a crash when a pet would spawn on top of enemies
|
||||||
* Fixed a bug where the maximum number of units would be wrong on certain conditions
|
* Fixed a bug where the maximum number of units would be wrong on certain conditions
|
||||||
|
* Fixed a crash when clicking too fast after unpausing the game
|
||||||
Fix bug where quitting on level 2 arena goes back to level 1 shop
|
Fix bug where quitting on level 2 arena goes back to level 1 shop
|
||||||
Fix fullscreen with different resolutions that don't scale properly
|
Fix fullscreen with different resolutions that don't scale properly
|
||||||
Fix enemies still spawning after arena clear (this happens with the extra enemy spawns that were blocked earlier)
|
Fix enemies still spawning after arena clear (this happens with the extra enemy spawns that were blocked earlier)
|
||||||
|
https://i.imgur.com/ieVqYNI.png
|
||||||
|
https://i.imgur.com/3JCeFuZ.png
|
||||||
|
https://i.imgur.com/cvC1TBz.png
|
||||||
|
|
||||||
Sacrifice Update
|
Sacrifice Update
|
||||||
New mechanics
|
New mechanics
|
||||||
Sacrifice units to level items up
|
Sacrifice units to level items up
|
||||||
New items
|
New items
|
||||||
|
https://steamcommunity.com/app/915310/discussions/0/3106901028662504698/
|
||||||
Reworked items
|
Reworked items
|
||||||
Items shouldn't just be more powerful versions of other items
|
Items shouldn't just be more powerful versions of other items
|
||||||
Items should have drawbacks
|
Items should have drawbacks
|
||||||
Items that apply to a position on the snake (a good middle step between applying them to individual units like in Underlords)
|
Items that apply to a position on the snake (a good middle step between applying them to individual units like in Underlords)
|
||||||
New units
|
|
||||||
Nocturnals/Darks/??? (3/6)
|
|
||||||
Shadowmancer
|
|
||||||
Necromancer
|
|
||||||
Demonologist
|
|
||||||
Demon
|
|
||||||
Lich
|
|
||||||
Lifestealer
|
|
||||||
Zombie
|
|
||||||
QoL
|
QoL
|
||||||
Current items visible on item selection screen
|
Current items visible on item selection screen
|
||||||
Endless mode
|
Endless mode
|
||||||
|
Volume slider
|
||||||
|
Add visuals for defensive ouroboros, divine intervention, fairy buff
|
||||||
|
|
||||||
|
Melee Update
|
||||||
|
New Units
|
||||||
|
Guardians - https://i.imgur.com/Ynu5Cdw.png
|
||||||
|
Assists (2/4) -
|
||||||
|
Ringmaster (tier 4 assist, nuker) - +15% to all stats to adjacent units, Lv.3 effect - create a cross that deals AoE damage 5 times for 10 seconds
|
||||||
|
Absorber (tier 2 assist, warrior) - absorbs 50% damage from adjacent units, Lv.3 effect - absorbs 75% damage from adjacent units and gives the absorber +25% defense
|
||||||
|
Pardoner (tier 3 assist, mercenary) -
|
||||||
|
Oracle (tier 1 assist) - +10% dodge chance to adjacent units, Lv.3 effect - +20% dodge chance to adjacent units
|
||||||
|
Seraph (tier 2 assist, healer) - periodically chooses 1 random unit and gives it +100% defense for 6 seconds, Lv.3 - choose 2 units instead
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -83,25 +92,36 @@ Hexblaster? - curser that consumes curses to deal damage
|
||||||
Bench? - https://i.imgur.com/B1gNVKk.png
|
Bench? - https://i.imgur.com/B1gNVKk.png
|
||||||
Balance option for when there are more sets - https://i.imgur.com/JMynwbL.png
|
Balance option for when there are more sets - https://i.imgur.com/JMynwbL.png
|
||||||
Negative effect: colliding with yourself kills one of your units
|
Negative effect: colliding with yourself kills one of your units
|
||||||
Go through this later https://i.imgur.com/4t7NA32.png <- lots of good improvements
|
https://i.imgur.com/bxfvA7g.png
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
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
|
||||||
Elite
|
Elite
|
||||||
Boss
|
Boss
|
||||||
Map (map of bigger size than arena with fixed spawns)
|
Map (map of bigger size than arena with fixed spawns)
|
||||||
Unit shop
|
Unit shop
|
||||||
Item shop
|
Item shop
|
||||||
Text + reward
|
Text + reward
|
||||||
Training grounds (upgrade unit)
|
Training grounds (upgrade unit)
|
||||||
Tavern (heal units)
|
Tavern (heal units)
|
||||||
|
Units die permanently when they die (dead units can be stored in bench to be revived later)
|
||||||
|
Units can have items attached to them like in Underlords
|
||||||
|
Unit item ideas:
|
||||||
|
This unit's projectiles pierce/chain/fork/seek/split/stun/etc
|
||||||
|
This unit is a [class]
|
||||||
|
New stat system:
|
||||||
|
All stats are values from 1 to 10 (can be lower than 1 or higher than due to debuffs/buffs only) 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
|
||||||
|
In general it's better if units don't have hidden internal multipliers on these stats, although sometimes that may be inevitable
|
||||||
|
Damage:
|
||||||
|
Crash - damage dealt when bumping into enemies
|
||||||
|
Projectile - damage dealt by projectiles
|
||||||
|
AoE - damage dealt in an area
|
||||||
|
DoT - damage dealt over time
|
||||||
|
|
||||||
Units die permanently when they die (dead units can be stored in bench to be revived later)
|
|
||||||
Units can have items attached to them like in Underlords
|
|
||||||
Unit item ideas:
|
|
||||||
This unit's projectiles pierce/chain/fork/seek/split/stun/etc
|
|
||||||
|
|
Loading…
Reference in New Issue