Day 6
parent
2ff3cb9445
commit
ec0af70374
|
@ -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 = 'swordsman'}
|
||||
self.player = Player{group = self.main, x = gw/2, y = gh/2, leader = true, character = 'elementor'}
|
||||
--[[
|
||||
self.player:add_follower(Player{group = self.main, character = 'archer'})
|
||||
self.player:add_follower(Player{group = self.main, character = 'vagrant'})
|
||||
self.player:add_follower(Player{group = self.main, character = 'cleric'})
|
||||
self.player:add_follower(Player{group = self.main, character = 'scout'})
|
||||
self.player:add_follower(Player{group = self.main, character = 'wizard'})
|
||||
]]--
|
||||
|
||||
self.win_condition = random:table{'time', 'enemy_kill', 'wave'}
|
||||
if self.win_condition == 'wave' then
|
||||
|
|
Binary file not shown.
98
devlog.md
98
devlog.md
|
@ -97,3 +97,101 @@ Sounds done for everything. Surprising to me how much sounds added to the game a
|
|||
I should probably make it a habit to add sounds earlier rather than later from now on.
|
||||
|
||||
Tomorrow I should probably ideaguy the full set of characters and classes that I'll need so that the game is playable and start on implementing those additional characters as well as some class bonuses.
|
||||
|
||||
# Day 6 - 22/02/21
|
||||
|
||||
Ideaguyed the entire roster for the demo and implemented a few of them.
|
||||
|
||||
### Classes
|
||||
|
||||
| Class | Color | Set Effect |
|
||||
| --- | --- | --- |
|
||||
| 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 |
|
||||
|
||||
### Characters
|
||||
|
||||
| Character | Description | Trigger Range | Effect Range |
|
||||
| --- | --- | --- | --- |
|
||||
| Vagrant | shoots a projectile | medium | nil |
|
||||
| Scout | throws a knife that chains 3 times | small | nil |
|
||||
| Cleric | heals every unit when any one drops below 50% HP | nil | nil |
|
||||
| Swordsman | deals physical damage in an area around the unit | small | medium |
|
||||
| Archer | shoots an arrow that pierces | very long | nil |
|
||||
| Wizard | shoots a projectile that deals AoE damage | long | very small |
|
||||
| Outlaw | throws a fan of 5 knives | medium | nil |
|
||||
| Blade | shoots multiple blades that deal AoE damage on contact | small | small |
|
||||
| Elementor | deals massive AoE damage to a random target | long | medium |
|
||||
| Ninja | creates clones that roam and shoot shurikens | nil | very small |
|
||||
| Linker | links nearby enemies together making them share damage taken | medium | small |
|
||||
| Sage | shoots a slow projectile that draws enemies in | medium | medium |
|
||||
| Squire | improves damage and defense for adjacent units as well as healing them periodically | nil | nil |
|
||||
| Cannoneer | shoots a projectile that deals massive AoE damage | long | medium |
|
||||
| Dual Gunner | shoots two parallel projectiles | medium | nil |
|
||||
| Hunter | shoots an arrow with a chance to summon a pet | long | small |
|
||||
| Chronomancer | dramatically improves attack speed for adjacent units | nil | nil |
|
||||
| Spellblade | knives orbit you and hoam towards nearby enemies | small | small |
|
||||
| Psykeeper | all damage taken is stored and distributed as healing | nil | nil |
|
||||
| Gambler | drops a sentry that uses random attacks | nil | medium |
|
||||
|
||||
### Character Classes
|
||||
|
||||
| Character | Classes |
|
||||
| --- | --- |
|
||||
| Vagrant | warrior, ranger, psy |
|
||||
| Scout | rogue |
|
||||
| Cleric | healer |
|
||||
| Swordsman | warrior |
|
||||
| Archer | ranger |
|
||||
| Wizard | mage |
|
||||
| Outlaw | rogue, warrior |
|
||||
| Blade | warrior, nuker |
|
||||
| Elementor | mage, nuker |
|
||||
| Ninja | rogue, conjurer |
|
||||
| Linker | enchanter, nuker |
|
||||
| Sage | mage, nuker |
|
||||
| Squire | warrior, healer, enchanter |
|
||||
| Cannoneer | ranger, nuker |
|
||||
| Dual | unner [ranger, rogue |
|
||||
| Hunter | ranger, conjurer |
|
||||
| Chronomancer | mage, enchanter |
|
||||
| Spellblade | mage, rogue |
|
||||
| Psykeeper | healer, psy |
|
||||
| Gambler | conjurer |
|
||||
|
||||
### Class Numbers
|
||||
|
||||
| Class | Set Levels | Total Units |
|
||||
| --- | --- | --- |
|
||||
| Ranger | 2, 4 | 5 |
|
||||
| Warrior | 2, 4 | 5 |
|
||||
| Healer | 3 | 3 |
|
||||
| Mage | 2, 4 | 5 |
|
||||
| Nuker | 2, 4 | 5 |
|
||||
| Conjurer | 2 | 3 |
|
||||
| Rogue | 2, 4 | 5 |
|
||||
| Enchanter | 3 | 3 |
|
||||
| Psy | n | 2 |
|
||||
|
||||
### Class Stat Multipliers
|
||||
|
||||
| Class | HP | DMG | ASPD | Area DMG | Area Size | DEF | MVSPD |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| Warrior | 1.4 | 1.1 | 0.9 | 1.0 | 1.0 | 1.25 | 0.9 |
|
||||
| Ranger | 1.0 | 1.2 | 1.5 | 1.0 | 1.0 | 0.9 | 1.2 |
|
||||
| Healer | 1.2 | 1.0 | 0.5 | 1.0 | 1.0 | 1.2 | 1.0 |
|
||||
| Mage | 0.6 | 1.4 | 1.0 | 1.25 | 1.25 | 0.75 | 1.0 |
|
||||
| Rogue | 0.8 | 1.3 | 1.1 | 0.6 | 0.6 | 0.8 | 1.4 |
|
||||
| Nuker | 0.9 | 1.4 | 0.75 | 1.5 | 1.3 | 1.0 | 1.0 |
|
||||
| Conjurer | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 |
|
||||
| Enchanter | 1.2 | 1.0 | 1.0 | 1.0 | 1.0 | 1.2 | 1.2 |
|
||||
| Psy | 1.5 | 1.0 | 1.0 | 1.0 | 1.0 | 0.5 | 1.0 |
|
||||
|
||||
I've implemented up to Elementor today and ATM in the process of doing Ninja, but today seems like a particularly low energy day so I'm just going to play some games instead.
|
||||
|
|
2
main.lua
2
main.lua
|
@ -34,6 +34,7 @@ function init()
|
|||
magic_hit1 = Sound('Shadow Punch 1.ogg', s)
|
||||
magic_die1 = Sound('Magical Impact 27.ogg', s)
|
||||
knife_hit_wall1 = Sound('Shield Impacts Sword 1.ogg', s)
|
||||
blade_hit1 = Sound('Sword impact (Flesh) 2.ogg', s)
|
||||
player_hit1 = Sound('Body Fall 2.ogg', s)
|
||||
player_hit2 = Sound('Body Fall 18.ogg', s)
|
||||
player_hit_wall1 = Sound('Wood Heavy 5.ogg', s)
|
||||
|
@ -41,6 +42,7 @@ function init()
|
|||
heal1 = Sound('Buff 3.ogg', s)
|
||||
spawn1 = Sound('Buff 13.ogg', s)
|
||||
alert1 = Sound('Alert sounds 3.ogg', s)
|
||||
elementor1 = Sound('Wind Bolt 18.ogg', s)
|
||||
|
||||
main = Main()
|
||||
main:add(Arena'arena')
|
||||
|
|
23
objects.lua
23
objects.lua
|
@ -110,7 +110,7 @@ function Unit:calculate_stats(first_run)
|
|||
self.base_aspd_m = 1
|
||||
self.base_area_dmg_m = 1
|
||||
self.base_area_size_m = 1
|
||||
self.base_def = 0
|
||||
self.base_def = 25
|
||||
self.base_mvspd = 75
|
||||
self.class_hp_a = 0
|
||||
self.class_dmg_a = 0
|
||||
|
@ -138,9 +138,11 @@ function Unit:calculate_stats(first_run)
|
|||
for _, class in ipairs(self.classes) do
|
||||
if class == 'warrior' then self.class_hp_m = self.class_hp_m*1.4
|
||||
elseif class == 'mage' then self.class_hp_m = self.class_hp_m*0.6
|
||||
elseif class == 'healer' then self.class_hp_m = self.class_hp_m*1.1
|
||||
elseif class == 'void' then self.class_hp_m = self.class_hp_m*0.9
|
||||
elseif class == 'healer' then self.class_hp_m = self.class_hp_m*1.2
|
||||
elseif class == 'nuker' then self.class_hp_m = self.class_hp_m*0.9
|
||||
elseif class == 'rogue' then self.class_hp_m = self.class_hp_m*0.8
|
||||
elseif class == 'enchanter' then self.class_hp_m = self.class_hp_m*1.2
|
||||
elseif class == 'psy' then self.class_hp_m = self.class_hp_m*1.5
|
||||
elseif class == 'seeker' then self.class_hp_m = self.class_hp_m*0.5 end
|
||||
end
|
||||
self.max_hp = (self.base_hp + self.class_hp_a + self.buff_hp_a)*self.class_hp_m*self.buff_hp_m
|
||||
|
@ -149,7 +151,7 @@ function Unit:calculate_stats(first_run)
|
|||
for _, class in ipairs(self.classes) do
|
||||
if class == 'warrior' then self.class_dmg_m = self.class_dmg_m*1.1
|
||||
elseif class == 'ranger' then self.class_dmg_m = self.class_dmg_m*1.2
|
||||
elseif class == 'rogue' then self.class_dmg_m = self.class_dmg_m*1.2
|
||||
elseif class == 'rogue' then self.class_dmg_m = self.class_dmg_m*1.3
|
||||
elseif class == 'mage' then self.class_dmg_m = self.class_dmg_m*1.4 end
|
||||
end
|
||||
self.dmg = (self.base_dmg + self.class_dmg_a + self.buff_dmg_a)*self.class_dmg_m*self.buff_dmg_m
|
||||
|
@ -159,29 +161,31 @@ function Unit:calculate_stats(first_run)
|
|||
elseif class == 'ranger' then self.class_aspd_m = self.class_aspd_m*1.5
|
||||
elseif class == 'healer' then self.class_aspd_m = self.class_aspd_m*0.5
|
||||
elseif class == 'rogue' then self.class_aspd_m = self.class_aspd_m*1.1
|
||||
elseif class == 'void' then self.class_aspd_m = self.class_aspd_m*0.75 end
|
||||
elseif class == 'nuker' then self.class_aspd_m = self.class_aspd_m*0.75 end
|
||||
end
|
||||
self.aspd_m = 1/(self.base_aspd_m*self.class_aspd_m*self.buff_aspd_m)
|
||||
|
||||
for _, class in ipairs(self.classes) do
|
||||
if class == 'mage' then self.class_area_dmg_m = self.class_area_dmg_m*1.25
|
||||
elseif class == 'void' then self.class_area_dmg_m = self.class_area_dmg_m*1.5
|
||||
elseif class == 'nuker' then self.class_area_dmg_m = self.class_area_dmg_m*1.5
|
||||
elseif class == 'rogue' then self.class_area_dmg_m = self.class_area_dmg_m*0.6 end
|
||||
end
|
||||
self.area_dmg_m = self.base_area_dmg_m*self.class_area_dmg_m*self.buff_area_dmg_m
|
||||
|
||||
for _, class in ipairs(self.classes) do
|
||||
if class == 'mage' then self.class_area_size_m = self.class_area_size_m*1.2
|
||||
elseif class == 'void' then self.class_area_size_m = self.class_area_size_m*1.3
|
||||
elseif class == 'nuker' then self.class_area_size_m = self.class_area_size_m*1.3
|
||||
elseif class == 'rogue' then self.class_area_size_m = self.class_area_size_m*0.6 end
|
||||
end
|
||||
self.area_size_m = self.base_area_size_m*self.class_area_size_m*self.buff_area_size_m
|
||||
|
||||
for _, class in ipairs(self.classes) do
|
||||
if class == 'warrior' then self.class_def_m = self.class_def_m*1.25
|
||||
elseif class == 'ranger' then self.class_def_m = self.class_def_m*1.1
|
||||
elseif class == 'mage' then self.class_def_m = self.class_def_m*0.8
|
||||
elseif class == 'ranger' then self.class_def_m = self.class_def_m*0.9
|
||||
elseif class == 'mage' then self.class_def_m = self.class_def_m*0.75
|
||||
elseif class == 'rogue' then self.class_def_m = self.class_def_m*0.8
|
||||
elseif class == 'enchanter' then self.class_def_m = self.class_def_m*1.2
|
||||
elseif class == 'psy' then self.class_def_m = self.class_def_m*0.5
|
||||
elseif class == 'healer' then self.class_def_m = self.class_def_m*1.2 end
|
||||
end
|
||||
self.def = (self.base_def + self.class_def_a + self.buff_def_a)*self.class_def_m*self.buff_def_m
|
||||
|
@ -190,6 +194,7 @@ function Unit:calculate_stats(first_run)
|
|||
if class == 'warrior' then self.class_mvspd_m = self.class_mvspd_m*0.9
|
||||
elseif class == 'ranger' then self.class_mvspd_m = self.class_mvspd_m*1.2
|
||||
elseif class == 'rogue' then self.class_mvspd_m = self.class_mvspd_m*1.4
|
||||
elseif class == 'enchanter' then self.class_mvspd_m = self.class_mvspd_m*1.2
|
||||
elseif class == 'seeker' then self.class_mvspd_m = self.class_mvspd_m*0.3 end
|
||||
end
|
||||
self.v = (self.base_mvspd + self.class_mvspd_a + self.buff_mvspd_a)*self.class_mvspd_m*self.buff_mvspd_m
|
||||
|
|
135
player.lua
135
player.lua
|
@ -10,7 +10,7 @@ function Player:init(args)
|
|||
self.color = fg[0]
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = {'ranger', 'warrior', 'mage'}
|
||||
self.classes = {'ranger', 'warrior', 'psy'}
|
||||
|
||||
self.attack_sensor = Circle(self.x, self.y, 96)
|
||||
self.t:every(2, function()
|
||||
|
@ -94,6 +94,62 @@ function Player:init(args)
|
|||
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
end
|
||||
end)
|
||||
|
||||
elseif self.character == 'outlaw' then
|
||||
self.color = red[0]
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = {'warrior', 'rogue'}
|
||||
|
||||
self.attack_sensor = Circle(self.x, self.y, 96)
|
||||
self.t:every(3, 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))
|
||||
end
|
||||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'blade' then
|
||||
self.color = orange[0]
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = {'warrior', 'rogue'}
|
||||
|
||||
self.attack_sensor = Circle(self.x, self.y, 64)
|
||||
self.t:every(4, function()
|
||||
local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies)
|
||||
if enemies and #enemies > 0 then
|
||||
self:shoot()
|
||||
end
|
||||
end, nil, nil, 'shoot')
|
||||
|
||||
elseif self.character == 'elementor' then
|
||||
self.color = blue[0]
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = {'mage', 'nuker'}
|
||||
|
||||
self.attack_sensor = Circle(self.x, self.y, 128)
|
||||
self.t:every(12, function()
|
||||
local enemy = self:get_random_object_in_shape(self.attack_sensor, main.current.enemies)
|
||||
if enemy then
|
||||
self:attack(128, {x = enemy.x, y = enemy.y})
|
||||
end
|
||||
end, nil, nil, 'attack')
|
||||
|
||||
elseif self.character == 'ninja' then
|
||||
self.color = red[0]
|
||||
self:set_as_rectangle(9, 9, 'dynamic', 'player')
|
||||
self.visual_shape = 'rectangle'
|
||||
self.classes = {'rogue', 'conjurer'}
|
||||
|
||||
self.t:every(8, function()
|
||||
self.t:every(0.25, function()
|
||||
SpawnEffect{group = self.effects, x = self.x, y = self.y, action = function(x, y)
|
||||
NinjaClone{group = self.main, x = x, y = y, parent = self}
|
||||
end}
|
||||
end, 3)
|
||||
end)
|
||||
end
|
||||
self:calculate_stats(true)
|
||||
|
||||
|
@ -247,9 +303,30 @@ end
|
|||
function Player:shoot(r, mods)
|
||||
camera:spring_shake(2, r)
|
||||
self.hfx:use('shoot', 0.25)
|
||||
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}
|
||||
Projectile(table.merge(t, mods or {}))
|
||||
|
||||
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}
|
||||
Projectile(table.merge(t, mods or {}))
|
||||
r = r + math.pi/8
|
||||
end
|
||||
elseif self.character == 'blade' then
|
||||
local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies)
|
||||
if enemies and #enemies > 0 then
|
||||
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}
|
||||
Projectile(table.merge(t, mods or {}))
|
||||
end
|
||||
end
|
||||
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}
|
||||
Projectile(table.merge(t, mods or {}))
|
||||
end
|
||||
|
||||
if self.character == 'vagrant' then
|
||||
shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.3}
|
||||
|
@ -257,7 +334,7 @@ function Player:shoot(r, mods)
|
|||
archer1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
elseif self.character == 'wizard' then
|
||||
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
|
||||
elseif self.character == 'scout' then
|
||||
elseif self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' then
|
||||
_G[random:table{'scout1', 'scout2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
end
|
||||
end
|
||||
|
@ -266,11 +343,13 @@ end
|
|||
function Player:attack(area, mods)
|
||||
camera:shake(2, 0.5)
|
||||
self.hfx:use('shoot', 0.25)
|
||||
local t = {group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.area_size_m*(area or 64), color = self.color, dmg = self.area_dmg_m*self.dmg, character = self.character}
|
||||
local t = {group = main.current.effects, x = mods.x or self.x, y = mods.y or self.y, r = self.r, w = self.area_size_m*(area or 64), color = self.color, dmg = self.area_dmg_m*self.dmg, character = self.character}
|
||||
Area(table.merge(t, mods or {}))
|
||||
|
||||
if self.character == 'swordsman' then
|
||||
_G[random:table{'swordsman1', 'swordsman2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.75}
|
||||
elseif self.character == 'elementor' then
|
||||
elementor1:play{pitch = random:float(0.9, 1.1), volume = 0.5}
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -314,7 +393,9 @@ 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.wizard.area_size_m*32, color = self.color, dmg = self.wizard.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}
|
||||
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}
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -333,7 +414,7 @@ function Projectile:on_collision_enter(other, contact)
|
|||
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}
|
||||
elseif self.character == 'scout' then
|
||||
elseif self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' then
|
||||
self:die(x, y, r, 0)
|
||||
knife_hit_wall1:play{pitch = random:float(0.9, 1.1), volume = 0.2}
|
||||
local r = Unit.bounce(self, nx, ny)
|
||||
|
@ -373,7 +454,7 @@ function Projectile:on_trigger_enter(other, contact)
|
|||
HitParticle{group = main.current.effects, x = self.x, y = self.y, color = other.color}
|
||||
end
|
||||
|
||||
if self.character == 'archer' or self.character == 'scout' then
|
||||
if self.character == 'archer' or self.character == 'scout' or self.character == 'outlaw' or self.character == 'blade' then
|
||||
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
elseif self.character == 'wizard' then
|
||||
magic_area1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
|
||||
|
@ -398,10 +479,13 @@ function Area:init(args)
|
|||
HitCircle{group = main.current.effects, x = enemy.x, y = enemy.y, rs = 6, color = fg[0], duration = 0.1}
|
||||
for i = 1, 2 do HitParticle{group = main.current.effects, x = enemy.x, y = enemy.y, color = self.color} end
|
||||
for i = 1, 2 do HitParticle{group = main.current.effects, x = enemy.x, y = enemy.y, color = enemy.color} end
|
||||
if self.character == 'wizard' then
|
||||
if self.character == 'wizard' or self.character == 'elementor' then
|
||||
magic_hit1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
|
||||
elseif self.character == 'swordsman' then
|
||||
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
|
||||
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}
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -436,3 +520,34 @@ function Area:draw()
|
|||
graphics.rectangle((x1+x2)/2, (y1+y2)/2, x2-x1, y2-y1, nil, nil, self.color_transparent)
|
||||
graphics.pop()
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
NinjaClone = Object:extend()
|
||||
NinjaClone:implement(GameObject)
|
||||
NinjaClone:implement(Physics)
|
||||
function NinjaClone:init(args)
|
||||
self:init_game_object(args)
|
||||
self:init_unit()
|
||||
self:set_as_rectangle(8, 8, 'dynamic', 'enemy')
|
||||
self:set_restitution(0.5)
|
||||
|
||||
self.color = red[0]
|
||||
self.classes = {'ninja_clone'}
|
||||
self:calculate_stats(true)
|
||||
self:set_as_steerable(self.v, 2000, 4*math.pi, 4)
|
||||
end
|
||||
|
||||
|
||||
function NinjaClone:update(dt)
|
||||
self:update_game_object(dt)
|
||||
self:calculate_stats()
|
||||
end
|
||||
|
||||
|
||||
function NinjaClone: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
|
||||
|
|
75
todo
75
todo
|
@ -1,19 +1,66 @@
|
|||
Vagrant: shoots an ethereal projectile at any nearby enemy that deals physical and magical damage, medium range
|
||||
Vagrant: shoots a projectile at any nearby enemy, medium range
|
||||
Scout: throws a knife that chains 3 times at any nearby enemy, small range
|
||||
Cleric: heals every unit when any one drops below 50% HP
|
||||
Swordsman: deals physical damage in a medium area around the unit, small range
|
||||
Swordsman: deals physical damage in a medium area around the unit, small range, AoE has medium range
|
||||
Archer: shoots an arrow that pierces at any nearby enemy, very long range
|
||||
Wizard: shoots a projectile at any nearby enemy and deals AoE magical damage on contact, long range, AoE has very small range
|
||||
Wizard: shoots a projectile at any nearby enemy and deals AoE damage on contact, long range, AoE has very small range
|
||||
Outlaw: throws a leque of knives at nearby enemies, medium range
|
||||
Blade: shoots multiple blades at nearby enemies, each dealing AoE damage on contact, small range, AoE has small range
|
||||
Elementor: deals massive AoE damage to a random target, long range, AoE has medium range
|
||||
|
||||
Engineer: drops a turret that shoots secondary projectiles very fast, medium range
|
||||
Ninja: creates clones that roam and shoot projectiles at nearby enemies, very small range
|
||||
Linker: links nearby enemies together making them share damage taken, medium range
|
||||
Sage: shoots a slow projectile that draws enemies in, medium range, AoE has medium range
|
||||
Squire: improves damage and defense for adjacent units, as well as healing them periodically
|
||||
Cannoneer: shoots a projectile at any nearby enemy and deals massive AoE damage on contact, long range, AoE has medium range
|
||||
Dual Gunner: shoots two parallel projectiles at any nearby enemy, medium range
|
||||
Hunter: shoots an arrow at any nearby enemy with a chance to summon a pet that will trample through enemies knocking them away, arrow has long range, pet has small range
|
||||
Chronomancer: dramatically improves attack speed for adjacent units
|
||||
Spellblade: knives orbit you and hoam towards nearby enemies, small range
|
||||
Psykeeper: all damage taken is stored and distributed as healing
|
||||
Gambler: drops a sentry that uses random attacks, medium range
|
||||
|
||||
Ranger: yellow, buff attack speed
|
||||
Warrior: orange, buff attack damage
|
||||
Healer: green, buff healing effectiveness
|
||||
Mage: blue, debuff enemy defense
|
||||
Void: purple, buff area damage and size
|
||||
Builder: orange, buffs construct damage, attack speed and duration
|
||||
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
|
||||
|
||||
Vagrant [warrior, ranger, psy]
|
||||
Scout [rogue]
|
||||
Cleric [healer]
|
||||
Swordsman [warrior]
|
||||
Archer [ranger]
|
||||
Wizard [mage]
|
||||
Outlaw [rogue, warrior]
|
||||
Blade [warrior, nuker]
|
||||
Elementor [mage, nuker]
|
||||
|
||||
Ninja [rogue, conjurer]
|
||||
Linker [enchanter, nuker]
|
||||
Sage [mage, nuker]
|
||||
Squire [warrior, healer, enchanter]
|
||||
Cannoneer [ranger, nuker]
|
||||
Dual Gunner [ranger, rogue]
|
||||
Hunter [ranger, conjurer]
|
||||
Chronomancer [mage, enchanter]
|
||||
Spellblade [mage, rogue]
|
||||
Psykeeper [healer, psy]
|
||||
Gambler [conjurer]
|
||||
|
||||
Ranger [2, 4] (5)
|
||||
Warrior [2, 4] (5)
|
||||
Healer [3]
|
||||
Mage [2, 4] (5)
|
||||
Nuker [2, 4] (5)
|
||||
Conjurer [2] (3)
|
||||
Rogue [2, 4] (5)
|
||||
Enchanter [3] (3)
|
||||
Psy [n] (2)
|
||||
|
||||
HP
|
||||
Damage
|
||||
|
@ -21,11 +68,3 @@ Area damage
|
|||
Area of effect
|
||||
Attack speed
|
||||
Defense -> if defense >= 0 then dmg_m = 100/(100+defense) else dmg_m = 2-100/(100-defense)
|
||||
|
||||
* HP bar should be drawn on top of all player units
|
||||
* Projectiles
|
||||
* Areas
|
||||
* Stats: attack speed, damage, area
|
||||
* One or a few of the characters
|
||||
* Port over enemy spawn logic from SHOOTRX
|
||||
* Sounds
|
||||
|
|
Loading…
Reference in New Issue