master
a327ex 2021-02-27 01:28:00 -03:00
parent 1be14b51b2
commit 0d0ca8564b
9 changed files with 194 additions and 36 deletions

View File

@ -50,12 +50,14 @@ function Arena:on_enter(from, level)
WallCover{group = self.post_main, vertices = math.to_rectangle_vertices(self.x1, -40, self.x2, self.y1), color = bg[-1]}
WallCover{group = self.post_main, vertices = math.to_rectangle_vertices(self.x1, self.y2, self.x2, gh + 40), color = bg[-1]}
self.player = Player{group = self.main, x = gw/2, y = gh/2, leader = true, character = 'engineer'}
self.player = Player{group = self.main, x = gw/2, y = gh/2, leader = true, character = 'swordsman'}
self.player:add_follower(Player{group = self.main, character = 'outlaw'})
-- self.player:add_follower(Player{group = self.main, character = 'squire'})
self.player:add_follower(Player{group = self.main, character = 'blade'})
--[[
self.player:add_follower(Player{group = self.main, character = 'sage'})
self.player:add_follower(Player{group = self.main, character = 'archer'})
self.player:add_follower(Player{group = self.main, character = 'spellblade'})
self.player:add_follower(Player{group = self.main, character = 'hunter'})
self.player:add_follower(Player{group = self.main, character = 'cleric'})
self.player:add_follower(Player{group = self.main, character = 'wizard'})
self.player:add_follower(Player{group = self.main, character = 'squire'})
@ -164,11 +166,65 @@ function Arena:on_enter(from, level)
end)
end)
end
local units = {}
table.insert(units, self.player)
for _, f in ipairs(self.player.followers) do table.insert(units, f) end
local rangers = 0
local warriors = 0
local healers = 0
local mages = 0
local nukers = 0
local conjurers = 0
local rogues = 0
local enchanters = 0
local psys = 0
for _, unit in ipairs(units) do
for _, unit_class in ipairs(unit.classes) do
if unit_class == 'ranger' then rangers = rangers + 1 end
if unit_class == 'warrior' then warriors = warriors + 1 end
if unit_class == 'healer' then healers = healers + 1 end
if unit_class == 'mage' then mages = mages + 1 end
if unit_class == 'nuker' then nukers = nukers + 1 end
if unit_class == 'conjurer' then conjurers = conjurers + 1 end
if unit_class == 'rogue' then rogues = rogues + 1 end
if unit_class == 'enchanter' then enchanters = enchanters + 1 end
if unit_class == 'psy' then psys = psys + 1 end
end
end
self.ranger_level = 0
if rangers >= 2 then self.ranger_level = 1 end
if rangers >= 4 then self.ranger_level = 2 end
self.warrior_level = 0
if warriors >= 2 then self.warrior_level = 1 end
if warriors >= 4 then self.warrior_level = 2 end
self.healer_level = 0
if healers >= 3 then self.healer_level = 1 end
self.mage_level = 0
if mages >= 2 then self.mage_level = 1 end
if mages >= 4 then self.mage_level = 2 end
self.nuke_level = 0
if nukers >= 2 then self.nuke_level = 1 end
if nukers >= 4 then self.nuke_level = 2 end
self.conjurer_level = 0
if conjurers >= 2 then self.conjurer_level = 1 end
self.rogue_level = 0
if rogues >= 2 then self.rogue_level = 1 end
if rogues >= 4 then self.rogue_level = 2 end
self.enchanter_level = 0
if enchanters >= 3 then self.enchanter_level = 1 end
self.psy_level = psys
end
function Arena:update(dt)
self:update_game_object(dt*slow_amount)
if self.enchanter_level == 1 then self.enchanter_dmg_m = 1.25
else self.enchanter_dmg_m = 1 end
self.main:update(dt*slow_amount)
self.post_main:update(dt*slow_amount)
self.effects:update(dt*slow_amount)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -214,3 +214,20 @@ Tomorrow I'll probably do some UI work so the player can buy new characters as h
and I have a essentially 1 week to do them, which should be more than enough.
Note: remember to attribute https://freesound.org/people/Hybrid_V/sounds/321215/ for turret_deploy sound in credits.
# Day 10 - 26/02/21
Another day with almost no sleep and just general low energy because of it... I managed to things done though. I got all the class set bonuses working. Here's what they do:
| Class | Set Numbers | Set Effect |
| --- | --- | --- |
| Ranger | 2/4 | 10/20% chance to release a barrage |
| Warrior | 2/4 | +25/+50 defense |
| Healer | 3 | +25% healing effectiveness |
| Mage | 2/4 | -15/-30 enemy defense |
| Nuker | 2/4 | +15/25% area damage and size |
| Conjurer | 2 | +25% construct damage and duration |
| Rogue | 2/4 | 10/20% chance to crit dealing 4x damage |
| Enchanter | 3 | +25% damage to all allies |
Tomorrow I should get started on going from arena to arena, buying characters and figuring out enemy scaling.

