master
a327ex 2021-04-19 22:04:53 -03:00
parent e74d8b44eb
commit 1008e91531
4 changed files with 263 additions and 46 deletions

View File

@ -970,3 +970,30 @@ than the characters since I made sure to pick types of passives that were alread
Finished literally everything needed to make passives work, now I only need to actually make them. The more I work on this the clearer the parts that slow me down because they're annoying to work with
become. Generally it's higher level "glue" type of code, rather than the code that actually makes the thing work as a unit. So the node refactor for instance is addressing a lot of this glue code by making it conceptually the same
thing, which should make it easier to work with. The rect cutting UI idea does something similar the high level part of UI, which tends to be mostly layouting. And so on.
# Day 62 - 19/04/21
20 out of 40 passives done today.
| Name | Description |
| --- | --- |
| Ouroboros Technique R | rotating around yourself to the right makes units release projectiles |
| Ouroboros Technique L | rotating around yourself to the left grants +25% defense to all units |
| Wall Echo | hitting walls has a 34% chance of releasing 2 projectiles |
| Wall Rider | hitting walls grants a 25% movement speed buff for 1 second |
| Centipede | +20% movement speed |
| Intimidation | enemies spawn with -20% max HP |
| Vulnerability | enemies take +20% damage |
| Temporal Chains | all enemies move 20% slower |
| Amplify | +25% AoE damage |
| Amplify X | +50% AoE damage |
| Resonance | all AoE attacks deal +5% damage per enemy hit |
| Ballista | +25% damage to rangers and rogues |
| Ballista X | +50% damage to rangers and rogues |
| Point Blank | projectiles deal up to +100% damage up close and down to -50% damage far away |
| Longshot | projectiles deal up to +100% damage far away and down to -50% damage up close |
| Blunt Arrow | all arrows fired by rangers have a 20% chance to knockback |
| Explosive Arrow | all arrows fired by rangers have a 30% chance to explode, dealing 20% AoE damage |
| Divine Machine Arrow | all arrows fired by rangers have a 40% chance to seek enemies and pierce 5 times |
| Chronomancy | all mages cast their spells 25% faster |
| Awakening | every round 1 mage is granted +100% cast speed and damage for that round |

View File

@ -216,6 +216,21 @@ function Seeker:init(args)
elseif self.spawner then
self.color = purple[0]:clone()
end
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:calculate_stats()
self.hp = self.max_hp
end
if player and player.vulnerability then
self.vulnerable = true
end
if player and player.temporal_chains then
self.temporal_chains_mvspd_m = 0.8
end
end
@ -239,7 +254,7 @@ function Seeker:update(dt)
if self.slowed then self.slow_mvspd_m = self.slowed
else self.slow_mvspd_m = 1 end
self.buff_mvspd_m = (self.speed_boosting_mvspd_m or 1)*(self.slow_mvspd_m or 1)
self.buff_mvspd_m = (self.speed_boosting_mvspd_m or 1)*(self.slow_mvspd_m or 1)*(self.temporal_chains_mvspd_m or 1)
self:calculate_stats()
@ -366,7 +381,9 @@ function Seeker:hit(damage, projectile)
self:show_hp()
local actual_damage = self:calculate_damage(damage)*self.stun_dmg_m*self.bane_dmg_m
if self.vulnerable then actual_damage = actual_damage*1.2 end
self.hp = self.hp - actual_damage
print(actual_damage)
main.current.damage_dealt = main.current.damage_dealt + actual_damage
if projectile and projectile.spawn_critters_on_hit then

View File

