SNKRX/objects.lua

398 lines
12 KiB
Lua
Raw Normal View History

2021-03-31 00:46:27 +02:00
SpawnMarker = Object:extend()
SpawnMarker:implement(GameObject)
function SpawnMarker:init(args)
self:init_game_object(args)
self.color = red[0]
self.r = random:float(0, 2*math.pi)
self.spring:pull(random:float(0.4, 0.6), 200, 10)
self.t:after(0.75, function() self.dead = true end)
self.m = 1
self.n = 0
pop3:play{pitch = 1, volume = 0.15}
2021-05-03 07:04:40 +02:00
self.t:every({0.13, 0.16}, function()
2021-03-31 00:46:27 +02:00
self.hidden = not self.hidden
self.m = self.m*random:float(0.84, 0.87)
end, nil, nil, 'blink')
end
function SpawnMarker:update(dt)
self:update_game_object(dt)
self.t:set_every_multiplier('blink', self.m)
end
function SpawnMarker:draw()
if self.hidden then return end
graphics.push(self.x, self.y, self.r, self.spring.x, self.spring.x)
graphics.push(self.x, self.y, self.r + math.pi/4)
graphics.rectangle(self.x, self.y, 24, 6, 4, 4, self.color)
graphics.pop()
graphics.push(self.x, self.y, self.r + 3*math.pi/4)
graphics.rectangle(self.x, self.y, 24, 6, 4, 4, self.color)
graphics.pop()
graphics.pop()
end
2021-02-24 06:47:22 +01:00
LightningLine = Object:extend()
LightningLine:implement(GameObject)
function LightningLine:init(args)
self:init_game_object(args)
self.lines = {}
table.insert(self.lines, {x1 = self.src.x, y1 = self.src.y, x2 = self.dst.x, y2 = self.dst.y})
self.w = 3
2021-04-21 04:39:41 +02:00
self.generations = args.generations or 3
self.max_offset = args.max_offset or 8
2021-02-24 06:47:22 +01:00
self:generate()
2021-04-21 04:39:41 +02:00
self.t:tween(self.duration or 0.1, self, {w = 1}, math.linear, function() self.dead = true end)
2021-04-02 03:59:26 +02:00
self.color = args.color or blue[0]
2021-04-21 04:39:41 +02:00
HitCircle{group = main.current.effects, x = self.src.x, y = self.src.y, rs = 6, color = fg[0], duration = self.duration or 0.1}
2021-04-02 03:59:26 +02:00
for i = 1, 2 do HitParticle{group = main.current.effects, x = self.src.x, y = self.src.y, color = self.color} end
2021-04-21 04:39:41 +02:00
HitCircle{group = main.current.effects, x = self.dst.x, y = self.dst.y, rs = 6, color = fg[0], duration = self.duration or 0.1}
2021-04-02 03:59:26 +02:00
HitParticle{group = main.current.effects, x = self.dst.x, y = self.dst.y, color = self.color}
2021-02-24 06:47:22 +01:00
end
function LightningLine:update(dt)
self:update_game_object(dt)
end
function LightningLine:draw()
graphics.polyline(self.color, self.w, unpack(self.points))
end
function LightningLine:generate()
local offset_amount = self.max_offset
local lines = self.lines
for j = 1, self.generations do
for i = #self.lines, 1, -1 do
local x1, y1 = self.lines[i].x1, self.lines[i].y1
local x2, y2 = self.lines[i].x2, self.lines[i].y2
table.remove(self.lines, i)
local x, y = (x1+x2)/2, (y1+y2)/2
local p = Vector(x2-x1, y2-y1):normalize():perpendicular()
x = x + p.x*random:float(-offset_amount, offset_amount)
y = y + p.y*random:float(-offset_amount, offset_amount)
table.insert(self.lines, {x1 = x1, y1 = y1, x2 = x, y2 = y})
table.insert(self.lines, {x1 = x, y1 = y, x2 = x2, y2 = y2})
end
offset_amount = offset_amount/2
end
self.points = {}
while #self.lines > 0 do
local min_d, min_i = 1000000, 0
for i, line in ipairs(self.lines) do
local d = math.distance(self.src.x, self.src.y, line.x1, line.y1)
if d < min_d then
min_d = d
min_i = i
end
end
local line = table.remove(self.lines, min_i)
2021-05-17 10:05:48 +02:00
if line then
table.insert(self.points, line.x1)
table.insert(self.points, line.y1)
end
2021-02-24 06:47:22 +01:00
end
end
2021-02-22 03:54:50 +01:00
WallKnife = Object:extend()
WallKnife:implement(GameObject)
WallKnife:implement(Physics)
function WallKnife:init(args)
self:init_game_object(args)
self:set_as_rectangle(10, 4, 'dynamic', 'projectile')
self.hfx:add('hit', 1)
self.hfx:use('hit', 0.25)
self.t:tween({0.8, 1.6}, self, {v = 0}, math.linear, function()
self.t:every_immediate(0.05, function() self.hidden = not self.hidden end, 7, function() self.dead = true end)
end)
self.vr = self.r
self.dvr = random:table{random:float(-8*math.pi, -4*math.pi), random:float(4*math.pi, 8*math.pi)}
end
function WallKnife:update(dt)
self:update_game_object(dt)
self:set_angle(self.r)
self:move_along_angle(self.v, self.r)
self.vr = self.vr + self.dvr*dt
end
function WallKnife:draw()
if self.hidden then return end
graphics.push(self.x, self.y, self.vr, self.hfx.hit.x, self.hfx.hit.x)
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 2, 2, self.hfx.hit.f and fg[0] or self.color)
graphics.pop()
end
WallArrow = Object:extend()
WallArrow:implement(GameObject)
function WallArrow:init(args)
self:init_game_object(args)
self.shape = Rectangle(self.x, self.y, 10, 4)
self.hfx:add('hit', 1)
self.hfx:use('hit', 0.25)
self.t:after({0.8, 2}, function()
self.t:every_immediate(0.05, function() self.hidden = not self.hidden end, 7, function() self.dead = true end)
end)
end
function WallArrow:update(dt)
self:update_game_object(dt)
end
function WallArrow:draw()
if self.hidden then return end
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, 2, 2, self.hfx.hit.f and fg[0] or self.color)
graphics.pop()
end
2021-02-18 05:11:25 +01:00
Unit = Object:extend()
2021-02-19 04:50:27 +01:00
function Unit:init_unit()
2021-03-02 06:27:15 +01:00
self.level = self.level or 1
2021-02-18 05:11:25 +01:00
self.hfx:add('hit', 1)
2021-02-20 02:54:54 +01:00
self.hfx:add('shoot', 1)
self.hp_bar = HPBar{group = main.current.effects, parent = self}
2021-02-26 04:52:28 +01:00
self.effect_bar = EffectBar{group = main.current.effects, parent = self}
2021-02-18 05:11:25 +01:00
end
2021-02-19 04:50:27 +01:00
function Unit:bounce(nx, ny)
local vx, vy = self:get_velocity()
if nx == 0 then
self:set_velocity(vx, -vy)
self.r = 2*math.pi - self.r
end
if ny == 0 then
self:set_velocity(-vx, vy)
self.r = math.pi - self.r
2021-02-18 19:28:40 +01:00
end
2021-02-22 03:54:50 +01:00
return self.r
2021-02-18 19:28:40 +01:00
end
2021-02-19 04:50:27 +01:00
function Unit:show_hp(n)
2021-02-20 02:54:54 +01:00
self.hp_bar.hidden = false
2021-02-26 04:52:28 +01:00
self.hp_bar.color = red[0]
2021-02-20 02:54:54 +01:00
self.t:after(n or 2, function() self.hp_bar.hidden = true end, 'hp_bar')
2021-02-18 05:11:25 +01:00
end
2021-02-22 03:54:50 +01:00
function Unit:show_heal(n)
2021-02-26 04:52:28 +01:00
self.effect_bar.hidden = false
self.effect_bar.color = green[0]
self.t:after(n or 4, function() self.effect_bar.hidden = true end, 'effect_bar')
2021-02-18 05:11:25 +01:00
end
2021-02-24 06:47:22 +01:00
function Unit:show_infused(n)
2021-02-26 04:52:28 +01:00
self.effect_bar.hidden = false
self.effect_bar.color = blue[0]
self.t:after(n or 4, function() self.effect_bar.hidden = true end, 'effect_bar')
end
2021-02-18 05:11:25 +01:00
function Unit:calculate_damage(dmg)
if self.def >= 0 then dmg = dmg*(100/(100+self.def))
else dmg = dmg*(2 - 100/(100+self.def)) end
return dmg
end
2021-02-19 04:50:27 +01:00
function Unit:calculate_stats(first_run)
2021-03-02 06:27:15 +01:00
if self:is(Player) then
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(Seeker) then
2021-06-01 04:58:33 +02:00
if current_new_game_plus == 0 then
2021-05-29 03:42:16 +02:00
if self.boss then
local x = self.level
2021-06-14 06:59:16 +02:00
local y = {0, 0, 3, 0, 0, 6, 0, 0, 9, 0, 0, 12, 0, 0, 18, 0, 0, 40, 0, 0, 32, 0, 0, 64, 90}
2021-06-01 04:58:33 +02:00
self.base_hp = 100 + (current_new_game_plus*5) + (90 + current_new_game_plus*10)*y[x]
self.base_dmg = (12 + current_new_game_plus*2) + (2 + current_new_game_plus)*y[x]
2021-05-29 03:42:16 +02:00
self.base_mvspd = 35 + 1.5*y[x]
2021-06-08 06:21:35 +02:00
if x == 25 then
2021-06-09 06:35:57 +02:00
self.base_dmg = (12 + current_new_game_plus*2) + (1.25 + current_new_game_plus)*y[x]
2021-06-14 06:59:16 +02:00
self.base_mvspd = 35 + 1.1*y[x]
2021-06-08 06:21:35 +02:00
end
2021-05-29 03:42:16 +02:00
else
local x = self.level
local y = {0, 1, 3, 3, 4, 6, 5, 6, 9, 7, 8, 12, 10, 11, 15, 12, 13, 18, 16, 17, 21, 17, 20, 24, 25}
2021-05-30 17:00:03 +02:00
self.base_hp = 25 + 16.5*y[x]
self.base_dmg = 4.5 + 2.5*y[x]
2021-05-29 03:42:16 +02:00
self.base_mvspd = 70 + 3*y[x]
end
2021-04-04 01:49:54 +02:00
else
2021-05-29 03:42:16 +02:00
if self.boss then
local x = self.level
2021-06-18 23:36:00 +02:00
local y = {0, 0, 3, 0, 0, 6, 0, 0, 9, 0, 0, 12, 0, 0, 18, 0, 0, 40, 0, 0, 32, 0, 0, 64, 90}
2021-06-01 04:58:33 +02:00
self.base_hp = 100 + (current_new_game_plus*5) + (90 + current_new_game_plus*10)*y[x]
self.base_dmg = (12 + current_new_game_plus*2) + (2 + current_new_game_plus)*y[x]
2021-05-29 03:42:16 +02:00
self.base_mvspd = 35 + 1.5*y[x]
2021-06-08 06:21:35 +02:00
if x == 25 then
2021-06-14 06:59:16 +02:00
self.base_dmg = (12 + current_new_game_plus*2) + (1.75 + 0.5*current_new_game_plus)*y[x]
2021-06-08 06:21:35 +02:00
self.base_mvspd = 35 + 1.2*y[x]
end
2021-05-29 03:42:16 +02:00
else
local x = self.level
local y = {0, 1, 3, 3, 4, 6, 5, 6, 9, 7, 8, 12, 10, 11, 15, 12, 13, 18, 16, 17, 21, 17, 20, 24, 25}
2021-06-01 04:58:33 +02:00
self.base_hp = 22 + (current_new_game_plus*3) + (15 + current_new_game_plus*2.7)*y[x]
2021-06-05 08:11:23 +02:00
self.base_dmg = (4 + current_new_game_plus*1.15) + (2 + current_new_game_plus*1)*y[x]
2021-05-29 03:42:16 +02:00
self.base_mvspd = 70 + 3*y[x]
end
2021-04-04 01:49:54 +02:00
end
2021-03-14 06:40:12 +01:00
elseif self:is(Saboteur) then
self.base_hp = 100*math.pow(2, self.level-1)
self.base_dmg = 10*math.pow(2, self.level-1)
self.base_mvspd = 75
2021-06-02 07:43:03 +02:00
elseif self:is(Illusion) 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
2021-04-12 04:51:34 +02:00
elseif self:is(EnemyCritter) or self:is(Critter) then
2021-04-03 04:53:12 +02:00
local x = self.level
2021-05-29 10:10:52 +02:00
local y = {0, 1, 3, 3, 4, 6, 5, 6, 9, 7, 8, 12, 10, 11, 15, 12, 13, 18, 16, 17, 21, 17, 20, 24, 25}
self.base_hp = 25 + 30*(y[x] or 1)
self.base_dmg = 10 + 3*(y[x] or 1)
self.base_mvspd = 60 + 3*(y[x] or 1)
2021-04-13 03:23:53 +02:00
elseif self:is(Overlord) then
self.base_hp = 50*math.pow(2, self.level-1)
self.base_dmg = 10*math.pow(2, self.level-1)
self.base_mvspd = 40
2021-03-02 06:27:15 +01:00
end
2021-02-20 02:54:54 +01:00
self.base_aspd_m = 1
self.base_area_dmg_m = 1
self.base_area_size_m = 1
2021-02-23 04:47:57 +01:00
self.base_def = 25
2021-02-18 05:11:25 +01:00
self.class_hp_a = 0
self.class_dmg_a = 0
self.class_def_a = 0
self.class_mvspd_a = 0
self.class_hp_m = 1
self.class_dmg_m = 1
self.class_aspd_m = 1
2021-02-20 02:54:54 +01:00
self.class_area_dmg_m = 1
self.class_area_size_m = 1
2021-02-18 05:11:25 +01:00
self.class_def_m = 1
self.class_mvspd_m = 1
2021-02-26 04:52:28 +01:00
if first_run then
self.buff_hp_a = 0
self.buff_dmg_a = 0
self.buff_def_a = 0
self.buff_mvspd_a = 0
self.buff_hp_m = 1
self.buff_dmg_m = 1
self.buff_aspd_m = 1
self.buff_area_dmg_m = 1
self.buff_area_size_m = 1
self.buff_def_m = 1
self.buff_mvspd_m = 1
end
2021-02-18 05:11:25 +01:00
2021-03-08 05:33:01 +01:00
for _, class in ipairs(self.classes) do self.class_hp_m = self.class_hp_m*class_stat_multipliers[class].hp end
2021-02-18 05:11:25 +01:00
self.max_hp = (self.base_hp + self.class_hp_a + self.buff_hp_a)*self.class_hp_m*self.buff_hp_m
2021-02-19 04:50:27 +01:00
if first_run then self.hp = self.max_hp end
2021-02-18 05:11:25 +01:00
2021-03-08 05:33:01 +01:00
for _, class in ipairs(self.classes) do self.class_dmg_m = self.class_dmg_m*class_stat_multipliers[class].dmg end
2021-02-18 05:11:25 +01:00
self.dmg = (self.base_dmg + self.class_dmg_a + self.buff_dmg_a)*self.class_dmg_m*self.buff_dmg_m
2021-03-08 05:33:01 +01:00
for _, class in ipairs(self.classes) do self.class_aspd_m = self.class_aspd_m*class_stat_multipliers[class].aspd end
2021-02-20 02:54:54 +01:00
self.aspd_m = 1/(self.base_aspd_m*self.class_aspd_m*self.buff_aspd_m)
2021-03-08 05:33:01 +01:00
for _, class in ipairs(self.classes) do self.class_area_dmg_m = self.class_area_dmg_m*class_stat_multipliers[class].area_dmg end
2021-02-20 02:54:54 +01:00
self.area_dmg_m = self.base_area_dmg_m*self.class_area_dmg_m*self.buff_area_dmg_m
2021-02-18 05:11:25 +01:00
2021-03-08 05:33:01 +01:00
for _, class in ipairs(self.classes) do self.class_area_size_m = self.class_area_size_m*class_stat_multipliers[class].area_size end
2021-02-20 02:54:54 +01:00
self.area_size_m = self.base_area_size_m*self.class_area_size_m*self.buff_area_size_m
2021-02-18 05:11:25 +01:00
2021-03-08 05:33:01 +01:00
for _, class in ipairs(self.classes) do self.class_def_m = self.class_def_m*class_stat_multipliers[class].def end
2021-02-18 05:11:25 +01:00
self.def = (self.base_def + self.class_def_a + self.buff_def_a)*self.class_def_m*self.buff_def_m
2021-03-08 05:33:01 +01:00
for _, class in ipairs(self.classes) do self.class_mvspd_m = self.class_mvspd_m*class_stat_multipliers[class].mvspd end
2021-04-02 03:59:26 +02:00
self.max_v = (self.base_mvspd + self.class_mvspd_a + self.buff_mvspd_a)*self.class_mvspd_m*self.buff_mvspd_m
2021-02-18 05:11:25 +01:00
self.v = (self.base_mvspd + self.class_mvspd_a + self.buff_mvspd_a)*self.class_mvspd_m*self.buff_mvspd_m
end
2021-02-19 04:50:27 +01:00
2021-02-26 04:52:28 +01:00
EffectBar = Object:extend()
EffectBar:implement(GameObject)
EffectBar:implement(Parent)
function EffectBar:init(args)
2021-02-22 03:54:50 +01:00
self:init_game_object(args)
self.hidden = true
2021-02-26 04:52:28 +01:00
self.color = fg[0]
2021-02-22 03:54:50 +01:00
end
2021-02-26 04:52:28 +01:00
function EffectBar:update(dt)
2021-02-22 03:54:50 +01:00
self:update_game_object(dt)
self:follow_parent_exclusively()
end
2021-02-26 04:52:28 +01:00
function EffectBar:draw()
2021-02-22 03:54:50 +01:00
if self.hidden then return end
2021-02-26 04:52:28 +01:00
--[[
2021-02-22 03:54:50 +01:00
local p = self.parent
2021-02-26 04:52:28 +01:00
graphics.push(p.x, p.y, p.r, p.hfx.hit.x, p.hfx.hit.x)
graphics.rectangle(p.x, p.y, 3, 3, 1, 1, self.color)
2021-02-22 03:54:50 +01:00
graphics.pop()
2021-02-26 04:52:28 +01:00
]]--
2021-02-22 03:54:50 +01:00
end
2021-02-20 02:54:54 +01:00
HPBar = Object:extend()
HPBar:implement(GameObject)
HPBar:implement(Parent)
function HPBar:init(args)
2021-02-19 04:50:27 +01:00
self:init_game_object(args)
2021-02-20 02:54:54 +01:00
self.hidden = true
2021-02-19 04:50:27 +01:00
end
2021-02-20 02:54:54 +01:00
function HPBar:update(dt)
2021-02-19 04:50:27 +01:00
self:update_game_object(dt)
2021-02-20 02:54:54 +01:00
self:follow_parent_exclusively()
2021-02-19 04:50:27 +01:00
end
2021-02-20 02:54:54 +01:00
function HPBar:draw()
if self.hidden then return end
local p = self.parent
graphics.push(p.x, p.y, 0, p.hfx.hit.x, p.hfx.hit.x)
graphics.line(p.x - 0.5*p.shape.w, p.y - p.shape.h, p.x + 0.5*p.shape.w, p.y - p.shape.h, bg[-3], 2)
local n = math.remap(p.hp, 0, p.max_hp, 0, 1)
graphics.line(p.x - 0.5*p.shape.w, p.y - p.shape.h, p.x - 0.5*p.shape.w + n*p.shape.w, p.y - p.shape.h,
p.hfx.hit.f and fg[0] or ((p:is(Player) and green[0]) or (table.any(main.current.enemies, function(v) return p:is(v) end) and red[0])), 2)
2021-02-19 04:50:27 +01:00
graphics.pop()
end