View File

@ -17,6 +17,10 @@ end
function Seeker:update(dt)
self:update_game_object(dt)
if main.current.mage_level == 2 then self.buff_def_a = -30
elseif main.current.mage_level == 1 then self.buff_def_a = -15
else self.buff_def_a = 0 end
self:calculate_stats()
if self.being_pushed then

View File

@ -14,7 +14,7 @@ function init()
input:bind('move_up', {'w', 'up'})
input:bind('move_down', {'s', 'down'})
sfx_tag = {tags = {sfx}}
local s = {tags = {sfx}}
shoot1 = Sound('Shooting Projectile (Classic) 11.ogg', s)
archer1 = Sound('Releasing Bow String 1.ogg', s)
wizard1 = Sound('Wind Bolt 20.ogg', s)
@ -61,6 +61,8 @@ function init()
turret_hit_wall1 = Sound('Concrete 6.ogg', s)
turret_hit_wall2 = Sound('Concrete 7.ogg', s)
turret_deploy = Sound('321215__hybrid-v__sci-fi-weapons-deploy.ogg', s)
rogue_crit1 = Sound('Dagger Stab (Flesh) 4.ogg', s)
rogue_crit2 = Sound('Sword hits another sword 6.ogg', s)
main = Main()
main:add(Arena'arena')

View File

