Loop update 1/5

master
a327ex 2021-06-29 02:08:51 -03:00
parent c804c7e6e8
commit bbe9c9f7af
7 changed files with 117 additions and 59 deletions

View File

@ -644,6 +644,9 @@ function Arena:quit()
else
if not self.arena_clear_text then self.arena_clear_text = Text2{group = self.ui, x = gw/2, y = gh/2 - 48, lines = {{text = '[wavy_mid, cbyc]arena clear!', font = fat_font, alignment = 'center'}}} end
self:gain_gold()
self.t:after(2, function()
self.t:tween(0.7, self, {main_slow_amount = 0}, math.linear, function() self.main_slow_amount = 0 end)
end)
self.t:after(3, function()
if self.level % 3 == 0 then
input:set_mouse_visible(true)
@ -661,6 +664,9 @@ function Arena:quit()
{text = '[' .. character_color_strings[unit.character] .. ']' .. unit.character, font = pixul_font, alignment = 'left'}
}}
end
for i, passive in ipairs(self.passives) do
ItemCard{group = self.ui, x = 120 + (i-1)*30, y = gh - 30, w = 30, h = 45, sx = 0.75, sy = 0.75, force_update = true, passive = passive.passive , level = passive.level, xp = passive.xp, parent = self}
end
else
self:transition()
end
@ -884,7 +890,13 @@ end
function Arena:gain_gold()
local merchant = self.player:get_unit'merchant'
local merchant
for _, unit in ipairs(self.starting_units) do
if unit.character == 'merchant' then
merchant = true
break
end
end
self.gold_gained = random:int(level_to_gold_gained[self.level][1], level_to_gold_gained[self.level][2])
self.interest = math.min(math.floor(gold/5), 5) + math.min((merchant and math.floor(gold/10) or 0), 10)
gold = gold + self.gold_gained + self.gold_picked_up + self.interest

View File

