Loop update 3/5
16
arena.lua
|
@ -330,10 +330,6 @@ function Arena:on_enter(from, level, loop, units, passives, shop_level, shop_xp,
|
|||
self.t:after(1.125 + math.floor(n/4)*0.25, function() self.spawning_enemies = false end, 'spawning_enemies')
|
||||
self.enemy_spawns_prevented = 0
|
||||
end)
|
||||
|
||||
self.level = 25*(self.loop+1)
|
||||
self.won = true
|
||||
self:quit()
|
||||
end
|
||||
|
||||
|
||||
|
@ -392,7 +388,9 @@ function Arena:update(dt)
|
|||
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'hextouch', 'whispers_of_doom',
|
||||
'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',
|
||||
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosense', 'rearm', 'taunt', 'summon_instability',
|
||||
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosense', 'rearm', 'taunt', 'construct_instability',
|
||||
'intimidation', 'vulnerability', 'temporal_chains', 'ceremonial_dagger', 'homing_barrage', 'critical_strike', 'noxious_strike', 'infesting_strike', 'burning_strike', 'lucky_strike', 'healing_strike', 'stunning_strike',
|
||||
'silencing_strike', 'culling_strike', 'lightning_strike', 'psycholeak', 'divine_blessing',
|
||||
}
|
||||
max_units = math.clamp(7 + current_new_game_plus + self.loop, 7, 12)
|
||||
main:add(BuyScreen'buy_screen')
|
||||
|
@ -838,7 +836,9 @@ function Arena:die()
|
|||
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'hextouch', 'whispers_of_doom',
|
||||
'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',
|
||||
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosense', 'rearm', 'taunt', 'summon_instability',
|
||||
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosense', 'rearm', 'taunt', 'construct_instability',
|
||||
'intimidation', 'vulnerability', 'temporal_chains', 'ceremonial_dagger', 'homing_barrage', 'critical_strike', 'noxious_strike', 'infesting_strike', 'burning_strike', 'lucky_strike', 'healing_strike', 'stunning_strike',
|
||||
'silencing_strike', 'culling_strike', 'lightning_strike', 'psycholeak', 'divine_blessing',
|
||||
}
|
||||
max_units = math.clamp(7 + current_new_game_plus + self.loop, 7, 12)
|
||||
main:add(BuyScreen'buy_screen')
|
||||
|
@ -908,6 +908,8 @@ function Arena:create_credits()
|
|||
open_url(b, 'https://freesound.org/people/benzix2/sounds/467951/') end}
|
||||
Button{group = self.credits, x = 204, y = 160, button_text = 'lord', fg_color = 'yellowm5', bg_color = 'yellow', credits_button = true, action = function(b)
|
||||
open_url(b, 'https://store.steampowered.com/developer/T_TGames') end}
|
||||
Button{group = self.credits, x = 254, y = 160, button_text = 'InspectorJ', fg_color = 'yellowm5', bg_color = 'yellow', credits_button = true, action = function(b)
|
||||
open_url(b, 'https://freesound.org/people/InspectorJ/sounds/458586/') end}
|
||||
Text2{group = self.credits, x = 70, y = 190, lines = {{text = '[red]playtesters: ', font = pixul_font}}}
|
||||
Button{group = self.credits, x = 130, y = 190, button_text = 'Jofer', fg_color = 'redm5', bg_color = 'red', credits_button = true, action = function(b)
|
||||
open_url(b, 'https://twitter.com/JofersGames') end}
|
||||
|
@ -1108,7 +1110,7 @@ function Arena:spawn_n_enemies(p, j, n, pass)
|
|||
spawn1:play{pitch = random:float(0.8, 1.2), volume = 0.15}
|
||||
if not pass then
|
||||
check_circle:move_to(x, y)
|
||||
local objects = self.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Player, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
local objects = self.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Player, Sentry, Automaton, Bomb, Volcano, Saboteur, Pet, Turret})
|
||||
if #objects > 0 then self.enemy_spawns_prevented = self.enemy_spawns_prevented + 1; return end
|
||||
end
|
||||
|
||||
|
|
After Width: | Height: | Size: 529 B |
After Width: | Height: | Size: 374 B |
Before Width: | Height: | Size: 376 B After Width: | Height: | Size: 376 B |
After Width: | Height: | Size: 472 B |
After Width: | Height: | Size: 341 B |
After Width: | Height: | Size: 460 B |
After Width: | Height: | Size: 354 B |
After Width: | Height: | Size: 511 B |
After Width: | Height: | Size: 517 B |
After Width: | Height: | Size: 409 B |
After Width: | Height: | Size: 518 B |
After Width: | Height: | Size: 497 B |
After Width: | Height: | Size: 429 B |
After Width: | Height: | Size: 394 B |
After Width: | Height: | Size: 478 B |
After Width: | Height: | Size: 463 B |
After Width: | Height: | Size: 497 B |
|
@ -144,7 +144,9 @@ function BuyScreen:on_enter(from, level, loop, units, passives, shop_level, shop
|
|||
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'hextouch', 'whispers_of_doom',
|
||||
'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',
|
||||
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosense', 'rearm', 'taunt', 'summon_instability',
|
||||
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosense', 'rearm', 'taunt', 'construct_instability',
|
||||
'intimidation', 'vulnerability', 'temporal_chains', 'ceremonial_dagger', 'homing_barrage', 'critical_strike', 'noxious_strike', 'infesting_strike', 'burning_strike', 'lucky_strike', 'healing_strike', 'stunning_strike',
|
||||
'silencing_strike', 'culling_strike', 'lightning_strike', 'psycholeak', 'divine_blessing',
|
||||
}
|
||||
max_units = math.clamp(7 + current_new_game_plus + self.loop, 7, 12)
|
||||
main:add(BuyScreen'buy_screen')
|
||||
|
@ -547,7 +549,9 @@ function RestartButton:update(dt)
|
|||
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'hextouch', 'whispers_of_doom',
|
||||
'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',
|
||||
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosense', 'rearm', 'taunt', 'summon_instability',
|
||||
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosense', 'rearm', 'taunt', 'construct_instability',
|
||||
'intimidation', 'vulnerability', 'temporal_chains', 'ceremonial_dagger', 'homing_barrage', 'critical_strike', 'noxious_strike', 'infesting_strike', 'burning_strike', 'lucky_strike', 'healing_strike', 'stunning_strike',
|
||||
'silencing_strike', 'culling_strike', 'lightning_strike', 'psycholeak', 'divine_blessing',
|
||||
}
|
||||
system.save_state()
|
||||
main:add(BuyScreen'buy_screen')
|
||||
|
|
140
enemies.lua
|
@ -214,6 +214,7 @@ function Seeker:init(args)
|
|||
self.hp = self.max_hp
|
||||
local n = math.remap(current_new_game_plus, 0, 5, 1, 0.75)
|
||||
self.t:every({3*n, 5*n}, function()
|
||||
if self.silenced or self.barbarian_stunned then return end
|
||||
local enemy = self:get_closest_object_in_shape(Circle(self.x, self.y, 64), main.current.enemies)
|
||||
if enemy then
|
||||
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
|
@ -247,17 +248,17 @@ function Seeker:init(args)
|
|||
|
||||
local player = main.current.player
|
||||
if player and player.intimidation and not self.boss and not self.tank then
|
||||
self.buff_hp_m = 0.8
|
||||
self.buff_hp_m = (player.intimidation == 1 and 0.9) or (player.intimidation == 2 and 0.8) or (player.intimidation == 3 and 0.7)
|
||||
self:calculate_stats()
|
||||
self.hp = self.max_hp
|
||||
end
|
||||
|
||||
if player and player.vulnerability then
|
||||
self.vulnerable = true
|
||||
self.vulnerable = (player.vulnerability == 1 and 1.1) or (player.vulnerability == 2 and 1.2) or (player.vulnerability == 3 and 1.3)
|
||||
end
|
||||
|
||||
if player and player.temporal_chains then
|
||||
self.temporal_chains_mvspd_m = 0.8
|
||||
self.temporal_chains_mvspd_m = (player.temporal_chains and 0.9) or (player.temporal_chains and 0.8) or (player.temporal_chains and 0.7)
|
||||
end
|
||||
|
||||
self.usurer_count = 0
|
||||
|
@ -348,9 +349,9 @@ end
|
|||
function Seeker:draw()
|
||||
graphics.push(self.x, self.y, self.r, self.hfx.hit.x, self.hfx.hit.x)
|
||||
if self.boss then
|
||||
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 4, 4, self.hfx.hit.f and fg[0] or self.color)
|
||||
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 4, 4, self.hfx.hit.f and fg[0] or (self.silenced and bg[10]) or self.color)
|
||||
else
|
||||
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 3, 3, self.hfx.hit.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 and fg[0] or (self.silenced and bg[10]) or self.color)
|
||||
end
|
||||
graphics.pop()
|
||||
|
||||
|
@ -384,7 +385,7 @@ function Seeker:on_collision_enter(other, contact)
|
|||
|
||||
if main.current.player.heavy_impact then
|
||||
if self.being_pushed then
|
||||
self:hit(self.push_force)
|
||||
self:hit(self.push_force, nil, nil, true)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -413,8 +414,8 @@ function Seeker:on_collision_enter(other, contact)
|
|||
|
||||
elseif table.any(main.current.enemies, function(v) return other:is(v) end) then
|
||||
if self.being_pushed and math.length(self:get_velocity()) > 60 then
|
||||
other:hit(math.floor(self.push_force/4))
|
||||
self:hit(math.floor(self.push_force/2))
|
||||
other:hit(math.floor(self.push_force/4), nil, nil, true)
|
||||
self:hit(math.floor(self.push_force/2), nil, nil, true)
|
||||
other:push(math.floor(self.push_force/2), other:angle_to_object(self))
|
||||
HitCircle{group = main.current.effects, x = x, y = y, rs = 6, color = fg[0], duration = 0.1}
|
||||
for i = 1, 2 do HitParticle{group = main.current.effects, x = x, y = y, color = self.color} end
|
||||
|
@ -431,13 +432,13 @@ function Seeker:on_collision_enter(other, contact)
|
|||
elseif other:is(Turret) then
|
||||
self.headbutting = false
|
||||
_G[random:table{'player_hit1', 'player_hit2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
self:hit(0)
|
||||
self:hit(0, nil, nil, true)
|
||||
self:push(random:float(2.5, 7), other:angle_to_object(self))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Seeker:hit(damage, projectile, dot)
|
||||
function Seeker:hit(damage, projectile, dot, from_enemy)
|
||||
local pyrod = self.pyrod
|
||||
self.pyrod = false
|
||||
if self.dead then return end
|
||||
|
@ -445,12 +446,65 @@ function Seeker:hit(damage, projectile, dot)
|
|||
if self.push_invulnerable then return end
|
||||
self:show_hp()
|
||||
|
||||
local actual_damage = math.max(self:calculate_damage(damage)*(self.stun_dmg_m or 1), 0)
|
||||
if self.vulnerable then actual_damage = actual_damage*1.2 end
|
||||
local crit = 1
|
||||
if main.current.player.critical_strike and not dot and not from_enemy then
|
||||
if random:bool((main.current.player.critical_strike == 1 and 5) or (main.current.player.critical_strike == 2 and 10) or (main.current.player.critical_strike == 3 and 15)) then
|
||||
crit = 2
|
||||
camera:shake(2.5, 0.25)
|
||||
rogue_crit1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
rogue_crit2:play{pitch = random:float(0.95, 1.05), volume = 0.15}
|
||||
for i = 1, 2 do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = self.color, v = random:float(100, 400)} end
|
||||
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 12, color = fg[0], duration = 0.3}:scale_down():change_color(0.5, self.color)
|
||||
end
|
||||
end
|
||||
|
||||
if main.current.player.kinetic_strike and not dot and not from_enemy then
|
||||
if random:bool((main.current.player.kinetic_strike == 1 and 10) or (main.current.player.kinetic_strike == 2 and 20) or (main.current.player.kinetic_strike == 3 and 30)) then
|
||||
local units = main.current.player:get_all_units()
|
||||
local cx, cy = 0, 0
|
||||
for _, unit in ipairs(units) do
|
||||
cx = cx + unit.x
|
||||
cy = cy + unit.y
|
||||
end
|
||||
cx = cx/#units
|
||||
cy = cy/#units
|
||||
self:push(random:float(30, 60), projectile and projectile.r or self:angle_from_point(cx, cy))
|
||||
end
|
||||
end
|
||||
|
||||
if main.current.player.stunning_strike and not dot and not from_enemy then
|
||||
if random:bool((main.current.player.stunning_strike == 1 and 8) or (main.current.player.stunning_strike == 2 and 16) or (main.current.player.stunning_strike == 3 and 24)) then
|
||||
self:slow(0.1, 2)
|
||||
self.barbarian_stunned = true
|
||||
self.t:after(2, function() self.barbarian_stunned = false end)
|
||||
end
|
||||
end
|
||||
|
||||
if main.current.player.silencing_strike and not dot and not from_enemy then
|
||||
if random:bool((main.current.player.silencing_strike == 1 and 8) or (main.current.player.silencing_strike == 2 and 16) or (main.current.player.silencing_strike == 3 and 24)) then
|
||||
self.silenced = true
|
||||
self.t:after(4, function() self.silenced = false end)
|
||||
end
|
||||
end
|
||||
|
||||
local actual_damage = math.max(self:calculate_damage(damage)*(self.stun_dmg_m or 1)*crit, 0)
|
||||
if self.vulnerable then actual_damage = actual_damage*self.vulnerable end
|
||||
self.hp = self.hp - actual_damage
|
||||
if self.hp > self.max_hp then self.hp = self.max_hp end
|
||||
main.current.damage_dealt = main.current.damage_dealt + actual_damage
|
||||
|
||||
if main.current.player.noxious_strike and not dot and not from_enemy then
|
||||
if random:bool((main.current.player.noxious_strike == 1 and 8) or (main.current.player.noxious_strike == 2 and 16) or (main.current.player.noxious_strike == 3 and 24)) then
|
||||
self:apply_dot(0.6*actual_damage*(main.current.player.dot_dmg_m or 1)*(main.current.chronomancer_dot or 1), 3)
|
||||
end
|
||||
end
|
||||
|
||||
if main.current.player.burning_strike and not dot and not from_enemy then
|
||||
if random:bool(15) then
|
||||
self:apply_dot(0.6*actual_damage*(main.current.player.dot_dmg_m or 1)*(main.current.chronomancer_dot or 1), 3, red[0])
|
||||
end
|
||||
end
|
||||
|
||||
if dot then
|
||||
self.seeping_def_m = (main.current.player.seeping == 1 and 0.85) or (main.current.player.seeping == 2 and 0.75) or (main.current.player.seeping == 3 and 0.65) or 1
|
||||
self.t:after(1, function()
|
||||
|
@ -472,6 +526,12 @@ function Seeker:hit(damage, projectile, dot)
|
|||
end)
|
||||
end
|
||||
|
||||
if self.boss and main.current.player.culling_strike then
|
||||
if self.hp <= self.max_hp*((main.current.player.culling_strike == 1 and 0.1) or (main.current.player.culling_strike == 2 and 0.2) or (main.current.player.culling_strike == 3 and 0.3)) then
|
||||
self.hp = 0
|
||||
end
|
||||
end
|
||||
|
||||
if self.hp <= 0 then
|
||||
self.dead = true
|
||||
for i = 1, random:int(4, 6) do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = self.color} end
|
||||
|
@ -578,6 +638,54 @@ function Seeker:hit(damage, projectile, dot)
|
|||
dmg = self.bane_ref.area_dmg_m*self.bane_ref.dmg*(self.bane_ref.dot_dmg_m or 1), void_rift = true, duration = 1}
|
||||
end)
|
||||
end
|
||||
|
||||
if main.current.player.ceremonial_dagger and not from_enemy then
|
||||
trigger:after(0.01, function()
|
||||
if tostring(self.x) == tostring(0/0) or tostring(self.y) == tostring(0/0) then return end
|
||||
_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)
|
||||
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 = red[0], dmg = self.max_hp,
|
||||
homing = true, character = 'jester', parent = main.current.player}
|
||||
Projectile(table.merge(t, mods or {}))
|
||||
end)
|
||||
end
|
||||
|
||||
if main.current.player.homing_barrage and not from_enemy then
|
||||
trigger:after(0.01, function()
|
||||
if random:bool((main.current.player.homing_barrage == 1 and 8) or (main.current.player.homing_barrage == 2 and 16) or (main.current.player.homing_barrage == 3 and 24)) then
|
||||
local target = main.current.player:get_closest_object_in_shape(Circle(main.current.player.x, main.current.player.y, 128), main.current.enemies)
|
||||
main.current.player:barrage(target and main.current.player:angle_to_object(target) or main.current.player.r, 4, nil, nil, nil, true)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
if main.current.player.infesting_strike and not from_enemy then
|
||||
trigger:after(0.01, function()
|
||||
if random:bool((main.current.player.infesting_strike == 1 and 10) or (main.current.player.infesting_strike == 2 and 20) or (main.current.player.infesting_strike == 3 and 30)) then
|
||||
critter1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
for i = 1, 2 do
|
||||
Critter{group = main.current.main, x = self.x, y = self.y, color = orange[0], r = random:float(0, 2*math.pi), v = 5, dmg = main.current.player.dmg, parent = main.current.player}
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
if main.current.player.lucky_strike and not from_enemy then
|
||||
if random:bool(8) then
|
||||
trigger:after(0.01, function()
|
||||
Gold{group = main.current.main, x = self.x, y = self.y}
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
if main.current.player.healing_strike and not from_enemy then
|
||||
if random:bool(8) then
|
||||
trigger:after(0.01, function()
|
||||
HealingOrb{group = main.current.main, x = self.x, y = self.y}
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -668,13 +776,13 @@ function Seeker:curse(curse, duration, arg1, arg2, arg3)
|
|||
end
|
||||
|
||||
|
||||
function Seeker:apply_dot(dmg, duration)
|
||||
function Seeker:apply_dot(dmg, duration, color)
|
||||
self.t:every(0.25, function()
|
||||
hit2:play{pitch = random:float(0.8, 1.2), volume = 0.2}
|
||||
self:hit(dmg/4, nil, true)
|
||||
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = fg[0], duration = 0.1}
|
||||
for i = 1, 1 do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = self.color} end
|
||||
for i = 1, 1 do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = purple[0]} end
|
||||
for i = 1, 1 do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = color or purple[0]} end
|
||||
end, math.floor(duration/0.2))
|
||||
end
|
||||
|
||||
|
@ -833,7 +941,7 @@ end
|
|||
function EnemyCritter:on_trigger_enter(other, contact)
|
||||
if other:is(Player) then
|
||||
self:die(self.x, self.y, nil, random:int(2, 3))
|
||||
other:hit(self.dmg)
|
||||
other:hit(self.dmg, nil, nil, true)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -978,7 +1086,7 @@ function EnemyProjectile:on_trigger_enter(other, contact)
|
|||
elseif other:is(Seeker) or other:is(EnemyCritter) then
|
||||
if self.source == 'shooter' then
|
||||
self:die(self.x, self.y, nil, random:int(2, 3))
|
||||
other:hit(0.5*self.dmg)
|
||||
other:hit(0.5*self.dmg, nil, nil, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
192
main.lua
|
@ -21,6 +21,8 @@ function init()
|
|||
input:bind('enter', {'space', 'return', 'fleft', 'fdown', 'fright'})
|
||||
|
||||
local s = {tags = {sfx}}
|
||||
artificer1 = Sound('458586__inspectorj__ui-mechanical-notification-01-fx.ogg', s)
|
||||
explosion1 = Sound('Explosion Grenade_04.ogg', s)
|
||||
mine1 = Sound('Weapon Swap 2.ogg', s)
|
||||
level_up1 = Sound('Buff 4.ogg', s)
|
||||
unlock1 = Sound('Unlock 3.ogg', s)
|
||||
|
@ -213,7 +215,26 @@ function init()
|
|||
psychosense = Image('psychosense')
|
||||
rearm = Image('rearm')
|
||||
taunt = Image('taunt')
|
||||
summon_instability = Image('summon_instability')
|
||||
construct_instability = Image('construct_instability')
|
||||
intimidation = Image('intimidation')
|
||||
vulnerability = Image('vulnerability')
|
||||
temporal_chains = Image('temporal_chains')
|
||||
ceremonial_dagger = Image('ceremonial_dagger')
|
||||
homing_barrage = Image('homing_barrage')
|
||||
critical_strike = Image('critical_strike')
|
||||
noxious_strike = Image('noxious_strike')
|
||||
infesting_strike = Image('infesting_strike')
|
||||
kinetic_strike = Image('kinetic_strike')
|
||||
burning_strike = Image('burning_strike')
|
||||
lucky_strike = Image('lucky_strike')
|
||||
healing_strike = Image('healing_strike')
|
||||
stunning_strike = Image('stunning_strike')
|
||||
silencing_strike = Image('silencing_strike')
|
||||
warping_shots = Image('warping_shots')
|
||||
culling_strike = Image('culling_strike')
|
||||
lightning_strike = Image('lightning_strike')
|
||||
psycholeak = Image('psycholeak')
|
||||
divine_blessing = Image('divine_blessing')
|
||||
|
||||
class_colors = {
|
||||
['warrior'] = yellow[0],
|
||||
|
@ -265,12 +286,14 @@ function init()
|
|||
['blade'] = 'Blade',
|
||||
['elementor'] = 'Elementor',
|
||||
['saboteur'] = 'Saboteur',
|
||||
['bomber'] = 'Bomber',
|
||||
['stormweaver'] = 'Stormweaver',
|
||||
['sage'] = 'Sage',
|
||||
['squire'] = 'Squire',
|
||||
['cannoneer'] = 'Cannoneer',
|
||||
['dual_gunner'] = 'Dual Gunner',
|
||||
['hunter'] = 'Hunter',
|
||||
['sentry'] = 'Sentry',
|
||||
['chronomancer'] = 'Chronomancer',
|
||||
['spellblade'] = 'Spellblade',
|
||||
['psykeeper'] = 'Psykeeper',
|
||||
|
@ -298,6 +321,7 @@ function init()
|
|||
['flagellant'] = 'Flagellant',
|
||||
['arcanist'] = 'Arcanist',
|
||||
['illusionist'] = 'Illusionist',
|
||||
['artificer'] = 'Artificer',
|
||||
['witch'] = 'Witch',
|
||||
['silencer'] = 'Silencer',
|
||||
['vulcanist'] = 'Vulcanist',
|
||||
|
@ -322,12 +346,14 @@ function init()
|
|||
['blade'] = yellow[0],
|
||||
['elementor'] = blue[0],
|
||||
['saboteur'] = orange[0],
|
||||
['bomber'] = orange[0],
|
||||
['stormweaver'] = blue[0],
|
||||
['sage'] = purple[0],
|
||||
['squire'] = yellow[0],
|
||||
['cannoneer'] = orange[0],
|
||||
['dual_gunner'] = green[0],
|
||||
['hunter'] = green[0],
|
||||
['sentry'] = green[0],
|
||||
['chronomancer'] = blue[0],
|
||||
['spellblade'] = blue[0],
|
||||
['psykeeper'] = fg[0],
|
||||
|
@ -355,6 +381,7 @@ function init()
|
|||
['flagellant'] = fg[0],
|
||||
['arcanist'] = blue2[0],
|
||||
['illusionist'] = blue2[0],
|
||||
['artificer'] = blue2[0],
|
||||
['witch'] = purple[0],
|
||||
['silencer'] = blue2[0],
|
||||
['vulcanist'] = red[0],
|
||||
|
@ -379,12 +406,14 @@ function init()
|
|||
['blade'] = 'yellow',
|
||||
['elementor'] = 'blue',
|
||||
['saboteur'] = 'orange',
|
||||
['bomber'] = 'orange',
|
||||
['stormweaver'] = 'blue',
|
||||
['sage'] = 'purple',
|
||||
['squire'] = 'yellow',
|
||||
['cannoneer'] = 'orange',
|
||||
['dual_gunner'] = 'green',
|
||||
['hunter'] = 'green',
|
||||
['sentry'] = 'green',
|
||||
['chronomancer'] = 'blue',
|
||||
['spellblade'] = 'blue',
|
||||
['psykeeper'] = 'fg',
|
||||
|
@ -412,6 +441,7 @@ function init()
|
|||
['flagellant'] = 'fg',
|
||||
['arcanist'] = 'blue2',
|
||||
['illusionist'] = 'blue2',
|
||||
['artificer'] = 'blue2',
|
||||
['witch'] = 'purple',
|
||||
['silencer'] = 'blue2',
|
||||
['vulcanist'] = 'red',
|
||||
|
@ -435,13 +465,15 @@ function init()
|
|||
['outlaw'] = {'warrior', 'rogue'},
|
||||
['blade'] = {'warrior', 'nuker'},
|
||||
['elementor'] = {'mage', 'nuker'},
|
||||
['saboteur'] = {'rogue', 'conjurer', 'nuker'},
|
||||
-- ['saboteur'] = {'rogue', 'conjurer', 'nuker'},
|
||||
['bomber'] = {'nuker', 'conjurer'},
|
||||
['stormweaver'] = {'enchanter'},
|
||||
['sage'] = {'nuker', 'forcer'},
|
||||
['squire'] = {'warrior', 'enchanter'},
|
||||
['cannoneer'] = {'ranger', 'nuker'},
|
||||
['dual_gunner'] = {'ranger', 'rogue'},
|
||||
['hunter'] = {'ranger', 'conjurer', 'forcer'},
|
||||
-- ['hunter'] = {'ranger', 'conjurer', 'forcer'},
|
||||
['sentry'] = {'ranger', 'conjurer'},
|
||||
['chronomancer'] = {'mage', 'enchanter'},
|
||||
['spellblade'] = {'mage', 'rogue'},
|
||||
['psykeeper'] = {'healer', 'psyker'},
|
||||
|
@ -468,7 +500,8 @@ function init()
|
|||
['infestor'] = {'curser', 'swarmer'},
|
||||
['flagellant'] = {'psyker', 'enchanter'},
|
||||
['arcanist'] = {'sorcerer'},
|
||||
['illusionist'] = {'sorcerer', 'conjurer'},
|
||||
-- ['illusionist'] = {'sorcerer', 'conjurer'},
|
||||
['artificer'] = {'sorcerer', 'conjurer'},
|
||||
['witch'] = {'sorcerer', 'voider'},
|
||||
['silencer'] = {'sorcerer', 'curser'},
|
||||
['vulcanist'] = {'sorcerer', 'nuker'},
|
||||
|
@ -492,17 +525,19 @@ function init()
|
|||
['outlaw'] = '[yellow]Warrior, [red]Rogue',
|
||||
['blade'] = '[yellow]Warrior, [red]Nuker',
|
||||
['elementor'] = '[blue]Mage, [red]Nuker',
|
||||
['saboteur'] = '[red]Rogue, [orange]Conjurer, [red]Nuker',
|
||||
-- ['saboteur'] = '[red]Rogue, [orange]Conjurer, [red]Nuker',
|
||||
['bomber'] = '[red]Nuker, [orange]Builder',
|
||||
['stormweaver'] = '[blue]Enchanter',
|
||||
['sage'] = '[red]Nuker, [yellow]Forcer',
|
||||
['squire'] = '[yellow]Warrior, [blue]Enchanter',
|
||||
['cannoneer'] = '[green]Ranger, [red]Nuker',
|
||||
['dual_gunner'] = '[green]Ranger, [red]Rogue',
|
||||
['hunter'] = '[green]Ranger, [orange]Conjurer, [yellow]Forcer',
|
||||
-- ['hunter'] = '[green]Ranger, [orange]Conjurer, [yellow]Forcer',
|
||||
['sentry'] = '[green]Ranger, [orange]Builder',
|
||||
['chronomancer'] = '[blue]Mage, Enchanter',
|
||||
['spellblade'] = '[blue]Mage, [red]Rogue',
|
||||
['psykeeper'] = '[green]Healer, [fg]Psyker',
|
||||
['engineer'] = '[orange]Conjurer',
|
||||
['engineer'] = '[orange]Builder',
|
||||
['plague_doctor'] = '[red]Nuker, [purple]Voider',
|
||||
['barbarian'] = '[purple]Curser, [yellow]Warrior',
|
||||
['juggernaut'] = '[yellow]Forcer, Warrior',
|
||||
|
@ -515,7 +550,7 @@ function init()
|
|||
['jester'] = '[purple]Curser, [red]Rogue',
|
||||
['assassin'] = '[red]Rogue, [purple]Voider',
|
||||
['host'] = '[orange]Swarmer',
|
||||
['carver'] = '[orange]Conjurer, [green]Healer',
|
||||
['carver'] = '[orange]Builder, [green]Healer',
|
||||
['bane'] = '[purple]Curser, Voider',
|
||||
['psykino'] = '[blue]Mage, [fg]Psyker, [yellow]Forcer',
|
||||
['barrager'] = '[green]Ranger, [yellow]Forcer',
|
||||
|
@ -525,7 +560,8 @@ function init()
|
|||
['infestor'] = '[purple]Curser, [orange]Swarmer',
|
||||
['flagellant'] = '[fg]Psyker, [blue]Enchanter',
|
||||
['arcanist'] = '[blue2]Sorcerer',
|
||||
['illusionist'] = '[blue2]Sorcerer, [orange]Conjurer',
|
||||
-- ['illusionist'] = '[blue2]Sorcerer, [orange]Conjurer',
|
||||
['artificer'] = '[blue2]Sorcerer, [orange]Builder',
|
||||
['witch'] = '[blue2]Sorcerer, [purple]Voider',
|
||||
['silencer'] = '[blue2]Sorcerer, [purple]Curser',
|
||||
['vulcanist'] = '[blue2]Sorcerer, [red]Nuker',
|
||||
|
@ -566,12 +602,14 @@ function init()
|
|||
['blade'] = function(lvl) return '[fg]throws multiple blades that deal [yellow]' .. get_character_stat('blade', lvl, 'dmg') .. ' AoE[fg] damage' end,
|
||||
['elementor'] = function(lvl) return '[fg]deals [yellow]' .. get_character_stat('elementor', lvl, 'dmg') .. ' AoE[fg] damage in a large area centered on a random target' end,
|
||||
['saboteur'] = function(lvl) return '[fg]calls [yellow]2[fg] saboteurs to seek targets and deal [yellow]' .. get_character_stat('saboteur', lvl, 'dmg') .. ' AoE[fg] damage' end,
|
||||
['bomber'] = function(lvl) return '[fg]plants a bomb, when it explodes it deals [yellow]' .. 2*get_character_stat('bomber', lvl, 'dmg') .. ' AoE[fg] damage' end,
|
||||
['stormweaver'] = function(lvl) return '[fg]infuses projectiles with chain lightning that deals [yellow]20%[fg] damage to [yellow]2[fg] enemies' end,
|
||||
['sage'] = function(lvl) return '[fg]shoots a slow projectile that draws enemies in' end,
|
||||
['squire'] = function(lvl) return '[yellow]+20%[fg] damage and defense to all allies' end,
|
||||
['cannoneer'] = function(lvl) return '[fg]shoots a projectile that deals [yellow]' .. 2*get_character_stat('cannoneer', lvl, 'dmg') .. ' AoE[fg] damage' end,
|
||||
['dual_gunner'] = function(lvl) return '[fg]shoots two parallel projectiles, each dealing [yellow]' .. get_character_stat('dual_gunner', lvl, 'dmg') .. '[fg] damage' end,
|
||||
['hunter'] = function(lvl) return '[fg]shoots an arrow that deals [yellow]' .. get_character_stat('hunter', lvl, 'dmg') .. '[fg] damage and has a [yellow]20%[fg] chance to summon a pet' end,
|
||||
['sentry'] = function(lvl) return '[fg]spawns a rotating turret that shoots [yellow]4[fg] projectiles, each dealing [yellow]' .. get_character_stat('sentry', lvl, 'dmg') .. '[fg] damage' end,
|
||||
['chronomancer'] = function(lvl) return '[yellow]+20%[fg] attack speed to all allies' end,
|
||||
['spellblade'] = function(lvl) return '[fg]throws knives that deal [yellow]' .. get_character_stat('spellblade', lvl, 'dmg') .. '[fg] damage, pierce and spiral outwards' end,
|
||||
['psykeeper'] = function(lvl) return '[fg]creates [yellow]1[fg] healing orb every time the psykeeper takes [yellow]20%[fg] of its max HP in damage' end,
|
||||
|
@ -589,7 +627,7 @@ function init()
|
|||
['assassin'] = function(lvl) return '[fg]throws a piercing knife that deals [yellow]' .. get_character_stat('assassin', lvl, 'dmg') .. '[fg] damage + [yellow]' ..
|
||||
get_character_stat('assassin', lvl, 'dmg')/2 .. '[fg] damage per second' end,
|
||||
['host'] = function(lvl) return '[fg]periodically spawn [yellow]1[fg] small critter' end,
|
||||
['carver'] = function(lvl) return '[fg]carves a statue that periodically heals [yellow]1[fg] unit for [yellow]20%[fg] max HP if in range' end,
|
||||
['carver'] = function(lvl) return '[fg]carves a statue that creates [yellow]1[fg] healing orb every [yellow]6[fg] seconds' end,
|
||||
['bane'] = function(lvl) return '[fg]curses [yellow]6[fg] nearby enemies for [yellow]6[fg] seconds, they will create small void rifts on death' end,
|
||||
['psykino'] = function(lvl) return '[fg]pulls enemies together for [yellow]2[fg] seconds' end,
|
||||
['barrager'] = function(lvl) return '[fg]shoots a barrage of [yellow]3[fg] arrows, each dealing [yellow]' .. get_character_stat('barrager', lvl, 'dmg') .. '[fg] damage and pushing enemies' end,
|
||||
|
@ -600,6 +638,7 @@ function init()
|
|||
['flagellant'] = function(lvl) return '[fg]deals [yellow]' .. 2*get_character_stat('flagellant', lvl, 'dmg') .. '[fg] damage to self and grants [yellow]+4%[fg] damage to all allies per cast' end,
|
||||
['arcanist'] = function(lvl) return '[fg]launches a slow moving orb that launches projectiles, each dealing [yellow]' .. get_character_stat('arcanist', lvl, 'dmg') .. '[fg] damage' end,
|
||||
['illusionist'] = function(lvl) return '[fg]launches a projectile that deals [yellow]' .. get_character_stat('illusionist', lvl, 'dmg') .. '[fg] damage and creates copies that do the same' end,
|
||||
['artificer'] = function(lvl) return '[fg]spawns an automaton that shoots a projectile that deals [yellow]' .. get_character_stat('artificer', lvl, 'dmg') .. '[fg] damage' end,
|
||||
['witch'] = function(lvl) return '[fg]creates an area that ricochets and deals [yellow]' .. get_character_stat('witch', lvl, 'dmg') .. '[fg] damage per second' end,
|
||||
['silencer'] = function(lvl) return '[fg]curses [yellow]5[fg] nearby enemies for [yellow]6[fg] seconds, preventing them from using special attacks' 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,
|
||||
|
@ -619,17 +658,19 @@ function init()
|
|||
['magician'] = '[blue]Ethereal Form',
|
||||
['archer'] = '[green]Bounce Shot',
|
||||
['scout'] = '[red]Dagger Resonance',
|
||||
['cleric'] = '[green]Mass Heal ',
|
||||
['cleric'] = '[green]Mass Heal',
|
||||
['outlaw'] = '[red]Flying Daggers',
|
||||
['blade'] = '[yellow]Blade Resonance',
|
||||
['elementor'] = '[blue]Windfield',
|
||||
['saboteur'] = '[orange]Demoman',
|
||||
['bomber'] = '[orange]Demoman',
|
||||
['stormweaver'] = '[blue]Wide Lightning',
|
||||
['sage'] = '[purple]Dimension Compression',
|
||||
['squire'] = '[yellow]Shiny Gear',
|
||||
['cannoneer'] = '[orange]Cannon Barrage',
|
||||
['dual_gunner'] = '[green]Gun Kata',
|
||||
['hunter'] = '[green]Feral Pack',
|
||||
['sentry'] = '[green]Sentry Barrage',
|
||||
['chronomancer'] = '[blue]Quicken',
|
||||
['spellblade'] = '[blue]Spiralism',
|
||||
['psykeeper'] = '[fg]Crucio',
|
||||
|
@ -657,6 +698,7 @@ function init()
|
|||
['flagellant'] = '[red]Zealotry',
|
||||
['arcanist'] = '[blue2]Arcane Orb',
|
||||
['illusionist'] = '[blue2]Mirror Image',
|
||||
['artificer'] = '[blue2]Spell Formula Efficiency',
|
||||
['witch'] = '[purple]Death Pool',
|
||||
['silencer'] = '[blue2]Arcane Curse',
|
||||
['vulcanist'] = '[red]Lava Burst',
|
||||
|
@ -681,12 +723,14 @@ function init()
|
|||
['blade'] = '[light_bg]Blade Resonance',
|
||||
['elementor'] = '[light_bg]Windfield',
|
||||
['saboteur'] = '[light_bg]Demoman',
|
||||
['bomber'] = '[light_bg]Demoman',
|
||||
['stormweaver'] = '[light_bg]Wide Lightning',
|
||||
['sage'] = '[light_bg]Dimension Compression',
|
||||
['squire'] = '[light_bg]Shiny Gear',
|
||||
['cannoneer'] = '[light_bg]Cannon Barrage',
|
||||
['dual_gunner'] = '[light_bg]Gun Kata',
|
||||
['hunter'] = '[light_bg]Feral Pack',
|
||||
['sentry'] = '[light_bg]Sentry Barrage',
|
||||
['chronomancer'] = '[light_bg]Quicken',
|
||||
['spellblade'] = '[light_bg]Spiralism',
|
||||
['psykeeper'] = '[light_bg]Crucio',
|
||||
|
@ -714,6 +758,7 @@ function init()
|
|||
['flagellant'] = '[light_bg]Zealotry',
|
||||
['arcanist'] = '[light_bg]Arcane Orb',
|
||||
['illusionist'] = '[light_bg]Mirror Image',
|
||||
['artificer'] = '[light_bg]Spell Formula Efficiency',
|
||||
['witch'] = '[light_bg]Death Pool',
|
||||
['silencer'] = '[light_bg]Arcane Curse',
|
||||
['vulcanist'] = '[light_bg]Lava Burst',
|
||||
|
@ -738,12 +783,14 @@ function init()
|
|||
['blade'] = function() return '[fg]deal additional [yellow]' .. math.round(get_character_stat('blade', 3, 'dmg')/3, 2) .. '[fg] damage per enemy hit' end,
|
||||
['elementor'] = function() return '[fg]slows enemies by [yellow]60%[fg] for [yellow]6[fg] seconds on hit' end,
|
||||
['saboteur'] = function() return '[fg]the explosion has [yellow]50%[fg] chance to crit, increasing in size and dealing [yellow]2x[fg] damage' end,
|
||||
['bomber'] = function() return '[yellow]+100%[fg] bomb area and damage' end,
|
||||
['stormweaver'] = function() return "[fg]chain lightning's trigger area of effect and number of units hit is [yellow]doubled" end,
|
||||
['sage'] = function() return '[fg]when the projectile expires deal [yellow]' .. 3*get_character_stat('sage', 3, 'dmg') .. '[fg] damage to all enemies under its influence' end,
|
||||
['squire'] = function() return '[yellow]+30%[fg] damage, attack speed, movement speed and defense to all allies' 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,
|
||||
['hunter'] = function() return '[fg]summons [yellow]3[fg] pets and the pets ricochet off walls once' end,
|
||||
['sentry'] = function() return '[yellow]+50%[fg] sentry attack speed and the projectiles ricochet [yellow]twice[fg]' 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,
|
||||
['psykeeper'] = function() return '[fg]deal [yellow]double[fg] the damage taken by the psykeeper to all enemies' end,
|
||||
|
@ -760,7 +807,7 @@ function init()
|
|||
['jester'] = function() return '[fg]all knives seek enemies and pierce [yellow]2[fg] times' end,
|
||||
['assassin'] = function() return '[fg]poison inflicted from crits deals [yellow]8x[fg] damage' end,
|
||||
['host'] = function() return '[fg][yellow]+100%[fg] critter spawn rate and spawn [yellow]2[fg] critters instead' end,
|
||||
['carver'] = function() return '[fg]carves a tree that heals [yellow]twice[fg] as fast, in a bigger area, and heals [yellow]2[fg] units instead' end,
|
||||
['carver'] = function() return '[fg]carves a tree that creates healing orbs [yellow]twice[fg] as fast' end,
|
||||
['bane'] = function() return "[yellow]100%[fg] increased area for bane's void rifts" end,
|
||||
['psykino'] = function() return '[fg]enemies take [yellow]' .. 4*get_character_stat('psykino', 3, 'dmg') .. '[fg] damage and are pushed away when the area expires' end,
|
||||
['barrager'] = function() return '[fg]every 3rd attack the barrage shoots [yellow]15[fg] projectiles and they push harder' end,
|
||||
|
@ -771,6 +818,7 @@ function init()
|
|||
['flagellant'] = function() return '[yellow]2X[fg] flagellant max HP and grants [yellow]+12%[fg] damage to all allies per cast instead' end,
|
||||
['arcanist'] = function() return '[yellow]+50%[fg] attack speed for the orb and [yellow]2[fg] projectiles are released per cast' end,
|
||||
['illusionist'] = function() return '[yellow]doubles[fg] the number of copies created and they release [yellow]12[fg] projectiles on death' end,
|
||||
['artificer'] = function() return '[fg]automatons shoot and move 50% faster and release [yellow]12[fg] projectiles on death' end,
|
||||
['witch'] = function() return '[fg]the area releases projectiles, each dealing [yellow]' .. get_character_stat('witch', 3, 'dmg') .. '[fg] damage and chaining once' end,
|
||||
['silencer'] = function() return '[fg]the curse also deals [yellow]' .. get_character_stat('silencer', 3, 'dmg') .. '[fg] damage per second' end,
|
||||
['vulcanist'] = function() return '[fg]the number and speed of explosions is [yellow]doubled[fg]' end,
|
||||
|
@ -795,12 +843,14 @@ function init()
|
|||
['blade'] = function() return '[light_bg]deal additional ' .. math.round(get_character_stat('blade', 3, 'dmg')/2, 2) .. ' damage per enemy hit' end,
|
||||
['elementor'] = function() return '[light_bg]slows enemies by 60% for 6 seconds on hit' end,
|
||||
['saboteur'] = function() return '[light_bg]the explosion has 50% chance to crit, increasing in size and dealing 2x damage' end,
|
||||
['bomber'] = function() return '[light_bg]+100% bomb area and damage' end,
|
||||
['stormweaver'] = function() return "[light_bg]chain lightning's trigger area of effect and number of units hit is doubled" end,
|
||||
['sage'] = function() return '[light_bg]when the projectile expires deal ' .. 3*get_character_stat('sage', 3, 'dmg') .. ' damage to all enemies under its influence' end,
|
||||
['squire'] = function() return '[light_bg]+30% damage, attack speed, movement speed and defense to all allies' 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,
|
||||
['hunter'] = function() return '[light_bg]summons 3 pets and the pets ricochet off walls once' end,
|
||||
['sentry'] = function() return '[light_bg]+50% attack speed and the projectiles ricochet twice' 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,
|
||||
['psykeeper'] = function() return '[light_bg]deal double the damage taken by the psykeeper to all enemies' end,
|
||||
|
@ -828,6 +878,7 @@ function init()
|
|||
['flagellant'] = function() return '[light_bg]2X flagellant max HP and grants +12% damage to all allies per cast instead' end,
|
||||
['arcanist'] = function() return '[light_bg]+50% attack speed for the orb and 2 projectiles are released per cast' end,
|
||||
['illusionist'] = function() return '[light_bg]doubles the number of copies created and they release 12 projectiles on death' end,
|
||||
['artificer'] = function() return '[light_bg]automatons shoot and move 50% faster and release 12 projectiles on death' end,
|
||||
['witch'] = function() return '[light_bg]the area periodically releases projectiles, each dealing ' .. get_character_stat('witch', 3, 'dmg') .. ' damage and chaining once' end,
|
||||
['silencer'] = function() return '[light_bg]the curse also deals ' .. get_character_stat('silencer', 3, 'dmg') .. ' damage per second' end,
|
||||
['vulcanist'] = function() return '[light_bg]the number and speed of explosions is doubled' end,
|
||||
|
@ -852,12 +903,14 @@ function init()
|
|||
['blade'] = function(lvl) return get_character_stat_string('blade', lvl) end,
|
||||
['elementor'] = function(lvl) return get_character_stat_string('elementor', lvl) end,
|
||||
['saboteur'] = function(lvl) return get_character_stat_string('saboteur', lvl) end,
|
||||
['bomber'] = function(lvl) return get_character_stat_string('bomber', lvl) end,
|
||||
['stormweaver'] = function(lvl) return get_character_stat_string('stormweaver', lvl) end,
|
||||
['sage'] = function(lvl) return get_character_stat_string('sage', lvl) end,
|
||||
['squire'] = function(lvl) return get_character_stat_string('squire', lvl) end,
|
||||
['cannoneer'] = function(lvl) return get_character_stat_string('cannoneer', lvl) end,
|
||||
['dual_gunner'] = function(lvl) return get_character_stat_string('dual_gunner', lvl) end,
|
||||
['hunter'] = function(lvl) return get_character_stat_string('hunter', lvl) end,
|
||||
['sentry'] = function(lvl) return get_character_stat_string('sentry', lvl) end,
|
||||
['chronomancer'] = function(lvl) return get_character_stat_string('chronomancer', lvl) end,
|
||||
['spellblade'] = function(lvl) return get_character_stat_string('spellblade', lvl) end,
|
||||
['psykeeper'] = function(lvl) return get_character_stat_string('psykeeper', lvl) end,
|
||||
|
@ -885,6 +938,7 @@ function init()
|
|||
['flagellant'] = function(lvl) return get_character_stat_string('flagellant', lvl) end,
|
||||
['arcanist'] = function(lvl) return get_character_stat_string('arcanist', lvl) end,
|
||||
['illusionist'] = function(lvl) return get_character_stat_string('illusionist', lvl) end,
|
||||
['artificer'] = function(lvl) return get_character_stat_string('artificer', lvl) end,
|
||||
['witch'] = function(lvl) return get_character_stat_string('witch', lvl) end,
|
||||
['silencer'] = function(lvl) return get_character_stat_string('silencer', lvl) end,
|
||||
['vulcanist'] = function(lvl) return get_character_stat_string('vulcanist', lvl) end,
|
||||
|
@ -943,7 +997,7 @@ function init()
|
|||
['healer'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+8%[light_bg]/[' .. ylb2(lvl) .. ']+16% [fg] chance for enemies to drop healing orbs on death' end,
|
||||
['enchanter'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+15%[light_bg]/[' .. ylb2(lvl) .. ']+25% [fg]damage to all allies' end,
|
||||
['nuker'] = function(lvl) return '[' .. ylb1(lvl) .. ']3[light_bg]/[' .. ylb2(lvl) .. ']6 [fg]- [' .. ylb1(lvl) .. ']+15%[light_bg]/[' .. ylb2(lvl) .. ']+25% [fg]area damage and size to allied nukers' end,
|
||||
['conjurer'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+25%[light_bg]/[' .. ylb2(lvl) .. ']+50% [fg]summon damage and duration' end,
|
||||
['conjurer'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+25%[light_bg]/[' .. ylb2(lvl) .. ']+50% [fg]construct damage and duration' end,
|
||||
['psyker'] = function(lvl) return '[fg]create a piercing, damaging orb around each psyker' end,
|
||||
['curser'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[light_bg]/[' .. ylb2(lvl) .. ']4 [fg]- [' .. ylb1(lvl) .. ']+1[light_bg]/[' .. ylb2(lvl) .. ']+3 [fg]max curse targets to allied cursers' 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,
|
||||
|
@ -959,8 +1013,8 @@ function init()
|
|||
|
||||
tier_to_characters = {
|
||||
[1] = {'vagrant', 'swordsman', 'magician', 'archer', 'scout', 'cleric', 'arcanist', 'merchant'},
|
||||
[2] = {'wizard', 'saboteur', 'sage', 'squire', 'dual_gunner', 'hunter', 'chronomancer', 'barbarian', 'cryomancer', 'beastmaster', 'jester', 'carver', 'psychic', 'witch', 'silencer', 'outlaw', 'miner'},
|
||||
[3] = {'elementor', 'stormweaver', 'spellblade', 'psykeeper', 'engineer', 'juggernaut', 'pyromancer', 'host', 'assassin', 'bane', 'barrager', 'infestor', 'flagellant', 'illusionist', 'usurer', 'gambler'},
|
||||
[2] = {'wizard', 'bomber', 'sage', 'squire', 'dual_gunner', 'sentry', 'chronomancer', 'barbarian', 'cryomancer', 'beastmaster', 'jester', 'carver', 'psychic', 'witch', 'silencer', 'outlaw', 'miner'},
|
||||
[3] = {'elementor', 'stormweaver', 'spellblade', 'psykeeper', 'engineer', 'juggernaut', 'pyromancer', 'host', 'assassin', 'bane', 'barrager', 'infestor', 'flagellant', 'artificer', 'usurer', 'gambler'},
|
||||
[4] = {'priest', 'highlander', 'psykino', 'fairy', 'blade', 'plague_doctor', 'cannoneer', 'vulcanist', 'warden', 'corruptor', 'thief'},
|
||||
}
|
||||
|
||||
|
@ -977,14 +1031,16 @@ function init()
|
|||
['outlaw'] = 2,
|
||||
['blade'] = 4,
|
||||
['elementor'] = 3,
|
||||
['saboteur'] = 2,
|
||||
-- ['saboteur'] = 2,
|
||||
['bomber'] = 2,
|
||||
['wizard'] = 2,
|
||||
['stormweaver'] = 3,
|
||||
['sage'] = 2,
|
||||
['squire'] = 2,
|
||||
['cannoneer'] = 4,
|
||||
['dual_gunner'] = 2,
|
||||
['hunter'] = 2,
|
||||
-- ['hunter'] = 2,
|
||||
['sentry'] = 2,
|
||||
['chronomancer'] = 2,
|
||||
['spellblade'] = 3,
|
||||
['psykeeper'] = 3,
|
||||
|
@ -1011,7 +1067,8 @@ function init()
|
|||
['infestor'] = 3,
|
||||
['flagellant'] = 3,
|
||||
['arcanist'] = 1,
|
||||
['illusionist'] = 3,
|
||||
-- ['illusionist'] = 3,
|
||||
['artificer'] = 3,
|
||||
['witch'] = 2,
|
||||
['silencer'] = 2,
|
||||
['vulcanist'] = 4,
|
||||
|
@ -1026,7 +1083,7 @@ function init()
|
|||
|
||||
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'}
|
||||
'arcanist', 'illusionist', 'artificer', 'miner', 'thief', 'sentry'}
|
||||
return table.any(classes, function(v) return v == character end)
|
||||
end
|
||||
|
||||
|
@ -1202,7 +1259,26 @@ function init()
|
|||
['psychosense'] = 'Psychosense',
|
||||
['rearm'] = 'Rearm',
|
||||
['taunt'] = 'Taunt',
|
||||
['summon_instability'] = 'Summon Instability',
|
||||
['construct_instability'] = 'Construct Instability',
|
||||
['intimidation'] = 'Intimidation',
|
||||
['vulnerability'] = 'Vulnerability',
|
||||
['temporal_chains'] = 'Temporal Chains',
|
||||
['ceremonial_dagger'] = 'Ceremonial Dagger',
|
||||
['homing_barrage'] = 'Homing Barrage',
|
||||
['critical_strike'] = 'Critical Strike',
|
||||
['noxious_strike'] = 'Noxious Strike',
|
||||
['infesting_strike'] = 'Infesting Strike',
|
||||
['kinetic_strike'] = 'Kinetic Strike',
|
||||
['burning_strike'] = 'Burning Strike',
|
||||
['lucky_strike'] = 'Lucky Strike',
|
||||
['healing_strike'] = 'Healing Strike',
|
||||
['stunning_strike'] = 'Stunning Strike',
|
||||
['silencing_strike'] = 'Silencing Strike',
|
||||
['warping_shots'] = 'Warping Shots',
|
||||
['culling_strike'] = 'Culling Strike',
|
||||
['lightning_strike'] = 'Lightning Strike',
|
||||
['psycholeak'] = 'Psycholeak',
|
||||
['divine_blessing'] = 'Divine Blessing',
|
||||
}
|
||||
|
||||
passive_descriptions = {
|
||||
|
@ -1266,9 +1342,28 @@ function init()
|
|||
['orbitism'] = '[yellow]+33/66/99%[fg] orb movement speed',
|
||||
['psyker_orbs'] = '[yellow]+1/2/3[fg] psyker orbs',
|
||||
['psychosense'] = '[yellow]+33/66/99%[fg] orb range',
|
||||
['rearm'] = '[fg]summons repeat their attacks once',
|
||||
['taunt'] = '[yellow]10/20/30%[fg] chance for summons to taunt nearby enemies on attack',
|
||||
['summon_instability'] = '[fg]summons explode when disappearing, dealing [yellow]100/150/200%[fg] damage',
|
||||
['rearm'] = '[fg]constructs repeat their attacks once',
|
||||
['taunt'] = '[yellow]10/20/30%[fg] chance for constructs to taunt nearby enemies on attack',
|
||||
['construct_instability'] = '[fg]constructs explode when disappearing, dealing [yellow]100/150/200%[fg] damage',
|
||||
['intimidation'] = '[fg]enemies spawn with [yellow]-10/20/30%[fg] max HP',
|
||||
['vulnerability'] = '[fg]enemies take [yellow]+10/20/30%[fg] damage',
|
||||
['temporal_chains'] = '[fg]enemies are [yellow]10/20/30%[fg] slower',
|
||||
['ceremonial_dagger'] = '[fg]killing an enemy fires a homing dagger',
|
||||
['homing_barrage'] = '[yellow]8/16/24%[fg] chance to release a homing barrage on enemy kill',
|
||||
['critical_strike'] = '[yellow]5/10/15%[fg] chance for attacks to critically strike, dealing [yellow]2x[fg] damage',
|
||||
['noxious_strike'] = '[yellow]8/16/24%[fg] chance for attacks to poison, dealing [yellow]20%[fg] dps for [yellow]3[fg] seconds',
|
||||
['infesting_strike'] = '[yellow]10/20/30%[fg] chance for attacks to spawn [yellow]2[fg] critters on kill',
|
||||
['kinetic_strike'] = '[yellow]10/20/30%[fg] chance for attacks to push enemies away with high force',
|
||||
['burning_strike'] = '[yellow]15%[fg] chance for attacks to burn, dealing [yellow]20%[fg] dps for [yellow]3[fg] seconds',
|
||||
['lucky_strike'] = '[yellow]8%[fg] chance for attacks to cause enemies to drop gold on death',
|
||||
['healing_strike'] = '[yellow]8%[fg] chance for attacks to spawn a healing orb on kill',
|
||||
['stunning_strike'] = '[yellow]8/16/24%[fg] chance for attacks to stun for [yellow]2[fg] seconds',
|
||||
['silencing_strike'] = '[yellow]8/16/24%[fg] chance for attacks to silence for [yellow]2[fg] seconds on hit',
|
||||
['warping_shots'] = 'projectiles ignore wall collisions and warp around the screen [yellow]1/2/3[fg] times',
|
||||
['culling_strike'] = '[fg]instantly kill elites below [yellow]10/20/30%[fg] max HP',
|
||||
['lightning_strike'] = '[yellow]5/10/15%[fg] chance for projectiles to create chain lightning, dealing [yellow]60/80/100%[fg] damage',
|
||||
['psycholeak'] = '[fg]position [yellow]1[fg] generates [yellow]1[fg] psyker orb every [yellow]10[fg] seconds',
|
||||
['divine_blessing'] = '[fg]generate [yellow]1[fg] healing orb every [yellow]8[fg] seconds',
|
||||
}
|
||||
|
||||
local ts = function(lvl, a, b, c) return '[' .. ylb1(lvl) .. ']' .. tostring(a) .. '[light_bg]/[' .. ylb2(lvl) .. ']' .. tostring(b) .. '[light_bg]/[' .. ylb3(lvl) .. ']' .. tostring(c) .. '[fg]' end
|
||||
|
@ -1333,9 +1428,28 @@ function init()
|
|||
['orbitism'] = function(lvl) return ts(lvl, '+33%', '66%', '99%') .. ' orb movement speed' end,
|
||||
['psyker_orbs'] = function(lvl) return ts(lvl, '+1', '2', '3') .. ' psyker orbs' end,
|
||||
['psychosense'] = function(lvl) return ts(lvl, '+33%', '66%', '99%') .. ' orb range' end,
|
||||
['rearm'] = function(lvl) return '[fg]summons repeat their attacks once' end,
|
||||
['taunt'] = function(lvl) return ts(lvl, '10%', '20%', '30%') .. ' chance for summons to taunt nearby enemies on attack' end,
|
||||
['summon_instability'] = function(lvl) return '[fg]summons explode when disappearing, dealing [yellow]100/150/200%[fg] damage' end,
|
||||
['rearm'] = function(lvl) return '[fg]constructs repeat their attacks once' end,
|
||||
['taunt'] = function(lvl) return ts(lvl, '10%', '20%', '30%') .. ' chance for constructs to taunt nearby enemies on attack' end,
|
||||
['construct_instability'] = function(lvl) return '[fg]constructs explode when disappearing, dealing ' .. ts(lvl, '100', '150', '200%') .. ' damage' end,
|
||||
['intimidation'] = function(lvl) return '[fg]enemies spawn with ' .. ts(lvl, '-10', '20', '30%') .. ' max HP' end,
|
||||
['vulnerability'] = function(lvl) return '[fg]enemies take ' .. ts(lvl, '+10', '20', '30%').. ' damage' end,
|
||||
['temporal_chains'] = function(lvl) return '[fg]enemies are ' .. ts(lvl, '10', '20', '30%').. ' slower' end,
|
||||
['ceremonial_dagger'] = function(lvl) return '[fg]killing an enemy fires a homing dagger' end,
|
||||
['homing_barrage'] = function(lvl) return ts(lvl, '8', '16', '24%') .. ' chance to release a homing barrage on enemy kill' end,
|
||||
['critical_strike'] = function(lvl) return ts(lvl, '5', '10', '15%') .. ' chance for attacks to critically strike, dealing [yellow]2x[fg] damage' end,
|
||||
['noxious_strike'] = function(lvl) return ts(lvl, '8', '16', '24%') .. ' chance for attacks to poison, dealing [yellow]20%[fg] dps for [yellow]3[fg] seconds' end,
|
||||
['infesting_strike'] = function(lvl) return ts(lvl, '10', '20', '30%') .. ' chance for attacks to spawn [yellow]2[fg] critters on kill' end,
|
||||
['kinetic_strike'] = function(lvl) return ts(lvl, '10', '20', '30%') .. ' chance for attacks to push enemies away with high force' end,
|
||||
['burning_strike'] = function(lvl) return '[yellow]15%[fg] chance for attacks to burn, dealing [yellow]20%[fg] dps for [yellow]3[fg] seconds' end,
|
||||
['lucky_strike'] = function(lvl) return '[yellow]8%[fg] chance for attacks to cause enemies to drop gold on death' end,
|
||||
['healing_strike'] = function(lvl) return '[yellow]8%[fg] chance for attacks to spawn a healing orb on kill' end,
|
||||
['stunning_strike'] = function(lvl) return ts(lvl, '8', '16', '24%') .. ' chance for attacks to stun for [yellow]2[fg] seconds' end,
|
||||
['silencing_strike'] = function(lvl) return ts(lvl, '8', '16', '24%') .. ' chance for attacks to silence for [yellow]2[fg] seconds on hit' end,
|
||||
['warping_shots'] = function(lvl) return 'projectiles ignore wall collisions and warp around the screen ' .. ts(lvl, '1', '2', '3') .. ' times' end,
|
||||
['culling_strike'] = function(lvl) return '[fg]instantly kill elites below ' .. ts(lvl, '10', '20', '30%') .. ' max HP' end,
|
||||
['lightning_strike'] = function(lvl) return ts(lvl, '5', '10', '15%') .. ' chance for projectiles to create chain lightning, dealing ' .. ts(lvl, '60', '80', '100%') .. ' damage' end,
|
||||
['psycholeak'] = function(lvl) return '[fg]position [yellow]1[fg] generates [yellow]1[fg] psyker orb every [yellow]10[fg] seconds' end,
|
||||
['divine_blessing'] = function(lvl) return '[fg]generate [yellow]1[fg] healing orb every [yellow]8[fg] seconds' end,
|
||||
}
|
||||
|
||||
level_to_tier_weights = {
|
||||
|
@ -1571,7 +1685,7 @@ function init()
|
|||
unlevellable_items = {
|
||||
'speed_3', 'damage_4', 'shoot_5', 'death_6', 'lasting_7', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'annihilation',
|
||||
'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'divine_punishment', 'unleash', 'freezing_field', 'burning_field', 'gravity_field',
|
||||
'magnetism', 'insurance', 'dividends', 'haste', 'rearm',
|
||||
'magnetism', 'insurance', 'dividends', 'haste', 'rearm', 'ceremonial_dagger', 'burning_strike', 'lucky_strike', 'healing_strike', 'psycholeak', 'divine_blessing'
|
||||
}
|
||||
|
||||
steam.userStats.requestCurrentStats()
|
||||
|
@ -1584,8 +1698,10 @@ function init()
|
|||
main_song_instance = _G[random:table{'song1', 'song2', 'song3', 'song4', 'song5'}]:play{volume = 0.5}
|
||||
main = Main()
|
||||
|
||||
--[[
|
||||
main:add(MainMenu'mainmenu')
|
||||
main:go_to('mainmenu')
|
||||
]]--
|
||||
|
||||
--[[
|
||||
main:add(BuyScreen'buy_screen')
|
||||
|
@ -1593,33 +1709,25 @@ function init()
|
|||
-- main:go_to('buy_screen', 7, run.units or {}, {'unleash'})
|
||||
]]--
|
||||
|
||||
--[[
|
||||
gold = 10
|
||||
run_passive_pool = {
|
||||
'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', 'hextouch', 'whispers_of_doom',
|
||||
'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',
|
||||
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosense', 'rearm', 'taunt', 'summon_instability',
|
||||
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosense', 'rearm', 'taunt', 'construct_instability',
|
||||
'intimidation', 'vulnerability', 'temporal_chains', 'ceremonial_dagger', 'homing_barrage', 'critical_strike', 'noxious_strike', 'infesting_strike', 'burning_strike', 'lucky_strike', 'healing_strike', 'stunning_strike',
|
||||
'silencing_strike', 'culling_strike', 'lightning_strike', 'psycholeak', 'divine_blessing',
|
||||
}
|
||||
main:add(Arena'arena')
|
||||
main:go_to('arena', 1, {
|
||||
{character = 'vagrant', level = 3},
|
||||
main:go_to('arena', 2, 0, {
|
||||
{character = 'carver', level = 3},
|
||||
-- {character = 'carver', level = 2},
|
||||
{character = 'dual_gunner', level = 3},
|
||||
-- {character = 'saboteur', level = 2},
|
||||
-- {character = 'hunter', level = 2},
|
||||
}, {
|
||||
{passive = 'summon_instability', level = 3},
|
||||
{passive = 'summon_instability', level = 3},
|
||||
{passive = 'summon_instability', level = 3},
|
||||
{passive = 'summon_instability', level = 3},
|
||||
{passive = 'summon_instability', level = 3},
|
||||
{passive = 'summon_instability', level = 3},
|
||||
{passive = 'summon_instability', level = 3},
|
||||
{passive = 'summon_instability', level = 3},
|
||||
{passive = 'rearm', level = 1},
|
||||
})
|
||||
]]--
|
||||
|
||||
--[[
|
||||
main:add(Media'media')
|
||||
|
@ -1789,7 +1897,7 @@ function open_options(self)
|
|||
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'hextouch', 'whispers_of_doom',
|
||||
'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',
|
||||
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosense', 'rearm', 'taunt', 'summon_instability',
|
||||
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance', 'blessing', 'haste', 'divine_barrage', 'orbitism', 'psyker_orbs', 'psychosense', 'rearm', 'taunt', 'construct_instability',
|
||||
}
|
||||
max_units = 7 + current_new_game_plus
|
||||
main:add(BuyScreen'buy_screen')
|
||||
|
|
|
@ -310,7 +310,7 @@ function Unit:calculate_stats(first_run)
|
|||
self.base_hp = 100*math.pow(2, self.level-1)
|
||||
self.base_dmg = 10*math.pow(2, self.level-1)
|
||||
self.base_mvspd = 75
|
||||
elseif self:is(Illusion) then
|
||||
elseif self:is(Automaton) then
|
||||
self.base_hp = 100*math.pow(2, self.level-1)
|
||||
self.base_dmg = 10*math.pow(2, self.level-1)
|
||||
self.base_mvspd = 15
|
||||
|
|
416
player.lua
|
@ -141,14 +141,14 @@ function Player:init(args)
|
|||
if self.level == 3 then
|
||||
for i = 1, 4 do
|
||||
local check_circle = Circle(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16), 2)
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Sentry, Automaton, Bomb, Volcano, Saboteur, Pet, Turret})
|
||||
while #objects > 0 do
|
||||
check_circle:move_to(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16))
|
||||
objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Sentry, Automaton, Bomb, Volcano, Saboteur, Pet, Turret})
|
||||
end
|
||||
SpawnEffect{group = main.current.effects, x = check_circle.x, y = check_circle.y, color = green[0], action = function(x, y)
|
||||
local check_circle = Circle(x, y, 2)
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Sentry, Automaton, Bomb, Volcano, Saboteur, Pet, Turret})
|
||||
if #objects == 0 then
|
||||
HealingOrb{group = main.current.main, x = x, y = y}
|
||||
end
|
||||
|
@ -156,14 +156,14 @@ function Player:init(args)
|
|||
end
|
||||
else
|
||||
local check_circle = Circle(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16), 2)
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Sentry, Automaton, Bomb, Volcano, Saboteur, Pet, Turret})
|
||||
while #objects > 0 do
|
||||
check_circle:move_to(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16))
|
||||
objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Sentry, Automaton, Bomb, Volcano, Saboteur, Pet, Turret})
|
||||
end
|
||||
SpawnEffect{group = main.current.effects, x = check_circle.x, y = check_circle.y, color = green[0], action = function(x, y)
|
||||
local check_circle = Circle(x, y, 2)
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Sentry, Automaton, Bomb, Volcano, Saboteur, Pet, Turret})
|
||||
if #objects == 0 then
|
||||
HealingOrb{group = main.current.main, x = x, y = y}
|
||||
end
|
||||
|
@ -205,49 +205,31 @@ function Player:init(args)
|
|||
end
|
||||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'illusionist' then
|
||||
elseif self.character == 'artificer' then
|
||||
self.sorcerer_count = 0
|
||||
self.attack_sensor = Circle(self.x, self.y, 96)
|
||||
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))
|
||||
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_repeat()
|
||||
self.sorcerer_count = 0
|
||||
self.t:after(0.25, function()
|
||||
self:shoot(self:angle_to_object(closest_enemy))
|
||||
end)
|
||||
end
|
||||
self.t:every(6, function()
|
||||
SpawnEffect{group = main.current.effects, x = self.x, y = self.y, color = self.color, action = function(x, y)
|
||||
artificer1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
local check_circle = Circle(self.x, self.y, 2)
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Volcano, Saboteur, Pet, Turret, Sentry, Bomb})
|
||||
if #objects == 0 then Automaton{group = main.current.main, x = x, y = y, parent = self, level = self.level, conjurer_buff_m = self.conjurer_buff_m or 1} end
|
||||
end}
|
||||
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_repeat()
|
||||
self.sorcerer_count = 0
|
||||
self.t:after(0.25, function()
|
||||
SpawnEffect{group = main.current.effects, x = self.x, y = self.y, color = self.color, action = function(x, y)
|
||||
artificer1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
local check_circle = Circle(self.x, self.y, 2)
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Volcano, Saboteur, Pet, Turret, Sentry, Bomb})
|
||||
if #objects == 0 then Automaton{group = main.current.main, x = x, y = y, parent = self, level = self.level, conjurer_buff_m = self.conjurer_buff_m or 1} end
|
||||
end}
|
||||
end)
|
||||
end
|
||||
end
|
||||
end, nil, nil, 'shoot')
|
||||
self.t:every(8, function()
|
||||
self.t:every(0.25, function()
|
||||
SpawnEffect{group = main.current.effects, x = self.x, y = self.y, color = self.color, action = function(x, y)
|
||||
illusion1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
local check_circle = Circle(self.x, self.y, 2)
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
if #objects == 0 then Illusion{group = main.current.main, x = x, y = y, parent = self, level = self.level, conjurer_buff_m = self.conjurer_buff_m or 1} end
|
||||
end}
|
||||
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_repeat()
|
||||
self.sorcerer_count = 0
|
||||
self.t:after(0.25, function()
|
||||
SpawnEffect{group = main.current.effects, x = self.x, y = self.y, color = self.color, action = function(x, y)
|
||||
illusion1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
local check_circle = Circle(self.x, self.y, 2)
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
if #objects == 0 then Illusion{group = main.current.main, x = x, y = y, parent = self, level = self.level, conjurer_buff_m = self.conjurer_buff_m or 1} end
|
||||
end}
|
||||
end)
|
||||
end
|
||||
end
|
||||
end, self.level == 3 and 2 or 1)
|
||||
end)
|
||||
|
||||
elseif self.character == 'outlaw' then
|
||||
|
@ -316,6 +298,13 @@ function Player:init(args)
|
|||
end, 2)
|
||||
end, nil, nil, 'spawn')
|
||||
|
||||
elseif self.character == 'bomber' then
|
||||
self.t:every(8, function()
|
||||
SpawnEffect{group = main.current.effects, x = self.x, y = self.y, color = self.color, action = function(x, y)
|
||||
Bomb{group = main.current.main, x = x, y = y, parent = self, level = self.level, conjurer_buff_m = self.conjurer_buff_m or 1}
|
||||
end}
|
||||
end, nil, nil, 'spawn')
|
||||
|
||||
elseif self.character == 'stormweaver' then
|
||||
self.t:every(8, function()
|
||||
stormweaver1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
|
@ -363,7 +352,7 @@ function Player:init(args)
|
|||
x, y = x/2, y/2
|
||||
main.current.t:every_immediate(0.1, function()
|
||||
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, Saboteur, Pet, Turret, Sentry, Bomb})
|
||||
if #objects == 0 then
|
||||
Volcano{group = main.current.main, x = x, y = y, color = self.color, parent = self, rs = 24, level = self.level}
|
||||
main.current.t:cancel('volcano_spawn')
|
||||
|
@ -619,7 +608,12 @@ function Player:init(args)
|
|||
|
||||
elseif self.character == 'carver' then
|
||||
self.t:every(16, function()
|
||||
Tree{group = main.current.main, x = self.x, y = self.y, color = self.color, parent = self, rs = self.area_size_m*(self.level == 3 and 128 or 64), level = self.level}
|
||||
Tree{group = main.current.main, x = self.x, y = self.y, color = self.color, parent = self, level = self.level}
|
||||
end, nil, nil, 'spawn')
|
||||
|
||||
elseif self.character == 'sentry' then
|
||||
self.t:every(7, function()
|
||||
Sentry{group = main.current.main, x = self.x, y = self.y, color = self.color, parent = self, level = self.level}
|
||||
end, nil, nil, 'spawn')
|
||||
|
||||
elseif self.character == 'bane' then
|
||||
|
@ -697,14 +691,14 @@ function Player:init(args)
|
|||
buff1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
for i = 1, 2 do
|
||||
local check_circle = Circle(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16), 2)
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Volcano, Saboteur, Bomb, Pet, Turret, Sentry})
|
||||
while #objects > 0 do
|
||||
check_circle:move_to(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16))
|
||||
objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Volcano, Saboteur, Pet, Turret, Sentry, Bomb})
|
||||
end
|
||||
SpawnEffect{group = main.current.effects, x = check_circle.x, y = check_circle.y, color = green[0], action = function(x, y)
|
||||
local check_circle = Circle(x, y, 2)
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Volcano, Saboteur, Bomb, Pet, Turret, Sentry})
|
||||
if #objects == 0 then
|
||||
HealingOrb{group = main.current.main, x = x, y = y}
|
||||
end
|
||||
|
@ -720,14 +714,14 @@ function Player:init(args)
|
|||
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
buff1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
local check_circle = Circle(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16), 2)
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Volcano, Saboteur, Bomb, Pet, Turret, Sentry})
|
||||
while #objects > 0 do
|
||||
check_circle:move_to(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16))
|
||||
objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Volcano, Saboteur, Bomb, Pet, Turret, Sentry})
|
||||
end
|
||||
SpawnEffect{group = main.current.effects, x = check_circle.x, y = check_circle.y, color = green[0], action = function(x, y)
|
||||
local check_circle = Circle(x, y, 2)
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Volcano, Saboteur, Pet, Turret, Sentry, Bomb})
|
||||
if #objects == 0 then
|
||||
HealingOrb{group = main.current.main, x = x, y = y}
|
||||
end
|
||||
|
@ -812,7 +806,7 @@ function Player:init(args)
|
|||
for i = 1, 5 do
|
||||
SpawnEffect{group = main.current.effects, x = x, y = y, color = green[0], action = function(x, y)
|
||||
local check_circle = Circle(x, y, 2)
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Volcano, Saboteur, Bomb, Pet, Turret, Sentry, Automaton})
|
||||
if #objects == 0 then HealingOrb{group = main.current.main, x = x, y = y} end
|
||||
end}
|
||||
end
|
||||
|
@ -1090,6 +1084,24 @@ function Player:init(args)
|
|||
end)
|
||||
end
|
||||
|
||||
if self.leader and self.psycholeak then
|
||||
main.current.t:every(10, function()
|
||||
local unit = main.current.player
|
||||
Projectile{group = main.current.main, x = unit.x + 24*math.cos(unit.r), y = unit.y + 24*math.sin(unit.r), color = fg[0], v = 200, dmg = unit.dmg, character = 'psyker', parent = unit}
|
||||
end)
|
||||
end
|
||||
|
||||
if self.leader and self.divine_blessing then
|
||||
main.current.t:every(8, function()
|
||||
local x, y = random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16)
|
||||
SpawnEffect{group = main.current.effects, x = x, y = y, color = green[0], action = function(x, y)
|
||||
local check_circle = Circle(x, y, 2)
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Volcano, Saboteur, Bomb, Pet, Turret, Sentry, Automaton})
|
||||
if #objects == 0 then HealingOrb{group = main.current.main, x = x, y = y} end
|
||||
end}
|
||||
end)
|
||||
end
|
||||
|
||||
self.mouse_control_v_buffer = {}
|
||||
|
||||
if main.current:is(MainMenu) then
|
||||
|
@ -1516,14 +1528,14 @@ function Player:hit(damage, from_undead)
|
|||
if self.stored_heal > (0.2*self.max_hp) then
|
||||
self.stored_heal = 0
|
||||
local check_circle = Circle(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16), 2)
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Volcano, Saboteur, Bomb, Pet, Turret, Sentry, Automaton})
|
||||
while #objects > 0 do
|
||||
check_circle:move_to(random:float(main.current.x1 + 16, main.current.x2 - 16), random:float(main.current.y1 + 16, main.current.y2 - 16))
|
||||
objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Volcano, Saboteur, Bomb, Pet, Turret, Sentry, Automaton})
|
||||
end
|
||||
SpawnEffect{group = main.current.effects, x = check_circle.x, y = check_circle.y, color = green[0], action = function(x, y)
|
||||
local check_circle = Circle(x, y, 2)
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Seeker, EnemyCritter, Critter, Sentry, Volcano, Saboteur, Bomb, Pet, Turret, Automaton})
|
||||
if #objects == 0 then
|
||||
HealingOrb{group = main.current.main, x = x, y = y}
|
||||
end
|
||||
|
@ -1817,7 +1829,7 @@ function Player:shoot(r, mods)
|
|||
Projectile(table.merge(t, mods or {}))
|
||||
end
|
||||
|
||||
if self.character == 'vagrant' or self.character == 'illusionist' then
|
||||
if self.character == 'vagrant' or self.character == 'artificer' then
|
||||
shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.2}
|
||||
elseif self.character == 'dual_gunner' then
|
||||
dual_gunner1:play{pitch = random:float(0.95, 1.05), volume = 0.3}
|
||||
|
@ -1886,7 +1898,7 @@ function Player:dot_attack(area, mods)
|
|||
end
|
||||
|
||||
|
||||
function Player:barrage(r, n, pierce, ricochet, shoot_5)
|
||||
function Player:barrage(r, n, pierce, ricochet, shoot_5, homing)
|
||||
n = n or 8
|
||||
for i = 1, n do
|
||||
self.t:after((i-1)*0.075, function()
|
||||
|
@ -1894,7 +1906,7 @@ function Player:barrage(r, n, pierce, ricochet, shoot_5)
|
|||
else archer1:play{pitch = random:float(0.95, 1.05), volume = 0.35} end
|
||||
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,
|
||||
parent = self, character = 'barrage', level = self.level, pierce = pierce or 0, ricochet = ricochet or 0, shoot_5 = shoot_5}
|
||||
parent = self, character = 'barrage', level = self.level, pierce = pierce or 0, ricochet = ricochet or 0, shoot_5 = shoot_5, homing = homing}
|
||||
Projectile(table.merge(t, mods or {}))
|
||||
end)
|
||||
end
|
||||
|
@ -1909,7 +1921,7 @@ Projectile:implement(Physics)
|
|||
function Projectile:init(args)
|
||||
self:init_game_object(args)
|
||||
self.hfx:add('hit', 1)
|
||||
self:set_as_rectangle(10, 4, 'dynamic', 'projectile')
|
||||
self:set_as_rectangle(10, 4, 'dynamic', main.current.player.warping_shots and 'true_ghost' or 'projectile')
|
||||
self.pierce = args.pierce or 0
|
||||
self.chain = args.chain or 0
|
||||
self.ricochet = args.ricochet or 0
|
||||
|
@ -1986,7 +1998,7 @@ function Projectile:init(args)
|
|||
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 = self.parent.color, dmg = self.parent.dmg, pierce = 2, character = 'arcanist_projectile',
|
||||
parent = self.parent, level = self.parent.level}
|
||||
local check_circle = Circle(t.x, t.y, 2)
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Player, Seeker, EnemyCritter, Critter, Illusion, Volcano, Saboteur, Pet, Turret})
|
||||
local objects = main.current.main:get_objects_in_shape(check_circle, {Player, Seeker, EnemyCritter, Critter, Sentry, Volcano, Saboteur, Bomb, Pet, Turret, Automaton})
|
||||
if #objects == 0 then Projectile(table.merge(t, mods or {})) end
|
||||
end
|
||||
end)
|
||||
|
@ -2162,7 +2174,7 @@ function Projectile:on_collision_enter(other, contact)
|
|||
else r = 0 end
|
||||
|
||||
if other:is(Wall) then
|
||||
if self.character == 'archer' or self.character == 'hunter' or self.character == 'barrage' or self.character == 'barrager' then
|
||||
if self.character == 'archer' or self.character == 'hunter' or self.character == 'barrage' or self.character == 'barrager' or self.character == 'sentry' then
|
||||
if self.ricochet <= 0 then
|
||||
self:die(x, y, r, 0)
|
||||
WallArrow{group = main.current.main, x = x, y = y, r = self.r, color = self.color}
|
||||
|
@ -2183,7 +2195,7 @@ function Projectile:on_collision_enter(other, contact)
|
|||
if self.character == 'spellblade' then
|
||||
magic_area1:play{pitch = random:float(0.95, 1.05), volume = 0.075}
|
||||
end
|
||||
elseif self.character == 'illusionist_death' then
|
||||
elseif self.character == 'artificer_death' then
|
||||
if self.ricochet <= 0 then
|
||||
self:die(x, y, r, random:int(2, 3))
|
||||
magic_area1:play{pitch = random:float(0.95, 1.05), volume = 0.075}
|
||||
|
@ -2249,7 +2261,7 @@ function Projectile:on_trigger_enter(other, contact)
|
|||
|
||||
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' or self.character == 'miner' or self.character == 'thief' or
|
||||
self.character == 'psyker' then
|
||||
self.character == 'psyker' or self.character == 'sentry' then
|
||||
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
if self.character == 'spellblade' or self.character == 'psyker' then
|
||||
magic_area1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
|
||||
|
@ -2312,6 +2324,26 @@ function Projectile:on_trigger_enter(other, contact)
|
|||
end
|
||||
end
|
||||
|
||||
if self.parent and self.parent.lightning_strike then
|
||||
if random:bool((self.parent.lightning_strike == 1 and 5) or (self.parent.lightning_strike == 2 and 10) or (self.parent.lightning_strike == 3 and 15)) then
|
||||
local src = other
|
||||
for j = 1, 3 do
|
||||
main.current.t:after((j-1)*0.1, function()
|
||||
_G[random:table{'spark1', 'spark2', 'spark3'}]:play{pitch = random:float(0.9, 1.1), volume = 0.3}
|
||||
for i = 1, 3 do
|
||||
table.insert(self.infused_enemies_hit, src)
|
||||
local dst = src:get_random_object_in_shape(Circle(src.x, src.y, 64), main.current.enemies, self.infused_enemies_hit)
|
||||
if dst then
|
||||
dst:hit(0.33*((self.parent.lightning_strike == 1 and 0.6) or (self.parent.lightning_strike == 2 and 0.8) or (self.parent.lightning_strike == 3 and 1))*self.dmg*(self.distance_dmg_m or 1))
|
||||
LightningLine{group = main.current.effects, src = src, dst = dst}
|
||||
src = dst
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if self.crit then
|
||||
camera:shake(5, 0.25)
|
||||
rogue_crit1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
|
@ -2388,7 +2420,7 @@ function Area:init(args)
|
|||
elseif self.character == 'blade' then
|
||||
blade_hit1:play{pitch = random:float(0.9, 1.1), volume = 0.35}
|
||||
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.2}
|
||||
elseif self.character == 'saboteur' or self.character == 'pyromancer' then
|
||||
elseif self.character == 'saboteur' or self.character == 'pyromancer' or self.character == 'bomber' then
|
||||
if self.character == 'pyromancer' then pyro2:play{pitch = random:float(0.95, 1.05), volume = 0.4} end
|
||||
_G[random:table{'saboteur_hit1', 'saboteur_hit2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.2}
|
||||
elseif self.character == 'cannoneer' then
|
||||
|
@ -2729,7 +2761,7 @@ function Tree:init(args)
|
|||
self:set_restitution(0.5)
|
||||
self.hfx:add('hit', 1)
|
||||
self.color = orange[0]
|
||||
self.heal_sensor = Circle(self.x, self.y, args.rs)
|
||||
self.heal_sensor = Circle(self.x, self.y, 48)
|
||||
|
||||
self.vr = 0
|
||||
self.dvr = random:float(-math.pi/4, math.pi/4)
|
||||
|
@ -2743,6 +2775,39 @@ function Tree:init(args)
|
|||
self.t:tween(0.05, self, {rs = args.rs}, math.cubic_in_out, function() self.spring:pull(0.15) end)
|
||||
self.t:after(0.2, function() self.color = args.color end)
|
||||
|
||||
self.t:every(self.parent.level == 3 and 3 or 6, function()
|
||||
self.hfx:use('hit', 0.2)
|
||||
HealingOrb{group = main.current.main, x = self.x, y = self.y}
|
||||
if self.parent.taunt and random:bool((self.parent.taunt == 1 and 10) or (self.parent.taunt == 2 and 20) or (self.parent.taunt == 3 and 30)) then
|
||||
local enemies = self:get_objects_in_shape(Circle(self.x, self.y, 96), main.current.enemies)
|
||||
|
||||
if #enemies > 0 then
|
||||
for _, enemy in ipairs(enemies) do
|
||||
enemy.taunted = self
|
||||
enemy.t:after(4, function() enemy.taunted = false end, 'taunt')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if self.parent.rearm then
|
||||
self.t:after(0.25, function()
|
||||
self.hfx:use('hit', 0.2)
|
||||
HealingOrb{group = main.current.main, x = self.x, y = self.y}
|
||||
|
||||
if self.parent.taunt and random:bool((self.parent.taunt == 1 and 10) or (self.parent.taunt == 2 and 20) or (self.parent.taunt == 3 and 30)) then
|
||||
local enemies = self:get_objects_in_shape(Circle(self.x, self.y, 96), main.current.enemies)
|
||||
if #enemies > 0 then
|
||||
for _, enemy in ipairs(enemies) do
|
||||
enemy.taunted = self
|
||||
enemy.t:after(4, function() enemy.taunted = false end, 'taunt')
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
--[[
|
||||
self.t:cooldown(3.33/(self.level == 3 and 2 or 1), function() return #self:get_objects_in_shape(self.heal_sensor, {Player}) > 0 end, function()
|
||||
local n = n or random:int(3, 4)
|
||||
for i = 1, n do HitParticle{group = main.current.effects, x = self.x, y = self.y, r = random:float(0, 2*math.pi), color = self.color} end
|
||||
|
@ -2815,14 +2880,15 @@ function Tree:init(args)
|
|||
end
|
||||
end
|
||||
end)
|
||||
]]--
|
||||
|
||||
self.t:after(10*(self.parent.conjurer_buff_m or 1), function()
|
||||
self.t:after(12*(self.parent.conjurer_buff_m or 1), function()
|
||||
self.t:every_immediate(0.05, function() self.hidden = not self.hidden end, 7, function()
|
||||
self.dead = true
|
||||
|
||||
if self.parent.summon_instability then
|
||||
if self.parent.construct_instability then
|
||||
camera:shake(2, 0.5)
|
||||
local n = (self.parent.summon_instability == 1 and 1) or (self.parent.summon_instability == 2 and 1.5) or (self.parent.summon_instability == 3 and 2) or 1
|
||||
local n = (self.parent.construct_instability == 1 and 1) or (self.parent.construct_instability == 2 and 1.5) or (self.parent.construct_instability == 3 and 2) or 1
|
||||
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*48, color = self.color, dmg = n*self.parent.dmg*self.parent.area_dmg_m, parent = self.parent}
|
||||
_G[random:table{'cannoneer1', 'cannoneer2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
end
|
||||
|
@ -2974,6 +3040,97 @@ end
|
|||
|
||||
|
||||
|
||||
Sentry = Object:extend()
|
||||
Sentry:implement(GameObject)
|
||||
Sentry:implement(Physics)
|
||||
function Sentry:init(args)
|
||||
self:init_game_object(args)
|
||||
self:set_as_rectangle(6, 6, 'static', 'player')
|
||||
self:set_restitution(0.5)
|
||||
self.hfx:add('hit', 1)
|
||||
|
||||
self.t:after(15*(self.parent.conjurer_buff_m or 1), function()
|
||||
local n = n or random:int(3, 4)
|
||||
for i = 1, n do HitParticle{group = main.current.effects, x = self.x, y = self.y, r = random:float(0, 2*math.pi), color = self.color} end
|
||||
HitCircle{group = main.current.effects, x = self.x, y = self.y}:scale_down()
|
||||
self.dead = true
|
||||
|
||||
if self.parent.construct_instability then
|
||||
camera:shake(2, 0.5)
|
||||
local n = (self.parent.construct_instability == 1 and 1) or (self.parent.construct_instability == 2 and 1.5) or (self.parent.construct_instability == 3 and 2) or 1
|
||||
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*48, color = self.color, dmg = n*self.parent.dmg*self.parent.area_dmg_m, parent = self.parent}
|
||||
_G[random:table{'cannoneer1', 'cannoneer2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
end
|
||||
end)
|
||||
|
||||
self.t:every({2.75, 3.5}, function()
|
||||
self.hfx:use('hit', 0.25, 200, 10)
|
||||
local r = self.r
|
||||
for i = 1, 4 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 = 200, r = r, color = self.color,
|
||||
dmg = self.parent.dmg*(self.parent.conjurer_buff_m or 1), character = 'sentry', parent = self.parent}
|
||||
Projectile(table.merge(t, mods or {}))
|
||||
r = r + math.pi/2
|
||||
end
|
||||
|
||||
if self.parent.taunt and random:bool((self.parent.taunt == 1 and 10) or (self.parent.taunt == 2 and 20) or (self.parent.taunt == 3 and 30)) then
|
||||
local enemies = self:get_objects_in_shape(Circle(self.x, self.y, 96), main.current.enemies)
|
||||
if #enemies > 0 then
|
||||
for _, enemy in ipairs(enemies) do
|
||||
enemy.taunted = self
|
||||
enemy.t:after(4, function() enemy.taunted = false end, 'taunt')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if self.parent.rearm then
|
||||
self.t:after(0.25, function()
|
||||
self.hfx:use('hit', 0.25, 200, 10)
|
||||
local r = self.r
|
||||
for i = 1, 4 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 = 200, r = r, color = self.color,
|
||||
dmg = self.parent.dmg*(self.parent.conjurer_buff_m or 1), character = 'sentry', parent = self.parent}
|
||||
Projectile(table.merge(t, mods or {}))
|
||||
r = r + math.pi/2
|
||||
end
|
||||
|
||||
if self.parent.taunt and random:bool((self.parent.taunt == 1 and 10) or (self.parent.taunt == 2 and 20) or (self.parent.taunt == 3 and 30)) then
|
||||
local enemies = self:get_objects_in_shape(Circle(self.x, self.y, 96), main.current.enemies)
|
||||
if #enemies > 0 then
|
||||
for _, enemy in ipairs(enemies) do
|
||||
enemy.taunted = self
|
||||
enemy.t:after(4, function() enemy.taunted = false end, 'taunt')
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
function Sentry:update(dt)
|
||||
self:update_game_object(dt)
|
||||
self.r = self.r + math.pi*dt
|
||||
self:set_angle(self.r)
|
||||
end
|
||||
|
||||
|
||||
function Sentry:draw()
|
||||
if self.hidden then return end
|
||||
graphics.push(self.x, self.y, self.r, self.spring.x, self.spring.x)
|
||||
graphics.rectangle(self.x, self.y, 2*self.shape.w, 4, 2, 2, self.hfx.hit.f and fg[0] or self.color)
|
||||
graphics.rectangle(self.x, self.y, 4, 2*self.shape.h, 2, 2, self.hfx.hit.f and fg[0] or self.color)
|
||||
graphics.pop()
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
Turret = Object:extend()
|
||||
Turret:implement(GameObject)
|
||||
Turret:implement(Physics)
|
||||
|
@ -3038,9 +3195,9 @@ function Turret:init(args)
|
|||
HitCircle{group = main.current.effects, x = self.x, y = self.y}:scale_down()
|
||||
self.dead = true
|
||||
|
||||
if self.parent.summon_instability then
|
||||
if self.parent.construct_instability then
|
||||
camera:shake(2, 0.5)
|
||||
local n = (self.parent.summon_instability == 1 and 1) or (self.parent.summon_instability == 2 and 1.5) or (self.parent.summon_instability == 3 and 2) or 1
|
||||
local n = (self.parent.construct_instability == 1 and 1) or (self.parent.construct_instability == 2 and 1.5) or (self.parent.construct_instability == 3 and 2) or 1
|
||||
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*48, color = self.color, dmg = n*self.parent.dmg*self.parent.area_dmg_m, parent = self.parent}
|
||||
_G[random:table{'cannoneer1', 'cannoneer2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
end
|
||||
|
@ -3135,9 +3292,9 @@ function Pet:on_collision_enter(other, contact)
|
|||
else
|
||||
self.dead = true
|
||||
|
||||
if self.parent.summon_instability then
|
||||
if self.parent.construct_instability then
|
||||
camera:shake(2, 0.5)
|
||||
local n = (self.parent.summon_instability == 1 and 1) or (self.parent.summon_instability == 2 and 1.5) or (self.parent.summon_instability == 3 and 2) or 1
|
||||
local n = (self.parent.construct_instability == 1 and 1) or (self.parent.construct_instability == 2 and 1.5) or (self.parent.construct_instability == 3 and 2) or 1
|
||||
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*48, color = self.color, dmg = n*self.parent.dmg*self.parent.area_dmg_m, parent = self.parent}
|
||||
_G[random:table{'cannoneer1', 'cannoneer2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
end
|
||||
|
@ -3173,6 +3330,74 @@ end
|
|||
|
||||
|
||||
|
||||
Bomb = Object:extend()
|
||||
Bomb:implement(GameObject)
|
||||
Bomb:implement(Physics)
|
||||
function Bomb:init(args)
|
||||
self:init_game_object(args)
|
||||
self:set_as_rectangle(8, 8, 'static', 'player')
|
||||
self:set_restitution(0.5)
|
||||
self.hfx:add('hit', 1)
|
||||
|
||||
mine1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
self.color = orange[0]
|
||||
self.dmg = 2*get_character_stat('bomber', self.level, 'dmg')
|
||||
self.t:after(8, function() self:explode() end)
|
||||
end
|
||||
|
||||
|
||||
function Bomb:update(dt)
|
||||
self:update_game_object(dt)
|
||||
end
|
||||
|
||||
|
||||
function Bomb: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, 3, 3, self.hfx.hit.f and fg[0] or self.color)
|
||||
graphics.pop()
|
||||
end
|
||||
|
||||
|
||||
function Bomb:explode()
|
||||
camera:shake(4, 0.5)
|
||||
local t = {group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*64*(self.level == 3 and 2 or 1), color = self.color,
|
||||
dmg = self.parent.area_dmg_m*self.dmg*(self.parent.conjurer_buff_m or 1)*(self.level == 3 and 2 or 1), character = self.character, parent = self.parent}
|
||||
Area(table.merge(t, mods or {}))
|
||||
if not self.parent.construct_instability and not self.parent.rearm then self.dead = true end
|
||||
_G[random:table{'cannoneer1', 'cannoneer2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
_G[random:table{'saboteur_hit1', 'saboteur_hit2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
explosion1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
|
||||
self.t:after(0.25, function()
|
||||
if self.parent.construct_instability then
|
||||
camera:shake(2, 0.5)
|
||||
local n = (self.parent.construct_instability == 1 and 1) or (self.parent.construct_instability == 2 and 1.5) or (self.parent.construct_instability == 3 and 2) or 1
|
||||
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r + random:float(-math.pi/16, math.pi/16), w = self.parent.area_size_m*48*(self.level == 3 and 2 or 1), color = self.color,
|
||||
dmg = n*self.parent.dmg*self.parent.area_dmg_m*(self.level == 3 and 2 or 1), parent = self.parent}
|
||||
_G[random:table{'cannoneer1', 'cannoneer2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
self.dead = true
|
||||
end
|
||||
|
||||
if self.parent.rearm then
|
||||
camera:shake(2, 0.5)
|
||||
local n = (self.parent.construct_instability == 1 and 1) or (self.parent.construct_instability == 2 and 1.5) or (self.parent.construct_instability == 3 and 2) or 1
|
||||
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r + random:float(-math.pi/16, math.pi/16), w = self.parent.area_size_m*48*(self.level == 3 and 2 or 1), color = self.color,
|
||||
dmg = n*self.parent.dmg*self.parent.area_dmg_m*(self.level == 3 and 2 or 1), parent = self.parent}
|
||||
_G[random:table{'cannoneer1', 'cannoneer2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
self.dead = true
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
function Bomb:on_collision_enter(other, contact)
|
||||
if table.any(main.current.enemies, function(v) return other:is(v) end) then
|
||||
self:explode()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
Saboteur = Object:extend()
|
||||
Saboteur:implement(GameObject)
|
||||
|
@ -3232,10 +3457,10 @@ function Saboteur:on_collision_enter(other, contact)
|
|||
dmg = (self.crit and 2 or 1)*self.area_dmg_m*self.actual_dmg*(self.conjurer_buff_m or 1), character = self.character, parent = self.parent}
|
||||
Area(table.merge(t, mods or {}))
|
||||
|
||||
if self.parent.summon_instability then
|
||||
if self.parent.construct_instability then
|
||||
self.t:after(0.25, function()
|
||||
camera:shake(2, 0.5)
|
||||
local n = (self.parent.summon_instability == 1 and 1) or (self.parent.summon_instability == 2 and 1.5) or (self.parent.summon_instability == 3 and 2) or 1
|
||||
local n = (self.parent.construct_instability == 1 and 1) or (self.parent.construct_instability == 2 and 1.5) or (self.parent.construct_instability == 3 and 2) or 1
|
||||
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*48, color = self.color, dmg = n*self.parent.dmg*self.parent.area_dmg_m, parent = self.parent}
|
||||
_G[random:table{'cannoneer1', 'cannoneer2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
self.dead = true
|
||||
|
@ -3248,18 +3473,18 @@ end
|
|||
|
||||
|
||||
|
||||
Illusion = Object:extend()
|
||||
Illusion:implement(GameObject)
|
||||
Illusion:implement(Physics)
|
||||
Illusion:implement(Unit)
|
||||
function Illusion:init(args)
|
||||
Automaton = Object:extend()
|
||||
Automaton:implement(GameObject)
|
||||
Automaton:implement(Physics)
|
||||
Automaton:implement(Unit)
|
||||
function Automaton:init(args)
|
||||
self:init_game_object(args)
|
||||
self:init_unit()
|
||||
self:set_as_rectangle(8, 8, 'dynamic', 'player')
|
||||
self:set_restitution(0.5)
|
||||
|
||||
self.color = character_colors.illusionist
|
||||
self.character = 'illusionist'
|
||||
self.color = character_colors.artificer
|
||||
self.character = 'artificer'
|
||||
self.classes = {'sorcerer', 'conjurer'}
|
||||
self:calculate_stats(true)
|
||||
self:set_as_steerable(self.v, 2000, 4*math.pi, 4)
|
||||
|
@ -3268,10 +3493,12 @@ function Illusion:init(args)
|
|||
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
|
||||
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.05}
|
||||
turret1:play{pitch = random:float(0.95, 1.05), volume = 0.10}
|
||||
turret2:play{pitch = random:float(0.95, 1.05), volume = 0.10}
|
||||
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.10}
|
||||
local r = self:angle_to_object(closest_enemy)
|
||||
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.parent.color, dmg = self.parent.dmg, character = 'illusionist',
|
||||
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.parent.color, dmg = self.parent.dmg, character = 'artificer',
|
||||
parent = self.parent, level = self.parent.level}
|
||||
Projectile(table.merge(t, mods or {}))
|
||||
end
|
||||
|
@ -3280,10 +3507,12 @@ function Illusion:init(args)
|
|||
self.t:after(0.25, function()
|
||||
local closest_enemy = self:get_closest_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||
if closest_enemy then
|
||||
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.05}
|
||||
turret1:play{pitch = random:float(0.95, 1.05), volume = 0.10}
|
||||
turret2:play{pitch = random:float(0.95, 1.05), volume = 0.10}
|
||||
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.10}
|
||||
local r = self:angle_to_object(closest_enemy)
|
||||
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.parent.color, dmg = self.parent.dmg, character = 'illusionist',
|
||||
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.parent.color, dmg = self.parent.dmg, character = 'artificer',
|
||||
parent = self.parent, level = self.parent.level}
|
||||
Projectile(table.merge(t, mods or {}))
|
||||
end
|
||||
|
@ -3301,7 +3530,7 @@ function Illusion:init(args)
|
|||
end
|
||||
end, nil, nil, 'shoot')
|
||||
|
||||
self.t:after(12*(self.parent.conjurer_buff_m or 1), function()
|
||||
self.t:after(18*(self.parent.conjurer_buff_m or 1), function()
|
||||
local n = n or random:int(3, 4)
|
||||
for i = 1, n do HitParticle{group = main.current.effects, x = self.x, y = self.y, r = random:float(0, 2*math.pi), color = self.color} end
|
||||
HitCircle{group = main.current.effects, x = self.x, y = self.y}:scale_down()
|
||||
|
@ -3310,14 +3539,14 @@ function Illusion:init(args)
|
|||
if self.parent.level == 3 then
|
||||
shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.2}
|
||||
for i = 1, 12 do
|
||||
Projectile{group = main.current.main, x = self.x, y = self.y, color = self.color, r = (i-1)*math.pi/6, v = 200, dmg = self.parent.dmg, character = 'illusionist_death',
|
||||
Projectile{group = main.current.main, x = self.x, y = self.y, color = self.color, r = (i-1)*math.pi/6, v = 200, dmg = self.parent.dmg, character = 'artificer_death',
|
||||
parent = self.parent, level = self.parent.level, pierce = 1, ricochet = 1}
|
||||
end
|
||||
end
|
||||
|
||||
if self.parent.summon_instability then
|
||||
if self.parent.construct_instability then
|
||||
camera:shake(2, 0.5)
|
||||
local n = (self.parent.summon_instability == 1 and 1) or (self.parent.summon_instability == 2 and 1.5) or (self.parent.summon_instability == 3 and 2) or 1
|
||||
local n = (self.parent.construct_instability == 1 and 1) or (self.parent.construct_instability == 2 and 1.5) or (self.parent.construct_instability == 3 and 2) or 1
|
||||
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*48, color = self.color, dmg = n*self.parent.dmg*self.parent.area_dmg_m, parent = self.parent}
|
||||
_G[random:table{'cannoneer1', 'cannoneer2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
end
|
||||
|
@ -3325,7 +3554,7 @@ function Illusion:init(args)
|
|||
end
|
||||
|
||||
|
||||
function Illusion:update(dt)
|
||||
function Automaton:update(dt)
|
||||
self:update_game_object(dt)
|
||||
|
||||
self:calculate_stats()
|
||||
|
@ -3346,11 +3575,12 @@ function Illusion:update(dt)
|
|||
end
|
||||
self.r = self:get_angle()
|
||||
|
||||
self.t:set_every_multiplier('shoot', self.parent.level == 3 and 0.75 or 1)
|
||||
self.attack_sensor:move_to(self.x, self.y)
|
||||
end
|
||||
|
||||
|
||||
function Illusion:draw()
|
||||
function Automaton: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, 3, 3, self.hfx.hit.f and fg[0] or self.color)
|
||||
graphics.pop()
|
||||
|
|
53
todo
|
@ -1,24 +1,24 @@
|
|||
Loop Update
|
||||
New items:
|
||||
General:
|
||||
Intimidation - enemies spawn with -10/20/30% max HP
|
||||
Vulnerability - enemies take +10/20/30% damage
|
||||
Ceremonial Dagger - killing an enemy fires a homing dagger
|
||||
Homing Barrage - X/Y/Z% chance to release a homing barrage on enemy kill
|
||||
Critical Strike - X/Y/Z% chance for attacks to critically strike, dealing 2x damage
|
||||
Noxious Strike - X/Y/Z% chance for attacks to poison enemies, dealing 20% damage per second for 3 seconds
|
||||
Infesting Strike - X/Y/Z% chance for attacks to spawn 2 critters on kill
|
||||
Kinetic Strike - X/Y/Z% chance for attacks to push enemies away with high force
|
||||
Burning Strike - X% chance for attacks to ignite, dealing 20% dps for 3 seconds, ignited enemies ignite nearby enemies on death
|
||||
Lucky Strike - X% chance for attacks to cause enemies to drop gold on death
|
||||
Healing Strike - X% chance for attacks to spawn a healing orb on kill
|
||||
Stunning Strike - X/Y/Z% chance for attacks to stun for 2 seconds
|
||||
Silencing Strike - X/Y/Z% chance for attacks to silence on hit
|
||||
Warping Shots - X/Y/Z% chance for projectiles to ignore wall collisions and warp around the screen 1/2/3 times
|
||||
Culling Strike - instantly kill elites below 10/20/30% max HP
|
||||
Lightning Strike - X/Y/Z% chance for attacks to create chain lightning, dealing 60/80/100% damage and hitting 2/3/4 enemies
|
||||
Psycholeak - Position X generates 1 additional orb every Y seconds
|
||||
Divine Blessing - generate 1 healing orb every X seconds
|
||||
* Intimidation - enemies spawn with -10/20/30% max HP
|
||||
* Vulnerability - enemies take +10/20/30% damage
|
||||
* Temporal Chains - enemies are 10/20/30% slower
|
||||
* Ceremonial Dagger - killing an enemy fires a homing dagger
|
||||
* Homing Barrage - 8/16/24% chance to release a homing barrage on enemy kill
|
||||
* Critical Strike - 5/10/15% chance for attacks to critically strike, dealing 2x damage
|
||||
* Noxious Strike - 8/16/24% chance for attacks to poison enemies, dealing 20% dps for 3 seconds
|
||||
* Infesting Strike - 10/20/30% chance for attacks to spawn 2 critters on kill
|
||||
* Kinetic Strike - 10/20/30% chance for attacks to push enemies away with high force
|
||||
* Burning Strike - 15% chance for attacks to ignite, dealing 20% dps for 3 seconds
|
||||
* Lucky Strike - 8% chance for attacks to cause enemies to drop gold on death
|
||||
* Healing Strike - 8% chance for attacks to spawn a healing orb on kill
|
||||
* Stunning Strike - 8/16/24% chance for attacks to stun for 2 seconds
|
||||
* Silencing Strike - 8/16/24% chance for attacks to silence for 4 seconds on hit
|
||||
* Culling Strike - instantly kill elites below 10/20/30% max HP
|
||||
* Lightning Strike - 5/10/15% chance for projectiles to create chain lightning, dealing 60/80/100% damage
|
||||
* Psycholeak - Position 1 generates 1 psyker orb every 10 seconds
|
||||
* Divine Blessing - generate 1 healing orb every 8 seconds
|
||||
Psyker
|
||||
Additional orbs will prefer to be assigned to psykers, if there are no psykers then they will be assigned randomly
|
||||
Orb speed scales with the unit's attack speed
|
||||
|
@ -35,12 +35,15 @@ Loop Update
|
|||
Increases amount of orbs dropped with only 1 or 2 healers
|
||||
Decreases amount of orbs dropped on full build
|
||||
Healing orbs are slightly attracted to the snake
|
||||
Warriors
|
||||
Increase sensor range
|
||||
Set juggernaut and barbarian's attacks on :cooldown calls
|
||||
Builders
|
||||
Carver (builder, healer) - every 12 seconds, creates a tree that drops 3 healing orbs, Lv.3 effect: drops 6 healing orbs instead
|
||||
Engineer (builder) - unchanged
|
||||
Illusionist -> Golemancer (builder, sorcerer): spawns 1 golem every 6 seconds, it shoots 2 rocks that deal X damage each, Lv.3 effect: golem rocks stun enemies for 2 seconds
|
||||
Saboteur -> Bomber (builder, nuker): plants a static bomb, when it explodes it deals 2X AoE damage, Lv.3 effect: 100% increased bomb area and damage
|
||||
Hunter (builder, ranger, forcer): shoots a projectile that has 20% chance to spawn a pet, Lv.3 effect: spawns 3 pets instead
|
||||
* Carver (builder, healer) - creates a tree that creates 1 healing orb every 6 seconds, Lv.3 effect: healing orbs are created twice as fast
|
||||
* Engineer (builder): unchanged
|
||||
* Illusionist -> Artificer (builder, sorcerer): unchanged
|
||||
* Saboteur -> Bomber (builder, nuker): plants a bomb, when it explodes it deals 2X AoE damage, Lv.3 effect: +100% bomb area and damage
|
||||
* Hunter -> Sentry (builder, ranger): spawns a turret that shoots projectiles, each dealing X damage, Lv.3 effect: +50% attack speed and the projectiles ricochet twice
|
||||
Looping
|
||||
* Change end screen
|
||||
* Loop button on end screen
|
||||
|
@ -53,14 +56,14 @@ Loop Update
|
|||
Add option for mouse cursor to always be visible
|
||||
Show cooldown on elite attack
|
||||
Add visuals divine intervention, fairy buff
|
||||
warrior attack range
|
||||
barbarian jugg attack
|
||||
Party + items on death screen
|
||||
* Silenced units are now gray
|
||||
* Items on end screen
|
||||
* Items on passive screen
|
||||
* Selling items
|
||||
* Decreased sound effect volume for shoot 5
|
||||
Bug fixes
|
||||
Fix stars
|
||||
* Fixed a series of crashes that happened sometimes right before changing from the arena back to the shop
|
||||
* Fixed merchant not giving interest or free reroll if it died in combat
|
||||
* Fixed shoot 5 and death 6 not working if a unit placed before it on the snake died
|
||||
|
|