@ -86,8 +86,8 @@ function Player:init(args)
if self.leader then followers = self.followers else followers = self.parent.followers end
if (table.any(followers, function(v) return v.hp <= 0.5*v.max_hp end) or (leader.hp <= 0.5*leader.max_hp)) and love.timer.getTime() - self.last_heal_time > 6 then
self.last_heal_time = love.timer.getTime()
if self.leader then self:heal(0.1*self.max_hp) else self.parent:heal(0.1*self.parent.max_hp) end
for _, f in ipairs(followers) do f:heal(0.1*f.max_hp) end
if self.leader then self:heal(0.1*self.max_hp*(self.heal_effect_m or 1)) else self.parent:heal(0.1*self.parent.max_hp*(self.heal_effect_m or 1)) end
for _, f in ipairs(followers) do f:heal(0.1*f.max_hp*(self.heal_effect_m or 1)) end
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
end
end)
@ -110,7 +110,7 @@ function Player:init(args)
self.color = orange[0]
self:set_as_rectangle(9, 9, 'dynamic', 'player')
self.visual_shape = 'rectangle'
self.classes = {'warrior', 'rogue'}
self.classes = {'warrior', 'nuker'}
self.attack_sensor = Circle(self.x, self.y, 64)
self.t:cooldown(4, function() local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies); return enemies and #enemies > 0 end, function()
@ -194,8 +194,8 @@ function Player:init(args)
if previous_character then previous_character:squire_buff(8) end
self.t:after(8, function() self.applying_buff = false end, 'squire_buff_apply')
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
if next_character then next_character:heal(0.1*next_character.max_hp) end
if previous_character then previous_character:heal(0.1*previous_character.max_hp) end
if next_character then next_character:heal(0.1*next_character.max_hp*(self.heal_effect_m or 1)) end
if previous_character then previous_character:heal(0.1*previous_character.max_hp*(self.heal_effect_m or 1)) end
end)
elseif self.character == 'cannoneer' then
@ -280,8 +280,8 @@ function Player:init(args)
if self.psykeeper_heal > 0 then
local heal_amount = math.floor(self.psykeeper_heal/(#followers+1))
if self.leader then self:heal(heal_amount) else self.parent:heal(heal_amount) end
for _, f in ipairs(followers) do f:heal(heal_amount) end
if self.leader then self:heal(heal_amount*(self.heal_effect_m or 1)) else self.parent:heal(heal_amount*(self.heal_effect_m or 1)) end
for _, f in ipairs(followers) do f:heal(heal_amount*(self.heal_effect_m or 1)) end
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
self.psykeeper_heal = 0
end
@ -313,7 +313,6 @@ end
function Player:update(dt)
if self.attack_sensor then self.enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies) end
self:update_game_object(dt)
if self.character == 'squire' then
@ -352,9 +351,51 @@ function Player:update(dt)
if previous_character then previous_character.chronomancer_aspd_m = 1.25 end
end
self.buff_dmg_a = self.squire_dmg_a or 0
self.buff_def_a = self.squire_def_a or 0
self.buff_aspd_m = self.chronomancer_aspd_m or 1
if table.any(self.classes, function(v) return v == 'ranger' end) then
if main.current.ranger_level == 2 then self.chance_to_barrage = 20
elseif main.current.ranger_level == 1 then self.chance_to_barrage = 10
elseif main.current.ranger_level == 0 then self.chance_to_barrage = 0 end
end
if table.any(self.classes, function(v) return v == 'warrior' end) then
if main.current.warrior_level == 2 then self.warrior_def_a = 50
elseif main.current.warrior_level == 1 then self.warrior_def_a = 25
elseif main.current.warrior_level == 0 then self.warrior_def_a = 0 end
end
if table.any(self.classes, function(v) return v == 'healer' end) then
if main.current.healer_level == 1 then self.heal_effect_m = 1.25
else self.heal_effect_m = 1 end
end
if table.any(self.classes, function(v) return v == 'nuker' end) then
if main.current.nuker_level == 2 then self.nuker_area_size_m = 1.25; self.nuker_area_dmg_m = 1.25
elseif main.current.nuker_level == 1 then self.nuker_area_size_m = 1.15; self.nuker_area_dmg_m = 1.15
elseif main.current.nuker_level == 0 then self.nuker_area_size_m = 1; self.nuker_area_dmg_m = 1 end
end
if table.any(self.classes, function(v) return v == 'conjurer' end) then
if main.current.conjurer_level == 1 then self.conjurer_buff_m = 1.25
else self.conjurer_buff_m = 1 end
end
if table.any(self.classes, function(v) return v == 'rogue' end) then
if main.current.rogue_level == 2 then self.chance_to_crit = 20
elseif main.current.rogue_level == 1 then self.chance_to_crit = 10
elseif main.current.rogue_level == 0 then self.chance_to_crit = 0 end
end
if table.any(self.classes, function(v) return v == 'enchanter' end) then
if main.current.enchanter_level == 1 then self.enchanter_dmg_m = 1.25
else self.enchanter_dmg_m = 1 end
end
self.buff_dmg_a = (self.squire_dmg_a or 0)
self.buff_def_a = (self.squire_def_a or 0) + (self.warrior_def_a or 0)
self.buff_aspd_m = (self.chronomancer_aspd_m or 1)
self.buff_dmg_m = (main.current.enchanter_dmg_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:calculate_stats()
if self.attack_sensor then self.attack_sensor:move_to(self.x, self.y) end
@ -408,6 +449,10 @@ function Player:update(dt)
self.r = self:get_angle()
end
end
if self.character == 'blade' then
print(self.def)
end
end
@ -509,14 +554,20 @@ end
function Player:shoot(r, mods)
mods = mods or {}
camera:spring_shake(2, r)
self.hfx:use('shoot', 0.25)
local dmg_m = 1
local crit = false
if self.chance_to_crit and random:bool(self.chance_to_crit) then dmg_m = 4; crit = true end
if self.character == 'outlaw' then
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}
r = r - 2*math.pi/8
for i = 1, 5 do
local t = {group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(r), y = self.y + 1.6*self.shape.w*math.sin(r), v = 250, r = r, color = self.color, dmg = self.dmg, character = self.character, parent = self}
local t = {group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(r), y = self.y + 1.6*self.shape.w*math.sin(r), v = 250, r = r, color = self.color, dmg = self.dmg*dmg_m, crit = crit, character = self.character,
parent = self}
Projectile(table.merge(t, mods or {}))
r = r + math.pi/8
end
@ -527,7 +578,8 @@ function Player:shoot(r, mods)
for _, enemy in ipairs(enemies) do
local r = self:angle_to_object(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.color, dmg = self.dmg, character = self.character, parent = self}
local t = {group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(r), y = self.y + 1.6*self.shape.w*math.sin(r), v = 250, r = r, color = self.color, dmg = self.dmg*dmg_m, crit = crit, character = self.character,
parent = self}
Projectile(table.merge(t, mods or {}))
end
end
@ -541,32 +593,37 @@ function Player:shoot(r, mods)
HitCircle{group = main.current.effects, x = self.x + 0.8*self.shape.w*math.cos(r) + 4*math.cos(r - math.pi/2), y = self.y + 0.8*self.shape.w*math.sin(r) + 4*math.sin(r - math.pi/2), rs = 6}
HitCircle{group = main.current.effects, x = self.x + 0.8*self.shape.w*math.cos(r) + 4*math.cos(r + math.pi/2), y = self.y + 0.8*self.shape.w*math.sin(r) + 4*math.sin(r + math.pi/2), rs = 6}
local t1 = {group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(r) + 4*math.cos(r - math.pi/2) , y = self.y + 1.6*self.shape.w*math.sin(r) + 4*math.sin(r - math.pi/2),
v = 250, r = r, color = self.color, dmg = self.dmg, character = self.character, parent = self}
v = 250, r = r, color = self.color, dmg = self.dmg*dmg_m, crit = crit, character = self.character, parent = self}
local t2 = {group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(r) + 4*math.cos(r + math.pi/2) , y = self.y + 1.6*self.shape.w*math.sin(r) + 4*math.sin(r + math.pi/2),
v = 250, r = r, color = self.color, dmg = self.dmg, character = self.character, parent = self}
v = 250, r = r, color = self.color, dmg = self.dmg*dmg_m, crit = crit, character = self.character, parent = self}
Projectile(table.merge(t1, mods or {}))
Projectile(table.merge(t2, mods or {}))
else
HitCircle{group = main.current.effects, x = self.x + 0.8*self.shape.w*math.cos(r), y = self.y + 0.8*self.shape.w*math.sin(r), rs = 6}
local t = {group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(r), y = self.y + 1.6*self.shape.w*math.sin(r), v = 250, r = r, color = self.color, dmg = self.dmg, character = self.character, parent = self}
local t = {group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(r), y = self.y + 1.6*self.shape.w*math.sin(r), v = 250, r = r, color = self.color, dmg = self.dmg*dmg_m, crit = crit, character = self.character,
parent = self}
Projectile(table.merge(t, mods or {}))
end
if self.character == 'vagrant' or self.character == 'dual_gunner' then
shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.3}
shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.2}
elseif self.character == 'archer' or self.character == 'hunter' then
archer1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
archer1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
elseif self.character == 'wizard' then
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
elseif self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' or self.character == 'spellblade' then
_G[random:table{'scout1', 'scout2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
_G[random:table{'scout1', 'scout2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.35}
if self.character == 'spellblade' then
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
end
elseif self.character == 'cannoneer' then
_G[random:table{'cannoneer1', 'cannoneer2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
end
if self.chance_to_barrage and random:bool(self.chance_to_barrage) then
self:barrage(r, 4)
end
end
@ -585,6 +642,20 @@ function Player:attack(area, mods)
end
function Player:barrage(r, n)
n = n or 8
for i = 1, n do
self.t:after((i-1)*0.075, function()
archer1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
HitCircle{group = main.current.effects, x = self.x + 0.8*self.shape.w*math.cos(r), y = self.y + 0.8*self.shape.w*math.sin(r), rs = 6}
local t = {group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(r), y = self.y + 1.6*self.shape.w*math.sin(r), v = 250, r = r + random:float(-math.pi/16, math.pi/16), color = self.color, dmg = self.dmg,
parent = self, character = 'barrage'}
Projectile(table.merge(t, mods or {}))
end)
end
end
Projectile = Object:extend()
@ -694,7 +765,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' then
if self.character == 'archer' or self.character == 'hunter' or self.character == 'barrage' then
self:die(x, y, r, 0)
_G[random:table{'arrow_hit_wall1', 'arrow_hit_wall2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.2}
WallArrow{group = main.current.main, x = x, y = y, r = self.r, color = self.color}
@ -783,6 +854,15 @@ function Projectile:on_trigger_enter(other, contact)
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}
rogue_crit2:play{pitch = random:float(0.95, 1.05), volume = 0.15}
for i = 1, 3 do HitParticle{group = main.current.effects, x = other.x, y = other.y, color = self.color, v = random:float(100, 400)} end
for i = 1, 3 do HitParticle{group = main.current.effects, x = other.x, y = other.y, color = other.color, v = random:float(100, 400)} end
HitCircle{group = main.current.effects, x = other.x, y = other.y, rs = 12, color = fg[0], duration = 0.3}:scale_down():change_color(0.5, self.color)
end
end
end
@ -866,15 +946,15 @@ function Turret:init(args)
self.t:every({0.1, 0.2}, function()
self.hfx:use('hit', 0.25, 200, 10)
HitCircle{group = main.current.effects, x = self.x + 0.8*self.shape.w*math.cos(self.r), y = self.y + 0.8*self.shape.w*math.sin(self.r), rs = 6}
local t = {group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(self.r), y = self.y + 1.6*self.shape.w*math.sin(self.r), v = 200, r = self.r, color = self.color, dmg = self.parent.dmg,
character = self.parent.character, parent = self.parent}
local t = {group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(self.r), y = self.y + 1.6*self.shape.w*math.sin(self.r), v = 200, r = self.r, color = self.color,
dmg = self.parent.dmg*(self.parent.conjurer_buff_m or 1), character = self.parent.character, parent = self.parent}
Projectile(table.merge(t, mods or {}))
turret1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
turret2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
end, 3)
end)
self.t:after(24, function()
self.t:after(24*(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()

19
todo
View File

@ -19,15 +19,15 @@ Spellblade: knives spiral outwards and pierce enemies
Psykeeper: all damage taken is stored and distributed as healing
Engineer: drops a sentry that uses random attacks, medium range
Ranger: yellow, chance to release a barrage
Warrior: orange, increased defense
Healer: green, increased healing effectiveness
Mage: blue, decreased enemy defense
Nuker: purple, increased area damage and size
Conjurer: orange, increased construct damage and duration
Rogue: red, chance to crit dealing 4x damage
Enchanter: pink, increased damage to all allies
Psy: white, returns damage taken based on number of active psy units
Ranger: yellow, 10%/20% chance to release a barrage on attack
Warrior: orange, +25/+50 defense to all warriors
Healer: green, 25% increased healing effectiveness
Mage: blue, -15/-30 enemy defense
Nuker: purple, 15%/25% increased area damage and size
Conjurer: orange, 25% increased construct damage and duration
Rogue: red, 10%/20% chance to crit dealing 4x damage
Enchanter: pink, 25% increased damage to all allies
Psy: white, 2X damage taken returned
Vagrant [warrior, ranger, psy]
Scout [rogue]
@ -48,7 +48,6 @@ Hunter [ranger, conjurer]
Chronomancer [mage, enchanter]
Spellblade [mage, rogue]
Psykeeper [healer, psy]
Engineer [conjurer]
Ranger [2, 4] (5)