@ -938,22 +938,22 @@ function init()
passive_descriptions = {
['ouroboros_technique_r'] = '[fg]rotating around yourself to the right makes units release projectiles',
['ouroboros_technique_l'] = '[fg]rotating around yourself to the left grants [yellow]+25%[fg] defense to all units',
['wall_echo'] = '[fg]hitting walls has a [yellow]25%[fg] chance of releasing [yellow]2[fg] projectiles',
['wall_echo'] = '[fg]hitting walls has a [yellow]34%[fg] chance of releasing [yellow]2[fg] projectiles',
['wall_rider'] = '[fg]hitting walls grants a [yellow]25%[fg] movement speed buff to your snake for [yellow]1[fg] second',
['centipede'] = '[yellow]+20%[fg] movement speed',
['intimidation'] = '[fg]enemies spawn with [yellow]-20%[fg] max HP',
['vulnerability'] = '[fg]all enemies take [yellow]+20%[fg] damage',
['temporal_chains'] = '[fg]all enemies move [yellow]20%[fg] slower',
['amplify'] = '[fg]all units that deal AoE damage gain [yellow]+25%[fg] AoE damage',
['amplify_x'] = '[yellow]+25%[fg] AoE damage if all your units only deal AoE damage',
['amplify'] = '[yellow]+25%[fg] AoE damage',
['amplify_x'] = '[yellow]+50%[fg] AoE damage',
['resonance'] = '[fg]all AoE attacks deal [yellow]+5%[fg] damage per unit hit',
['ballista'] = "[fg]all units that release projectiles and don't deal AoE damage gain [yellow]+25%[fg] damage",
['ballista_x'] = "[yellow]+25%[fg] damage if all your units only release projectiles and don't deal AoE damage",
['ballista'] = '[yellow]+25%[fg] damage to rangers and rogues ',
['ballista_x'] = '[yellow]+50%[fg] damage to rangers and rogues',
['point_blank'] = '[fg]projectiles deal up to [yellow]+100%[fg] damage up close and down to [yellow]-50%[fg] damage far away',
['longshot'] = '[fg]projectiles deal up to [yellow]+100%[fg] damage far away and down to [yellow]-50%[fg] up close',
['blunt_arrow'] = '[fg]all arrows fired by rangers have a [yellow]20%[fg] chance to knockback',
['explosive_arrow'] = '[fg]arrows fired by rangers have a [yellow]20%[fg] chance to explode, dealing [yellow]20%[fg] AoE damage',
['divine_machine_arrow'] = '[fg]arrows fired by rangers have a [yellow]20%[fg] chance to seek enemies and pierce [yellow]5[fg] times',
['explosive_arrow'] = '[fg]arrows fired by rangers have a [yellow]30%[fg] chance to explode, dealing [yellow]20%[fg] AoE damage',
['divine_machine_arrow'] = '[fg]arrows fired by rangers have a [yellow]40%[fg] chance to seek enemies and pierce [yellow]5[fg] times',
['chronomancy'] = '[fg]all mages cast their spells [yellow]25%[fg] faster',
['awakening'] = '[fg]every round [yellow]1[fg] mage is granted [yellow]+100%[fg] attack speed and damage for that round',
['divine_punishment'] = '[fg]periodically deal [yellow]10X[fg] damage to all enemies, where [yellow]X[fg] is how many mages you have',
@ -990,10 +990,10 @@ function init()
['vulnerability'] = 2,
['temporal_chains'] = 1,
['amplify'] = 1,
['amplify_x'] = 1,
['resonance'] = 2,
['amplify_x'] = 2,
['resonance'] = 3,
['ballista'] = 1,
['ballista_x'] = 1,
['ballista_x'] = 2,
['point_blank'] = 2,
['longshot'] = 2,
['blunt_arrow'] = 1,
@ -1044,12 +1044,59 @@ function init()
[24] = {20, 30, 50},
}
--[[
* ['ouroboros_technique_r'] = 2,
* ['ouroboros_technique_l'] = 2,
* ['wall_echo'] = 1,
* ['wall_rider'] = 1,
* ['centipede'] = 1,
* ['intimidation'] = 2,
* ['vulnerability'] = 2,
* ['temporal_chains'] = 1,
* ['amplify'] = 1,
* ['amplify_x'] = 1,
* ['resonance'] = 2,
* ['ballista'] = 1,
* ['ballista_x'] = 1,
* ['point_blank'] = 2,
* ['longshot'] = 2,
* ['blunt_arrow'] = 1,
* ['explosive_arrow'] = 2,
* ['divine_machine_arrow'] = 3,
* ['chronomancy'] = 2,
* ['awakening'] = 2,
['divine_punishment'] = 3,
['berserking'] = 1,
['unwavering_stance'] = 1,
['ultimatum'] = 2,
['flying_daggers'] = 3,
['assassination'] = 1,
['magnify'] = 1,
['concentrated_fire'] = 2,
['unleash'] = 1,
['reinforce'] = 2,
['payback'] = 2,
['blessing'] = 1,
['hex_master'] = 1,
['whispers_of_doom'] = 2,
['force_push'] = 1,
['heavy_impact'] = 2,
['crucio'] = 3,
['immolation'] = 2,
['call_of_the_void'] = 2,
['spawning_pool'] = 1,
['hive'] = 3,
]]--
gold = 2
passives = {'ouroboros_technique_r'}
passives = {'awakening'}
main = Main()
main:add(BuyScreen'buy_screen')
main:go_to('buy_screen', 2, {
{character = 'wizard', level = 1},
{character = 'spellblade', level = 1},
--[[
{character = 'swordsman', level = 3},
{character = 'wizard', level = 3},
{character = 'scout', level = 3},
@ -1062,6 +1109,7 @@ function init()
{character = 'juggernaut', level = 3},
{character = 'vagrant', level = 3},
{character = 'stormweaver', level = 3},
]]--
}, passives)
--[[
main:add(Arena'arena')

View File

@ -6,7 +6,7 @@ function Player:init(args)
self:init_game_object(args)
self:init_unit()
for k, v in pairs(self.passives) do self[v] = true end
if self.passives then for k, v in pairs(self.passives) do self[v] = true end end
self.color = character_colors[self.character]
self:set_as_rectangle(9, 9, 'dynamic', 'player')
@ -439,21 +439,61 @@ function Player:init(args)
if self.ouroboros_technique_r then
self.t:every(0.1, function()
if self.move_right_pressed and love.timer.getTime() - self.move_right_pressed > 1 then
local units = self:get_all_units()
local cx, cy = 0, 0
for _, unit in ipairs(units) do
cx = cx + unit.x
cy = cy + unit.y
local target = self:get_closest_object_in_shape(Circle(self.x, self.y, 96), main.current.enemies)
if target then
local units = self:get_all_units()
local unit = random:table(units)
unit:barrage(unit:angle_to_object(target), 1)
else
local units = self: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
local unit = random:table(units)
unit:barrage(unit:angle_from_point(cx, cy), 1)
end
cx = cx/#units
cy = cy/#units
local unit = random:table(units)
unit:barrage(unit:angle_from_point(cx, cy), 1)
end
end)
end
self.first_frame_calculate_stats = true
if self.centipede then self.centipede_mvspd_m = 1.2 end
if self.amplify then self.amplify_area_dmg_m = 1.25 end
if self.amplify_x then self.amplify_x_area_dmg_m = 1.5 end
if self.ballista then
if table.any(self.classes, function(v) return v == 'ranger' end) or table.any(self.classes, function(v) return v == 'rogue' end) then
self.ballista_dmg_m = 1.25
end
end
if self.ballista_x then
if table.any(self.classes, function(v) return v == 'ranger' end) or table.any(self.classes, function(v) return v == 'rogue' end) then
self.ballista_x_dmg_m = 1.5
end
end
if self.chronomancy then
if table.any(self.classes, function(v) return v == 'mage' end) then
self.chronomancy_aspd_m = 1.25
end
end
if self.leader and self.awakening then
local units = self:get_all_units()
local mages = {}
for _, unit in ipairs(units) do
if table.any(unit.classes, function(v) return v == 'mage' end) then
table.insert(mages, unit)
end
end
local mage = random:table(mages)
mage.awakening_aspd_m = 2
mage.awakening_dmg_m = 2
end
end
@ -573,12 +613,26 @@ function Player:update(dt)
else self.dot_dmg_m = 1 end
end
if self.ouroboros_technique_l and self.leader then
local units = self:get_all_units()
if self.move_left_pressed and love.timer.getTime() - self.move_left_pressed > 1 then
for _, unit in ipairs(units) do
unit.ouroboros_def_m = 1.25
end
else
for _, unit in ipairs(units) do
unit.ouroboros_def_m = 1
end
end
end
self.buff_def_a = (self.warrior_def_a or 0)
self.buff_aspd_m = (self.chronomancer_aspd_m or 1)*(self.vagrant_aspd_m or 1)*(self.outlaw_aspd_m or 1)*(self.fairy_aspd_m or 1)*(self.psyker_aspd_m or 1)
self.buff_dmg_m = (self.squire_dmg_m or 1)*(self.vagrant_dmg_m or 1)*(self.enchanter_dmg_m or 1)*(self.swordsman_dmg_m or 1)*(self.flagellant_dmg_m or 1)*(self.psyker_dmg_m or 1)
self.buff_def_m = (self.squire_def_m or 1)
self.buff_aspd_m = (self.chronomancer_aspd_m or 1)*(self.vagrant_aspd_m or 1)*(self.outlaw_aspd_m or 1)*(self.fairy_aspd_m or 1)*(self.psyker_aspd_m or 1)*(self.chronomancy_aspd_m or 1)*(self.awakening_aspd_m or 1)
self.buff_dmg_m = (self.squire_dmg_m or 1)*(self.vagrant_dmg_m or 1)*(self.enchanter_dmg_m or 1)*(self.swordsman_dmg_m or 1)*(self.flagellant_dmg_m or 1)*(self.psyker_dmg_m or 1)*(self.ballista_dmg_m or 1)*(self.ballista_x_dmg_m or 1)*(self.awakening_dmg_m or 1)
self.buff_def_m = (self.squire_def_m or 1)*(self.ouroboros_def_m or 1)
self.buff_area_size_m = (self.nuker_area_size_m or 1)
self.buff_area_dmg_m = (self.nuker_area_dmg_m or 1)
self.buff_area_dmg_m = (self.nuker_area_dmg_m or 1)*(self.amplify_area_dmg_m or 1)*(self.amplify_x_area_dmg_m or 1)
self.buff_mvspd_m = (self.wall_rider_mvspd_m or 1)*(self.centipede_mvspd_m or 1)
self:calculate_stats()
if self.attack_sensor then self.attack_sensor:move_to(self.x, self.y) end
@ -593,7 +647,15 @@ function Player:update(dt)
if input.move_right.released then self.move_right_pressed = nil end
if input.move_left.down then self.r = self.r - 1.66*math.pi*dt end
if input.move_right.down then self.r = self.r + 1.66*math.pi*dt end
self:set_velocity(self.v*math.cos(self.r), self.v*math.sin(self.r))
local total_v = 0
local units = self:get_all_units()
for _, unit in ipairs(units) do
total_v = total_v + unit.max_v
end
total_v = total_v/#units
self:set_velocity(total_v*math.cos(self.r), total_v*math.sin(self.r))
if not main.current.won and not main.current.choosing_passives then
local vx, vy = self:get_velocity()
@ -672,6 +734,26 @@ function Player:on_collision_enter(other, contact)
pop1:play{pitch = r + 0.05*i, volume = 0.2}
end)
end
if self.wall_echo then
if random:bool(34) then
local target = self:get_closest_object_in_shape(Circle(self.x, self.y, 96), main.current.enemies)
if target then
self:barrage(self:angle_to_object(target), 2)
else
local r = Vector(contact:getNormal()):angle()
self:barrage(r, 2)
end
end
end
if self.wall_rider then
local units = self:get_all_units()
for _, unit in ipairs(units) do unit.wall_rider_mvspd_m = 1.25 end
trigger:after(1, function()
for _, unit in ipairs(units) do unit.wall_rider_mvspd_m = 1 end
end, 'wall_rider')
end
end
elseif table.any(main.current.enemies, function(v) return other:is(v) end) then
@ -1065,6 +1147,13 @@ function Projectile:init(args)
end)
end
if self.parent.divine_machine_arrow and table.any(self.parent.classes, function(v) return v == 'ranger' end) then
if random:bool(40) then
self.homing = true
self.pierce = 5
end
end
if self.homing then
self.homing = false
self.t:after(0.1, function()
@ -1072,6 +1161,15 @@ function Projectile:init(args)
self.closest_sensor = Circle(self.x, self.y, 64)
end)
end
self.distance_travelled = 0
self.distance_dmg_m = 1
if self.parent.blunt_arrow and table.any(self.parent.classes, function(v) return v == 'ranger' end) then
if random:bool(20) then
self.knockback = 10
end
end
end
@ -1098,7 +1196,6 @@ function Projectile:update(dt)
self:move_along_angle(self.v, self.r + (self.orbit_r or 0))
end
if self.character == 'sage' then
self.pull_sensor:move_to(self.x, self.y)
local enemies = self:get_objects_in_shape(self.pull_sensor, main.current.enemies)
@ -1107,6 +1204,17 @@ function Projectile:update(dt)
end
self.vr = self.vr + self.dvr*dt
end
if self.parent.point_blank or self.parent.longshot then
self.distance_travelled = self.distance_travelled + math.length(self:get_velocity())
if self.parent.point_blank and self.parent.longshot then
self.distance_dmg_m = 1
elseif self.parent.point_blank then
self.distance_dmg_m = math.remap(self.distance_travelled, 0, 15000, 2, 0.75)
elseif self.parent.longshot then
self.distance_dmg_m = math.remap(self.distance_travelled, 0, 15000, 0.75, 2)
end
end
end
@ -1144,16 +1252,18 @@ function Projectile:die(x, y, r, n)
self.dead = true
if self.character == 'wizard' then
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*32, color = self.color, dmg = self.parent.area_dmg_m*self.dmg, character = self.character, level = self.level}
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*32, color = self.color, dmg = self.parent.area_dmg_m*self.dmg, character = self.character, level = self.level, parent = self}
elseif self.character == 'blade' then
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*64, color = self.color, dmg = self.parent.area_dmg_m*self.dmg, character = self.character, level = self.level}
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*64, color = self.color, dmg = self.parent.area_dmg_m*self.dmg, character = self.character, level = self.level, parent = self}
elseif self.character == 'cannoneer' then
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*96, color = self.color, dmg = 2*self.parent.area_dmg_m*self.dmg, character = self.character, level = self.level}
self.parent.t:every(0.2, function()
_G[random:table{'cannoneer1', 'cannoneer2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
Area{group = main.current.effects, x = self.x + random:float(-32, 32), y = self.y + random:float(-32, 32), r = self.r + random:float(0, 2*math.pi), w = self.parent.area_size_m*48, color = self.color,
dmg = 0.5*self.parent.area_dmg_m*self.dmg, character = self.character, level = self.level}
end, 5)
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*96, color = self.color, dmg = 2*self.parent.area_dmg_m*self.dmg, character = self.character, level = self.level, parent = self}
if self.level == 3 then
self.parent.t:every(0.2, function()
_G[random:table{'cannoneer1', 'cannoneer2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
Area{group = main.current.effects, x = self.x + random:float(-32, 32), y = self.y + random:float(-32, 32), r = self.r + random:float(0, 2*math.pi), w = self.parent.area_size_m*48, color = self.color,
dmg = 0.5*self.parent.area_dmg_m*self.dmg, character = self.character, level = self.level, parent = self}
end, 5)
end
end
end
@ -1251,10 +1361,10 @@ function Projectile:on_trigger_enter(other, contact)
hit3:play{pitch = random:float(0.95, 1.05), volume = 0.35}
end
other:hit(self.dmg, self)
other:hit(self.dmg*(self.distance_dmg_m or 1), self)
if self.character == 'wizard' and self.level == 3 then
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*32, color = self.color, dmg = self.parent.area_dmg_m*self.dmg, character = self.character}
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*32, color = self.color, dmg = self.parent.area_dmg_m*self.dmg, character = self.character, parent = self}
end
if self.character == 'hunter' and random:bool(40) then
@ -1297,7 +1407,7 @@ function Projectile:on_trigger_enter(other, contact)
table.insert(self.infused_enemies_hit, src)
local dst = src:get_random_object_in_shape(Circle(src.x, src.y, (stormweaver_level == 3 and 128 or 64)), main.current.enemies, self.infused_enemies_hit)
if dst then
dst:hit(0.2*self.dmg)
dst:hit(0.2*self.dmg*(self.distance_dmg_m or 1))
LightningLine{group = main.current.effects, src = src, dst = dst}
src = dst
end
@ -1316,6 +1426,14 @@ function Projectile:on_trigger_enter(other, contact)
if self.knockback then
other:push(self.knockback*(self.knockback_m or 1), self.r)
end
if self.parent.explosive_arrow and table.any(self.parent.classes, function(v) return v == 'ranger' end) then
if random:bool(30) then
_G[random:table{'cannoneer1', 'cannoneer2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r + random:float(0, 2*math.pi), w = self.parent.area_size_m*32, color = self.color,
dmg = 0.2*self.parent.area_dmg_m*self.dmg, character = self.character, level = self.level, parent = self}
end
end
end
end
@ -1329,21 +1447,28 @@ function Area:init(args)
self.shape = Rectangle(self.x, self.y, 1.5*self.w, 1.5*self.w, self.r)
local enemies = main.current.main:get_objects_in_shape(self.shape, main.current.enemies)
for _, enemy in ipairs(enemies) do
local resonance_dmg = 0
if self.character == 'elementor' then
enemy:hit(2*self.dmg)
if self.parent.resonance then resonance_dmg = 2*self.dmg*0.05*#enemies end
enemy:hit(2*self.dmg + resonance_dmg)
if self.level == 3 then
enemy:slow(0.4, 6)
end
elseif self.character == 'swordsman' then
enemy:hit(self.dmg + self.dmg*0.33*#enemies)
if self.parent.resonance then resonance_dmg = (self.dmg + self.dmg*0.33*#enemies)*0.05*#enemies end
enemy:hit(self.dmg + self.dmg*0.33*#enemies + resonance_dmg)
elseif self.character == 'blade' and self.level == 3 then
enemy:hit(self.dmg + self.dmg*0.5*#enemies)
if self.parent.resonance then resonance_dmg = (self.dmg + self.dmg*0.5*#enemies)*0.05*#enemies end
enemy:hit(self.dmg + self.dmg*0.5*#enemies + resonance_dmg)
elseif self.character == 'highlander' then
enemy:hit(6*self.dmg)
if self.parent.resonance then resonance_dmg = 6*self.dmg*0.05*#enemies end
enemy:hit(6*self.dmg + resonance_dmg)
elseif self.character == 'launcher' then
enemy:curse('launcher', 4, (self.level == 3 and 6*self.dmg or 2*self.dmg), self.parent)
if self.parent.resonance then resonance_dmg = (self.level == 3 and 6*self.dmg*0.05*#enemies or 2*self.dmg*0.05*#enemies) end
enemy:curse('launcher', 4, (self.level == 3 and 6*self.dmg or 2*self.dmg) + resonance_dmg, self.parent)
else
enemy:hit(self.dmg)
if self.parent.resonance then resonance_dmg = self.dmg*0.05*#enemies end
enemy:hit(self.dmg + resonance_dmg)
end
HitCircle{group = main.current.effects, x = enemy.x, y = enemy.y, rs = 6, color = fg[0], duration = 0.1}
for i = 1, 1 do HitParticle{group = main.current.effects, x = enemy.x, y = enemy.y, color = self.color} end