@ -397,7 +397,7 @@ function BuyScreen:set_items()
local y = 182
for k, passive in ipairs(self.passives) do
local i, j = math.index_to_coordinates(k, 4)
table.insert(self.items, ItemCard{group = self.main, x = 45 + (i-1)*60, y = y + (j-1)*50, w = 40, h = 50, passive = passive.passive , level = passive.level, xp = passive.xp, parent = self})
table.insert(self.items, ItemCard{group = self.main, x = 45 + (i-1)*60, y = y + (j-1)*50, w = 40, h = 50, passive = passive.passive , level = passive.level, xp = passive.xp, parent = self, i = k})
end
end
@ -928,7 +928,13 @@ function RerollButton:init(args)
self.text = Text({{text = '[bg10]reroll: [yellow]2', font = pixul_font, alignment = 'center'}}, global_text_tags)
elseif self.parent:is(Arena) then
self.shape = Rectangle(self.x, self.y, 60, 16)
local merchant = self.parent.player:get_unit'merchant'
local merchant
for _, unit in ipairs(self.parent.starting_units) do
if unit.character == 'merchant' then
merchant = unit
break
end
end
if self.parent.level == 3 or (merchant and merchant.level == 3) then
self.free_reroll = true
self.text = Text({{text = '[bg10]reroll: [yellow]0', font = pixul_font, alignment = 'center'}}, global_text_tags)
@ -1167,6 +1173,7 @@ function CharacterPart:update(dt)
self:die()
self.parent:set_party_and_sets()
self.parent:refresh_cards()
self.parent.party_text:set_text({{text = '[wavy_mid, fg]party ' .. tostring(#self.parent.units) .. '/' .. tostring(max_units), font = pixul_font, alignment = 'center'}})
system.save_run(self.parent.level, gold, self.parent.units, self.parent.passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool, locked_state)
else
self.parent.parent:gain_gold(self:get_sale_price())
@ -1383,6 +1390,8 @@ end
function ItemCard:update(dt)
self:update_game_object(dt)
if self.parent:is(Arena) then return end
if self.selected and input.m1.pressed and not self.unlevellable then
if self.level >= 3 then return end
if gold < 5 then
@ -1425,16 +1434,25 @@ function ItemCard:update(dt)
system.save_run(self.parent.level, gold, self.parent.units, self.parent.passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool, locked_state)
end
end
if self.selected and input.m2.pressed then
_G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
self.parent:gain_gold((self.level == 1 and 10) or (self.level == 2 and 20) or (self.level == 3 and 30))
table.remove(self.parent.passives, self.i)
self:die()
self.parent:set_items()
system.save_run(self.parent.level, gold, self.parent.units, self.parent.passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool, locked_state)
end
end
function ItemCard:draw()
graphics.push(self.x, self.y, 0, self.spring.x, self.spring.x)
graphics.push(self.x, self.y, 0, self.sx*self.spring.x, self.sy*self.spring.x)
if self.selected then
graphics.rectangle(self.x, self.y, self.w, self.h, 6, 6, bg[-1])
end
_G[self.passive]:draw(self.x, self.y, 0, 0.8, 0.7, 0, 0, fg[0])
if not self.unlevellable then
if not self.unlevellable and not self.parent:is(Arena) then
local x, y = self.x + self.w/2.5, self.y - self.h/2.5
if self.level == 1 then
graphics.rectangle(x - 2, y, 2, 2, nil, nil, self.xp >= 1 and fg[0] or bg[5])
@ -1466,8 +1484,8 @@ function ItemCard:create_info_text()
else
self.info_text = InfoText{group = main.current.ui, force_update = true}
self.info_text:activate({
{text = '[fg]' .. passive_names[self.passive] .. ', [yellow]Lv.' .. self.level .. '[fg], XP: [yellow]' .. self.xp .. '/' .. self.max_xp .. '[fg], +1 XP cost: [yellow]5', font = pixul_font, alignment = 'center',
height_multiplier = 1.25},
{text = '[fg]' .. passive_names[self.passive] .. ', [yellow]Lv.' .. self.level .. '[fg], XP: [yellow]' .. self.xp .. '/' .. self.max_xp .. '[fg], +1 XP cost: [yellow]5[fg], sells for: [yellow]' ..
tostring((self.level == 1 and 10) or (self.level == 2 and 20) or (self.level == 3 and 30)), font = pixul_font, alignment = 'center', height_multiplier = 1.25},
{text = passive_descriptions_level[self.passive](self.level), font = pixul_font, alignment = 'center', height_multiplier = 1.25},
}, nil, nil, nil, nil, 16, 4, nil, 2)
self.info_text.x, self.info_text.y = gw/2, gh/2 + 10
@ -1558,6 +1576,7 @@ function ShopCard:update(dt)
self:die()
self.parent.cards[self.i] = nil
self.parent:refresh_cards()
self.parent.party_text:set_text({{text = '[wavy_mid, fg]party ' .. tostring(#self.parent.units) .. '/' .. tostring(max_units), font = pixul_font, alignment = 'center'}})
locked_state = {locked = self.parent.locked, cards = {self.parent.cards[1] and self.parent.cards[1].unit, self.parent.cards[2] and self.parent.cards[2].unit, self.parent.cards[3] and self.parent.cards[3].unit}}
system.save_run(self.parent.level, gold, self.parent.units, self.parent.passives, self.parent.shop_level, self.parent.shop_xp, run_passive_pool, locked_state)
else

View File

@ -608,23 +608,6 @@ end
function Seeker:curse(curse, duration, arg1, arg2, arg3)
if main.current.player.whispers_of_doom then
if not self.doom then self.doom = 0 end
self.doom = self.doom + 1
if self.doom == ((main.current.player.whispers_of_doom == 1 and 4) or (main.current.player.whispers_of_doom == 2 and 3) or (main.current.player.whispers_of_doom == 3 and 2)) then
self.doom = 0
self:hit((main.current.player.whispers_of_doom == 1 and 100) or (main.current.player.whispers_of_doom == 2 and 150) or (main.current.player.whispers_of_doom == 3 and 200))
buff1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
end
end
if main.current.player.hextouch then
local p = main.current.player
local dmg = (p.hextouch == 1 and 10) or (p.hextouch == 2 and 15) or (p.hextouch == 3 and 20)
self:apply_dot(dmg*(p.dot_dmg_m or 1)*(main.current.chronomancer_dot or 1), 3)
end
buff1:play{pitch = random:float(0.65, 0.75), volume = 0.25}
if curse == 'launcher' then
self.t:after(duration, function()
@ -662,6 +645,23 @@ function Seeker:curse(curse, duration, arg1, arg2, arg3)
end
end
end
if main.current.player.whispers_of_doom then
if not self.doom then self.doom = 0 end
self.doom = self.doom + 1
if self.doom == ((main.current.player.whispers_of_doom == 1 and 4) or (main.current.player.whispers_of_doom == 2 and 3) or (main.current.player.whispers_of_doom == 3 and 2)) then
self.doom = 0
self:hit((main.current.player.whispers_of_doom == 1 and 100) or (main.current.player.whispers_of_doom == 2 and 150) or (main.current.player.whispers_of_doom == 3 and 200))
buff1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
end
end
if main.current.player.hextouch then
local p = main.current.player
local dmg = (p.hextouch == 1 and 10) or (p.hextouch == 2 and 15) or (p.hextouch == 3 and 20)
self:apply_dot(dmg*(p.dot_dmg_m or 1)*(main.current.chronomancer_dot or 1), 3)
end
end

View File

@ -3,6 +3,7 @@
Trigger = Object:extend()
function Trigger:init()
self.triggers = {}
self.time = love.timer.getTime()
end
@ -171,6 +172,12 @@ function Trigger:get_timer_and_delay(tag)
end
function Trigger:get_time()
self.time = love.timer.getTime()
return self.time
end
function Trigger:resolve_delay(delay)
if type(delay) == "table" then
return random:float(delay[1], delay[2])
@ -186,6 +193,8 @@ end
function Trigger:update(dt)
self.time = self.time + dt
for tag, trigger in pairs(self.triggers) do
if trigger.timer then
trigger.timer = trigger.timer + dt

View File

@ -1546,14 +1546,31 @@ 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',
}
main:add(Arena'arena')
main:go_to('arena', 10, {
main:go_to('arena', 3, {
{character = 'illusionist', level = 2},
-- {character = 'carver', level = 2},
{character = 'engineer', level = 2},
-- {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 = 'summon_instability', level = 3},
})
]]--
--[[
@ -1852,6 +1869,7 @@ function open_options(self)
current_new_game_plus = math.clamp(current_new_game_plus - 1, 0, 5)
state.current_new_game_plus = current_new_game_plus
self.ng_t.text:set_text({{text = '[bg10]current: ' .. current_new_game_plus, font = pixul_font, alignment = 'center'}})
max_units = 7 + current_new_game_plus
end}
self.ng_plus_plus_button = Button{group = self.ui, x = gw/2 + 5, y = gh - 50, force_update = true, button_text = 'NG+ up', fg_color = 'bg10', bg_color = 'bg', action = function(b)
@ -1861,6 +1879,7 @@ function open_options(self)
current_new_game_plus = math.clamp(current_new_game_plus + 1, 0, new_game_plus)
state.current_new_game_plus = current_new_game_plus
self.ng_t.text:set_text({{text = '[bg10]current: ' .. current_new_game_plus, font = pixul_font, alignment = 'center'}})
max_units = 7 + current_new_game_plus
end}
end

View File

@ -1005,7 +1005,6 @@ function Player:init(args)
local unit = random:table(units)
unit.enchanted_aspd_m = (self.enchanted == 1 and 1.33) or (self.enchanted == 2 and 1.66) or (self.enchanted == 3 and 1.99)
end
end)
end
@ -1040,15 +1039,15 @@ function Player:init(args)
if self.leader and self.shoot_5 then
main.current.t:after(0.1, function()
self.t:every(0.33, function()
local units = self:get_all_units()
main.current.t:every(0.33, function()
local units = main.current.player:get_all_units()
local unit = units[5]
if unit then
local target = unit:get_closest_object_in_shape(Circle(unit.x, unit.y, 96), main.current.enemies)
if target then
unit:barrage(unit:angle_to_object(target), 1)
unit:barrage(unit:angle_to_object(target), 1, nil, nil, true)
else
unit:barrage(random:float(0, 2*math.pi), 1)
unit:barrage(random:float(0, 2*math.pi), 1, nil, nil, true)
end
end
end)
@ -1057,9 +1056,9 @@ function Player:init(args)
if self.leader and self.death_6 then
main.current.t:after(0.1, function()
self.t:every(3, function()
main.current.t:every(3, function()
flagellant1:play{pitch = random:float(0.95, 1.05), volume = 0.4}
local units = self:get_all_units()
local units = main.current.player:get_all_units()
local unit = units[6]
if unit then
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.4}
@ -1284,7 +1283,7 @@ function Player:update(dt)
if self.haste then
if self.hasted then
self.haste_mvspd_m = math.remap(love.timer.getTime() - self.hasted, 0, 4, 1.5, 1)
self.haste_mvspd_m = math.clamp(math.remap(love.timer.getTime() - self.hasted, 0, 4, 1.5, 1), 1, 1.5)
else self.haste_mvspd_m = 1 end
end
@ -1552,7 +1551,7 @@ function Player:hit(damage, from_undead)
elseif self.lasting_7 and self.follower_index == 6 and not self.undead then
self.undead = true
self.t:after(10, function() self:hit(0, true) end)
self.t:after(10, function() self:hit(10000, true) end)
else
hit4:play{pitch = random:float(0.95, 1.05), volume = 0.5}
@ -1887,14 +1886,15 @@ function Player:dot_attack(area, mods)
end
function Player:barrage(r, n, pierce, ricochet)
function Player:barrage(r, n, pierce, ricochet, shoot_5)
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}
if shoot_5 then archer1:play{pitch = random:float(0.95, 1.05), volume = 0.2}
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}
parent = self, character = 'barrage', level = self.level, pierce = pierce or 0, ricochet = ricochet or 0, shoot_5 = shoot_5}
Projectile(table.merge(t, mods or {}))
end)
end
@ -3659,7 +3659,8 @@ function Critter:die(x, y, r, n)
if main.current.player.baneling_burst then
camera:shake(2, 0.5)
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*24, color = self.color, dmg = self.parent.dmg*self.parent.area_dmg_m*0.25, parent = self.parent}
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.parent.area_size_m*24, color = self.color,
dmg = (main.current.player.baneling_burst == 1 and 50) or (main.current.player.baneling_burst == 2 and 100) or (main.current.player.baneling_burst == 3 and 150) or 0, parent = self.parent}
_G[random:table{'cannoneer1', 'cannoneer2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
end
end

38
todo
View File

@ -32,6 +32,7 @@ Loop Update
Some solution that:
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
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
@ -46,32 +47,28 @@ Loop Update
Snake size goes up by 1 every loop, up to 12
Don't offer items if item slots are full
QoL
Selling items
Your party + items on end, death and passive screens - https://i.imgur.com/JJUddT3.png
Increase item choice slots to 4
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
remove already owned lvl 3 unit from shop...
Items on end screen
Party + items on death screen
* Items on passive screen
* Selling items
* Decreased sound effect volume for shoot 5
Bug fixes
Fixed a series of crashes that happened rarely right before changing from the arena back to the shop
https://i.imgur.com/Rk6qbDD.png - merchant doesnt give reroll if dies
https://i.imgur.com/1soUUdk.png - 5th position stops shooting when 1-4 die
https://i.imgur.com/G9DosVw.png - lasting 7 bug
https://i.imgur.com/8he1WDm.png - infinite money
https://i.imgur.com/0wZ5wma.png - max unit bugged when changing ng mid run, https://i.imgur.com/qrExpq5.png
https://i.imgur.com/Ad13Cyo.png
if undead from lasting 7 gets healed it becomes immortal
engine/game/group.lua:256: attempt to index local 'shape' (a nil value)
Traceback engine/game/group.lua:256: in function 'get_objects_in_shape' engine/game/physics.lua:264: in function 'get_objects_in_shape' player.lua:3386: in function 'update'
https://i.imgur.com/s4ZFE6z.png
https://i.imgur.com/VL8lOXm.png
bug with "party x/y" showing wrong numbers
https://i.imgur.com/sxwS8et.png
Close button on credits
https://i.imgur.com/O5zJNc7.png
https://i.imgur.com/cQl0VYp.png
* 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
* Fixed undying unit from lasting 7 being able to become immortal if it was healed during the 10 seconds before it truly died
* Fixed a bug where max units wouldn't be properly changed when changing NG difficulty in the menu
* Fixed Whispers of Doom applying before curses, now it applies after and triggers their effect when enemies are killed due to it
* Fixed mobile users not being able to close the credits screen due to there being no close button
* Fixed shop party numbers not being updated when units are bought or sold
* Fixed a bug where movement speed would become zero if the game was paused while under the effects of decaying haste
* Fixed baneling burst not dealing the correct amount of damage
---
@ -111,6 +108,7 @@ https://steamcommunity.com/app/915310/discussions/0/4658391921156086711/ - gener
https://steamcommunity.com/app/915310/discussions/0/4658391921156325745/ - math on gold, rerolls and units
https://steamcommunity.com/app/915310/discussions/0/3069747783686815659/ - general feedback
https://steamcommunity.com/app/915310/discussions/0/3069747783688708231/ - general feedback
https://steamcommunity.com/app/915310/discussions/0/3046104862443040220/ - general feedback
Challenge mode
Units die permanently when they die
Slower scaling with less individually threatening units