diff --git a/lovely/atlas.toml b/lovely/atlas.toml index 292960282..89afcba03 100644 --- a/lovely/atlas.toml +++ b/lovely/atlas.toml @@ -39,19 +39,3 @@ payload = ''' _atlas = G.ASSET_ATLAS[_smods_atlas] or _atlas end''' -## Hide floating ? from undiscovered types -# Card:draw() -[[patches]] -[patches.pattern] -target = 'card.lua' -pattern = '''shared_sprite:draw_shader('dissolve', nil, nil, nil, self.children.center, scale_mod, rotate_mod)''' -position = 'at' -match_indent = true -payload = ''' -if (self.config.center.undiscovered and not self.config.center.undiscovered.no_overlay) or not( SMODS.UndiscoveredSprites[self.ability.set] and SMODS.UndiscoveredSprites[self.ability.set].no_overlay) then - shared_sprite:draw_shader('dissolve', nil, nil, nil, self.children.center, scale_mod, rotate_mod) -else - if SMODS.UndiscoveredSprites[self.ability.set] and SMODS.UndiscoveredSprites[self.ability.set].overlay_sprite then - SMODS.UndiscoveredSprites[self.ability.set].overlay_sprite:draw_shader('dissolve', nil, nil, nil, self.children.center, scale_mod, rotate_mod) - end -end''' diff --git a/lovely/center.toml b/lovely/center.toml index c171219fa..bf444ba25 100644 --- a/lovely/center.toml +++ b/lovely/center.toml @@ -466,47 +466,6 @@ payload = ''' end ''' -# Card:draw() -[[patches]] -[patches.pattern] -target = 'card.lua' -pattern = '--If the card has any edition/seal, add that here' -position = 'before' -match_indent = true -payload = ''' -local center = self.config.center -if center.draw and type(center.draw) == 'function' then - center:draw(self, layer) -end -if center.set == 'Default' or center.set == 'Enhanced' and not center.replace_base_card then - if not center.no_suit then - local suit = SMODS.Suits[self.base.suit] or {} - if suit.draw and type(suit.draw) == 'function' then - suit:draw(self, layer) - end - end - if not center.no_rank then - local rank = SMODS.Ranks[self.base.value] or {} - if rank.draw and type(rank.draw) == 'function' then - rank:draw(self, layer) - end - end -end -''' - -[[patches]] -[patches.pattern] -target = 'card.lua' -pattern = 'if self.seal then' -position = 'at' -match_indent = true -payload = ''' -local seal = G.P_SEALS[self.seal or {}] or {} -if type(seal.draw) == 'function' then - seal:draw(self, layer) -elseif self.seal then -''' - # no_blueprint check [[patches]] [patches.pattern] diff --git a/lovely/edition.toml b/lovely/edition.toml index ccf477cbf..d03dbce9d 100644 --- a/lovely/edition.toml +++ b/lovely/edition.toml @@ -93,114 +93,6 @@ for _, v in ipairs(G.P_CENTER_POOLS.Edition) do G.BADGE_COL[v.key:sub(3)] = v.badge_colour end''' -# Limit ARGS.send_to_shader[1] to wiggle between 0 and 2 instead of growing infinitely -# this makes shaders responsiveness on tilt reliable over time -# Card:draw() -[[patches]] -[patches.regex] -target = "card.lua" -pattern = ''' -G\.TIMERS\.REAL/\(28\)''' -position = "at" -payload = '''math.sin(G.TIMERS.REAL/28) + 1''' - -# Allow editions to not draw shadow -# Card:draw() -[[patches]] -[patches.regex] -target = "card.lua" -pattern = ''' -self\.ability\.effect ~= 'Glass Card' and not self\.greyed''' -position = "after" -payload = ''' and self:should_draw_shadow() ''' - -# If shader modifies shape of card, this will stop "back" layer of the card being rendered. -# Card:draw() -[[patches]] -[patches.pattern] -target = "card.lua" -pattern = ''' -elseif not self.greyed then''' -position = "before" -payload = ''' -elseif not self:should_draw_base_shader() then - -- Don't render base dissolve shader. -''' -match_indent = true - -# If shader modifies shape of card, this will stop "back" layer of the card being rendered. -# spectral cards and booster packs only. -# Card:draw() -[[patches]] -[patches.pattern] -target = "card.lua" -pattern = ''' -if self.ability.set == 'Booster' or self.ability.set == 'Spectral' then''' -position = "at" -payload = ''' -if (self.ability.set == 'Booster' or self.ability.set == 'Spectral') and self:should_draw_base_shader() then''' -match_indent = true - -# If shader modifies shape of card, this will stop "back" layer of the card being rendered. -# invisible joker and vouchers. -# Card:draw() -[[patches]] -[patches.pattern] -target = "card.lua" -pattern = ''' -self.children.center:draw_shader('voucher', nil, self.ARGS.send_to_shader)''' -position = "at" -payload = ''' -if self:should_draw_base_shader() then - self.children.center:draw_shader('voucher', nil, self.ARGS.send_to_shader) -end''' -match_indent = true - -# Inject shaders applying to cards -# Card:draw() -[[patches]] -[patches.regex] -target = "card.lua" -pattern = ''' -(?[\t ]*)if self\.edition and self\.editi[A-z\.\:\n\t _(',)~=]*me', nil, self.ARGS.send_to_shader\) -[\t ]*end -[\t ]*end''' -position = "at" -payload = ''' -if self.edition then - for k, v in pairs(G.P_CENTER_POOLS.Edition) do - if self.edition[v.key:sub(3)] and v.shader then - if type(v.draw) == 'function' then - v:draw(self, layer) - else - self.children.center:draw_shader(v.shader, nil, self.ARGS.send_to_shader) - if self.children.front and self.ability.effect ~= 'Stone Card' and not self.config.center.replace_base_card then - self.children.front:draw_shader(v.shader, nil, self.ARGS.send_to_shader) - end - end - end - end -end''' -line_prepend = "$indent" - -# Inject shaders applying to floating sprites -[[patches]] -[patches.pattern] -target = "card.lua" -pattern = "self.children.floating_sprite:draw_shader('dissolve', nil, nil, nil, self.children.center, scale_mod, rotate_mod)" -position = "after" -payload = ''' -if self.edition then - for k, v in pairs(G.P_CENTER_POOLS.Edition) do - if v.apply_to_float then - if self.edition[v.key:sub(3)] then - self.children.floating_sprite:draw_shader(v.shader, nil, nil, nil, self.children.center, scale_mod, rotate_mod) - end - end - end -end''' -match_indent = true - # Remove prefix from shader key when calling send() [[patches]] [patches.pattern] diff --git a/lovely/enhancement.toml b/lovely/enhancement.toml index b831bc44c..2c340a0df 100644 --- a/lovely/enhancement.toml +++ b/lovely/enhancement.toml @@ -142,17 +142,6 @@ payload = """if not SMODS.has_no_suit(scoring_hand[i]) then G.GAME.cards_played[scoring_hand[i].base.value].suits[scoring_hand[i].base.suit] = true end""" - -## replace_base_card -# Determines whether to draw the base card's front or not -# Card:draw() -[[patches]] -[patches.pattern] -target = "card.lua" -pattern = "if self.children.front and self.ability.effect ~= 'Stone Card' then" -match_indent = true -position = "at" -payload = "if self.children.front and (self.ability.delayed or (self.ability.effect ~= 'Stone Card' and not self.config.center.replace_base_card)) then" # Add the delayed property to sprites that are delayed [[patches]] [patches.pattern] diff --git a/lovely/fixes.toml b/lovely/fixes.toml index 4917c653f..7eca2f906 100644 --- a/lovely/fixes.toml +++ b/lovely/fixes.toml @@ -467,31 +467,6 @@ pattern = "for _, v in pairs(G.I.SPRITE) do" position = "at" payload = 'for k, v in pairs(G.I.SPRITE) do' -## -## Card:draw() - improved mod compatibility -## -# Add option for sprites to not be drawn -[[patches]] -[patches.pattern] -target = "card.lua" -match_indent = true -pattern = ''' -if k ~= 'focused_ui' and k ~= "front" and k ~= "back" and k ~= "soul_parts" and k ~= "center" and k ~= 'floating_sprite' and k~= "shadow" and k~= "use_button" and k ~= 'buy_button' and k ~= 'buy_and_use_button' and k~= "debuff" and k ~= 'price' and k~= 'particles' and k ~= 'h_popup' then v:draw() end''' -position = "at" -payload = ''' -if not v.custom_draw and k ~= 'focused_ui' and k ~= "front" and k ~= "back" and k ~= "soul_parts" and k ~= "center" and k ~= 'floating_sprite' and k~= "shadow" and k~= "use_button" and k ~= 'buy_button' and k ~= 'buy_and_use_button' and k~= "debuff" and k ~= 'price' and k~= 'particles' and k ~= 'h_popup' then v:draw() end''' - -# This check is not necessary? -[[patches]] -[patches.pattern] -target = "card.lua" -match_indent = true -pattern = ''' -if self.edition or self.seal or self.ability.eternal or self.ability.rental or self.ability.perishable or self.sticker or ((self.sticker_run and self.sticker_run ~= 'NONE') and G.SETTINGS.run_stake_stickers) or (self.ability.set == 'Spectral') or self.debuff or self.greyed or (self.ability.name == 'The Soul') or (self.ability.set == 'Voucher') or (self.ability.set == 'Booster') or self.config.center.soul_pos or self.config.center.demo then''' -position = "at" -payload = ''' -if true then''' - ## Make vanilla enhancement jokers work with extra enhancements # Steel Joker diff --git a/lovely/sticker.toml b/lovely/sticker.toml index 92e329c58..f251f2cf6 100644 --- a/lovely/sticker.toml +++ b/lovely/sticker.toml @@ -88,27 +88,6 @@ position = "at" match_indent = true payload = '''if G.GAME.modifiers.enable_rentals_in_shop and pseudorandom((area == G.pack_cards and 'packssjr' or 'ssjr')..G.GAME.round_resets.ante) > 0.7 and not SMODS.Stickers["rental"].should_apply then''' -# Card:draw() -[[patches]] -[patches.pattern] -target = "card.lua" -pattern = '''if self.ability.name == 'The Soul' and (self.config.center.discovered or self.bypass_discovery_center) then''' -match_indent = true -position = "before" -payload = ''' -for k, v in pairs(SMODS.Stickers) do - if self.ability[v.key] then - if v and v.draw and type(v.draw) == 'function' then - v:draw(self, layer) - else - G.shared_stickers[v.key].role.draw_major = self - G.shared_stickers[v.key]:draw_shader('dissolve', nil, nil, nil, self.children.center) - G.shared_stickers[v.key]:draw_shader('voucher', nil, self.ARGS.send_to_shader, nil, self.children.center) - end - end -end -''' - # get_badge_colour() [[patches]] [patches.pattern] diff --git a/src/card_draw.lua b/src/card_draw.lua new file mode 100644 index 000000000..d5970ed60 --- /dev/null +++ b/src/card_draw.lua @@ -0,0 +1,455 @@ +SMODS.DrawSteps = {} +SMODS.DrawStep = SMODS.GameObject:extend { + obj_table = SMODS.DrawSteps, + obj_buffer = {}, + required_params = { + 'key', + 'order', + 'func', + }, + layers = { + card = true, + both = true, + }, + -- func = function(card, layer) end, + inject = function() end, + post_inject_class = function(self) + table.sort(self.obj_buffer, function(_self, _other) return self.obj_table[_self].order < self.obj_table[_other].order end) + end, + conditions = {}, + check_individual_condition = function(self, card, layer, k, v) + if k == 'vortex' then return not not card.vortex == v end + if k == 'facing' then return card.sprite_facing == v end + return true + end, + check_conditions = function(self, card, layer) + if not self.layers[layer] then return end + for k,v in pairs(self.conditions) do + if not self:check_individual_condition(card, layer, k, v) then return end + end + return true + end +} + +SMODS.DrawStep { + key = 'shadow', + order = -1000, + layers = { shadow = true, both = true }, + func = function(self) + self.ARGS.send_to_shader = self.ARGS.send_to_shader or {} + self.ARGS.send_to_shader[1] = math.min(self.VT.r*3, 1) + math.sin(G.TIMERS.REAL/28) + 1 + (self.juice and self.juice.r*20 or 0) + self.tilt_var.amt + self.ARGS.send_to_shader[2] = G.TIMERS.REAL + + for k, v in pairs(self.children) do + v.VT.scale = self.VT.scale + end + + G.shared_shadow = self.sprite_facing == 'front' and self.children.center or self.children.back + + --Draw the shadow + if not self.no_shadow and G.SETTINGS.GRAPHICS.shadows == 'On' and((self.ability.effect ~= 'Glass Card' and not self.greyed and self:should_draw_shadow() ) and ((self.area and self.area ~= G.discard and self.area.config.type ~= 'deck') or not self.area or self.states.drag.is)) then + self.shadow_height = 0*(0.08 + 0.4*math.sqrt(self.velocity.x^2)) + ((((self.highlighted and self.area == G.play) or self.states.drag.is) and 0.35) or (self.area and self.area.config.type == 'title_2') and 0.04 or 0.1) + G.shared_shadow:draw_shader('dissolve', self.shadow_height) + end + end, +} + +SMODS.DrawStep { + key = 'focused_ui_1', + order = -100, + func = function(self) + if self.area ~= G.hand then + if self.children.focused_ui then self.children.focused_ui:draw() end + end + end, +} + +SMODS.DrawStep { + key = 'tilt', + order = -50, + func = function(self) + -- for all hover/tilting: + self.tilt_var = self.tilt_var or {mx = 0, my = 0, dx = self.tilt_var.dx or 0, dy = self.tilt_var.dy or 0, amt = 0} + local tilt_factor = 0.3 + if self.states.focus.is then + self.tilt_var.mx, self.tilt_var.my = G.CONTROLLER.cursor_position.x + self.tilt_var.dx*self.T.w*G.TILESCALE*G.TILESIZE, G.CONTROLLER.cursor_position.y + self.tilt_var.dy*self.T.h*G.TILESCALE*G.TILESIZE + self.tilt_var.amt = math.abs(self.hover_offset.y + self.hover_offset.x - 1 + self.tilt_var.dx + self.tilt_var.dy - 1)*tilt_factor + elseif self.states.hover.is then + self.tilt_var.mx, self.tilt_var.my = G.CONTROLLER.cursor_position.x, G.CONTROLLER.cursor_position.y + self.tilt_var.amt = math.abs(self.hover_offset.y + self.hover_offset.x - 1)*tilt_factor + elseif self.ambient_tilt then + local tilt_angle = G.TIMERS.REAL*(1.56 + (self.ID/1.14212)%1) + self.ID/1.35122 + self.tilt_var.mx = ((0.5 + 0.5*self.ambient_tilt*math.cos(tilt_angle))*self.VT.w+self.VT.x+G.ROOM.T.x)*G.TILESIZE*G.TILESCALE + self.tilt_var.my = ((0.5 + 0.5*self.ambient_tilt*math.sin(tilt_angle))*self.VT.h+self.VT.y+G.ROOM.T.y)*G.TILESIZE*G.TILESCALE + self.tilt_var.amt = self.ambient_tilt*(0.5+math.cos(tilt_angle))*tilt_factor + end + end, +} + +SMODS.DrawStep { + key = 'particles', + order = -40, + func = function(self) + --Any particles + if self.children.particles then self.children.particles:draw() end + end, +} + +SMODS.DrawStep { + key = 'tags_buttons', + order = -30, + func = function(self) + --Draw any tags/buttons + if self.children.price then self.children.price:draw() end + if self.children.buy_button then + if self.highlighted then + self.children.buy_button.states.visible = true + self.children.buy_button:draw() + if self.children.buy_and_use_button then + self.children.buy_and_use_button:draw() + end + else + self.children.buy_button.states.visible = false + end + end + if self.children.use_button and self.highlighted then self.children.use_button:draw() end + end, +} + +SMODS.DrawStep { + key = 'vortex', + order = -20, + func = function(self) + if self.facing == 'back' then + self.children.back:draw_shader('vortex') + else + self.children.center:draw_shader('vortex') + if self.children.front then + self.children.front:draw_shader('vortex') + end + end + + love.graphics.setShader() + end, + conditions = { vortex = true }, +} + +SMODS.DrawStep { + key = 'center', + order = -10, + func = function(self, layer) + --Draw the main part of the card + if (self.edition and self.edition.negative) or (self.ability.name == 'Antimatter' and (self.config.center.discovered or self.bypass_discovery_center)) then + self.children.center:draw_shader('negative', nil, self.ARGS.send_to_shader) + elseif not self:should_draw_base_shader() then + -- Don't render base dissolve shader. + elseif not self.greyed then + self.children.center:draw_shader('dissolve') + end + + --If the card is not yet discovered + if not self.config.center.discovered and (self.ability.consumeable or self.config.center.unlocked) and not self.config.center.demo and not self.bypass_discovery_center then + local shared_sprite = (self.ability.set == 'Edition' or self.ability.set == 'Joker') and G.shared_undiscovered_joker or G.shared_undiscovered_tarot + local scale_mod = -0.05 + 0.05*math.sin(1.8*G.TIMERS.REAL) + local rotate_mod = 0.03*math.sin(1.219*G.TIMERS.REAL) + + shared_sprite.role.draw_major = self + if (self.config.center.undiscovered and not self.config.center.undiscovered.no_overlay) or not( SMODS.UndiscoveredSprites[self.ability.set] and SMODS.UndiscoveredSprites[self.ability.set].no_overlay) then + shared_sprite:draw_shader('dissolve', nil, nil, nil, self.children.center, scale_mod, rotate_mod) + else + if SMODS.UndiscoveredSprites[self.ability.set] and SMODS.UndiscoveredSprites[self.ability.set].overlay_sprite then + SMODS.UndiscoveredSprites[self.ability.set].overlay_sprite:draw_shader('dissolve', nil, nil, nil, self.children.center, scale_mod, rotate_mod) + end + end + end + + if self.ability.name == 'Invisible Joker' and (self.config.center.discovered or self.bypass_discovery_center) then + if self:should_draw_base_shader() then + self.children.center:draw_shader('voucher', nil, self.ARGS.send_to_shader) + end + end + + local center = self.config.center + if center.draw and type(center.draw) == 'function' then + center:draw(self, layer) + end + end, + conditions = { vortex = false, facing = 'front' }, +} + +SMODS.DrawStep { + key = 'front', + order = 0, + func = function(self, layer) + --Draw the main part of the card + if (self.edition and self.edition.negative) or (self.ability.name == 'Antimatter' and (self.config.center.discovered or self.bypass_discovery_center)) then + if self.children.front and (self.ability.delayed or (self.ability.effect ~= 'Stone Card' and not self.config.center.replace_base_card)) then + self.children.front:draw_shader('negative', nil, self.ARGS.send_to_shader) + end + elseif not self:should_draw_base_shader() then + -- Don't render base dissolve shader. + elseif not self.greyed then + if self.children.front and (self.ability.delayed or (self.ability.effect ~= 'Stone Card' and not self.config.center.replace_base_card)) then + self.children.front:draw_shader('dissolve') + end + end + + local center = self.config.center + if center.set == 'Default' or center.set == 'Enhanced' and not center.replace_base_card then + if not center.no_suit then + local suit = SMODS.Suits[self.base.suit] or {} + if suit.draw and type(suit.draw) == 'function' then + suit:draw(self, layer) + end + end + if not center.no_rank then + local rank = SMODS.Ranks[self.base.value] or {} + if rank.draw and type(rank.draw) == 'function' then + rank:draw(self, layer) + end + end + end + end, + conditions = { vortex = false, facing = 'front' }, +} +SMODS.DrawStep { + key = 'card_type_shader', + order = 10, + func = function(self) + if (self.ability.set == 'Voucher' or self.config.center.demo) and (self.ability.name ~= 'Antimatter' or not (self.config.center.discovered or self.bypass_discovery_center)) then + if self:should_draw_base_shader() then + self.children.center:draw_shader('voucher', nil, self.ARGS.send_to_shader) + end + end + if (self.ability.set == 'Booster' or self.ability.set == 'Spectral') and self:should_draw_base_shader() then + self.children.center:draw_shader('booster', nil, self.ARGS.send_to_shader) + end + end, + conditions = { vortex = false, facing = 'front' }, +} + +SMODS.DrawStep { + key = 'edition', + order = 20, + func = function(self, layer) + if self.edition then + for k, v in pairs(G.P_CENTER_POOLS.Edition) do + if self.edition[v.key:sub(3)] and v.shader then + if type(v.draw) == 'function' then + v:draw(self, layer) + else + self.children.center:draw_shader(v.shader, nil, self.ARGS.send_to_shader) + if self.children.front and self.ability.effect ~= 'Stone Card' and not self.config.center.replace_base_card then + self.children.front:draw_shader(v.shader, nil, self.ARGS.send_to_shader) + end + end + end + end + end + if (self.edition and self.edition.negative) or (self.ability.name == 'Antimatter' and (self.config.center.discovered or self.bypass_discovery_center)) then + self.children.center:draw_shader('negative_shine', nil, self.ARGS.send_to_shader) + end + end, + conditions = { vortex = false, facing = 'front' }, +} + +SMODS.DrawStep { + key = 'seal', + order = 30, + func = function(self, layer) + local seal = G.P_SEALS[self.seal] or {} + if type(seal.draw) == 'function' then + seal:draw(self, layer) + elseif self.seal then + G.shared_seals[self.seal].role.draw_major = self + G.shared_seals[self.seal]:draw_shader('dissolve', nil, nil, nil, self.children.center) + if self.seal == 'Gold' then G.shared_seals[self.seal]:draw_shader('voucher', nil, self.ARGS.send_to_shader, nil, self.children.center) end + end + end, + conditions = { vortex = false, facing = 'front' }, +} + +SMODS.DrawStep { + key = 'stickers', + order = 40, + func = function(self, layer) + if self.sticker and G.shared_stickers[self.sticker] then + G.shared_stickers[self.sticker].role.draw_major = self + G.shared_stickers[self.sticker]:draw_shader('dissolve', nil, nil, nil, self.children.center) + G.shared_stickers[self.sticker]:draw_shader('voucher', nil, self.ARGS.send_to_shader, nil, self.children.center) + elseif (self.sticker_run and G.shared_stickers[self.sticker_run]) and G.SETTINGS.run_stake_stickers then + G.shared_stickers[self.sticker_run].role.draw_major = self + G.shared_stickers[self.sticker_run]:draw_shader('dissolve', nil, nil, nil, self.children.center) + G.shared_stickers[self.sticker_run]:draw_shader('voucher', nil, self.ARGS.send_to_shader, nil, self.children.center) + end + + for k, v in pairs(SMODS.Stickers) do + if self.ability[v.key] then + if v and v.draw and type(v.draw) == 'function' then + v:draw(self, layer) + else + G.shared_stickers[v.key].role.draw_major = self + G.shared_stickers[v.key]:draw_shader('dissolve', nil, nil, nil, self.children.center) + G.shared_stickers[v.key]:draw_shader('voucher', nil, self.ARGS.send_to_shader, nil, self.children.center) + end + end + end + end, + conditions = { vortex = false, facing = 'front' }, +} + +SMODS.DrawStep { + key = 'soul', + order = 50, + func = function(self) + if self.ability.name == 'The Soul' and (self.config.center.discovered or self.bypass_discovery_center) then + local scale_mod = 0.05 + 0.05*math.sin(1.8*G.TIMERS.REAL) + 0.07*math.sin((G.TIMERS.REAL - math.floor(G.TIMERS.REAL))*math.pi*14)*(1 - (G.TIMERS.REAL - math.floor(G.TIMERS.REAL)))^3 + local rotate_mod = 0.1*math.sin(1.219*G.TIMERS.REAL) + 0.07*math.sin((G.TIMERS.REAL)*math.pi*5)*(1 - (G.TIMERS.REAL - math.floor(G.TIMERS.REAL)))^2 + + G.shared_soul.role.draw_major = self + G.shared_soul:draw_shader('dissolve',0, nil, nil, self.children.center,scale_mod, rotate_mod,nil, 0.1 + 0.03*math.sin(1.8*G.TIMERS.REAL),nil, 0.6) + G.shared_soul:draw_shader('dissolve', nil, nil, nil, self.children.center, scale_mod, rotate_mod) + end + end, + conditions = { vortex = false, facing = 'front' }, +} + +SMODS.DrawStep { + key = 'floating_sprite', + order = 60, + func = function(self) + if self.config.center.soul_pos and (self.config.center.discovered or self.bypass_discovery_center) then + local scale_mod = 0.07 + 0.02*math.sin(1.8*G.TIMERS.REAL) + 0.00*math.sin((G.TIMERS.REAL - math.floor(G.TIMERS.REAL))*math.pi*14)*(1 - (G.TIMERS.REAL - math.floor(G.TIMERS.REAL)))^3 + local rotate_mod = 0.05*math.sin(1.219*G.TIMERS.REAL) + 0.00*math.sin((G.TIMERS.REAL)*math.pi*5)*(1 - (G.TIMERS.REAL - math.floor(G.TIMERS.REAL)))^2 + + if type(self.config.center.soul_pos.draw) == 'function' then + self.config.center.soul_pos.draw(self, scale_mod, rotate_mod) + elseif self.ability.name == 'Hologram' then + self.hover_tilt = self.hover_tilt*1.5 + self.children.floating_sprite:draw_shader('hologram', nil, self.ARGS.send_to_shader, nil, self.children.center, 2*scale_mod, 2*rotate_mod) + self.hover_tilt = self.hover_tilt/1.5 + else + self.children.floating_sprite:draw_shader('dissolve',0, nil, nil, self.children.center,scale_mod, rotate_mod,nil, 0.1 + 0.03*math.sin(1.8*G.TIMERS.REAL),nil, 0.6) + self.children.floating_sprite:draw_shader('dissolve', nil, nil, nil, self.children.center, scale_mod, rotate_mod) + end + if self.edition then + for k, v in pairs(G.P_CENTER_POOLS.Edition) do + if v.apply_to_float then + if self.edition[v.key:sub(3)] then + self.children.floating_sprite:draw_shader(v.shader, nil, nil, nil, self.children.center, scale_mod, rotate_mod) + end + end + end + end + end + end, + conditions = { vortex = false, facing = 'front' }, +} + +SMODS.DrawStep { + key = 'debuff', + order = 70, + func = function(self) + if self.debuff then + self.children.center:draw_shader('debuff', nil, self.ARGS.send_to_shader) + if self.children.front and (self.ability.delayed or (self.ability.effect ~= 'Stone Card' and not self.config.center.replace_base_card)) then + self.children.front:draw_shader('debuff', nil, self.ARGS.send_to_shader) + end + end + end, + conditions = { vortex = false, facing = 'front' }, +} + +SMODS.DrawStep { + key = 'greyed', + order = 80, + func = function(self) + if self.greyed then + self.children.center:draw_shader('played', nil, self.ARGS.send_to_shader) + if self.children.front and (self.ability.delayed or (self.ability.effect ~= 'Stone Card' and not self.config.center.replace_base_card)) then + self.children.front:draw_shader('played', nil, self.ARGS.send_to_shader) + end + end + end, + conditions = { vortex = false, facing = 'front' }, +} + +SMODS.DrawStep { + key = 'back', + order = 0, + func = function(self) + local overlay = G.C.WHITE + if self.area and self.area.config.type == 'deck' and self.rank > 3 then + self.back_overlay = self.back_overlay or {} + self.back_overlay[1] = 0.5 + ((#self.area.cards - self.rank)%7)/50 + self.back_overlay[2] = 0.5 + ((#self.area.cards - self.rank)%7)/50 + self.back_overlay[3] = 0.5 + ((#self.area.cards - self.rank)%7)/50 + self.back_overlay[4] = 1 + overlay = self.back_overlay + end + + if self.area and self.area.config.type == 'deck' then + self.children.back:draw(overlay) + else + self.children.back:draw_shader('dissolve') + end + end, + conditions = { vortex = false, facing = 'back' }, +} + +SMODS.DrawStep { + key = 'back_sticker', + order = 10, + func = function(self) + if self.sticker and G.shared_stickers[self.sticker] then + G.shared_stickers[self.sticker].role.draw_major = self + local sticker_offset = self.sticker_offset or {} + G.shared_stickers[self.sticker]:draw_shader('dissolve', nil, nil, true, self.children.center, nil, self.sticker_rotation, sticker_offset.x, sticker_offset.y) + local stake = G.P_STAKES['stake_'..string.lower(self.sticker)] or {} + if stake.shiny then G.shared_stickers[self.sticker]:draw_shader('voucher', nil, self.ARGS.send_to_shader, true, self.children.center) end + end + end, + conditions = { vortex = false, facing = 'back' }, +} + +-- All keys in this table will not be automatically drawn with a default `draw()` call in the "others" DrawStep. +SMODS.draw_ignore_keys = { + focused_ui = true, front = true, back = true, soul_parts = true, center = true, floating_sprite = true, shadow = true, use_button = true, buy_button = true, buy_and_use_button = true, debuff = true, price = true, particles = true, h_popup = true +} +SMODS.DrawStep { + key = 'others', + order = 90, + func = function(self) + for k, v in pairs(self.children) do + if not v.custom_draw and not SMODS.draw_ignore_keys[k] then v:draw() end + end + end, +} + +SMODS.DrawStep { + key = 'focused_ui_2', + order = 100, + func = function(self) + if self.area == G.hand then + if self.children.focused_ui then self.children.focused_ui:draw() end + end + end, +} + +SMODS.DrawStep { + key = 'drawhash_boundingrect', + order = 1000, + func = function(self) + add_to_drawhash(self) + self:draw_boundingrect() + end, +} + +function Card:draw(layer) + layer = layer or 'both' + self.hover_tilt = 1 + if not self.states.visible then return end + for _, k in ipairs(SMODS.DrawStep.obj_buffer) do + if SMODS.DrawSteps[k]:check_conditions(self, layer) then SMODS.DrawSteps[k].func(self, layer) end + end +end \ No newline at end of file diff --git a/src/game_object.lua b/src/game_object.lua index adc130bc0..674bcb448 100644 --- a/src/game_object.lua +++ b/src/game_object.lua @@ -729,7 +729,7 @@ Set `prefix_config.key = false` on your object instead.]]):format(obj.key), obj. G.GAME.modifiers.enable_perishables_in_shop = true end, colour = G.C.ORANGE, - loc_txt = {} + loc_txt = {}, } SMODS.Stake { name = "Gold Stake", @@ -3265,6 +3265,12 @@ Set `prefix_config.key = false` on your object instead.]]):format(obj.key), obj. end, } + ------------------------------------------------------------------------------------------------- + ----- API IMPORT GameObject.DrawStep + ------------------------------------------------------------------------------------------------- + + assert(load(NFS.read(SMODS.path..'src/card_draw.lua'), ('=[SMODS _ "src/card_draw.lua"]')))() + ------------------------------------------------------------------------------------------------- ----- INTERNAL API CODE GameObject._Loc_Post -------------------------------------------------------------------------------------------------