From b20a17b004080926fa39c2ea04c1d40eab020940 Mon Sep 17 00:00:00 2001 From: yjyscztr <167316899+yjyscztr@users.noreply.github.com> Date: Wed, 10 Jul 2024 17:15:42 +0800 Subject: [PATCH] Add files via upload --- soulcraft/assets/1x/enhance_crystal.png | Bin 0 -> 5444 bytes soulcraft/assets/1x/soul_crystal.png | Bin 0 -> 5636 bytes soulcraft/assets/2x/enhance_crystal.png | Bin 0 -> 5617 bytes soulcraft/assets/2x/soul_crystal.png | Bin 0 -> 5786 bytes soulcraft/soulcraft.lua | 1623 +++++++++++++++++++++++ soulcraftlovely/lovely.toml | 7 +- 6 files changed, 1626 insertions(+), 4 deletions(-) create mode 100644 soulcraft/assets/1x/enhance_crystal.png create mode 100644 soulcraft/assets/1x/soul_crystal.png create mode 100644 soulcraft/assets/2x/enhance_crystal.png create mode 100644 soulcraft/assets/2x/soul_crystal.png create mode 100644 soulcraft/soulcraft.lua diff --git a/soulcraft/assets/1x/enhance_crystal.png b/soulcraft/assets/1x/enhance_crystal.png new file mode 100644 index 0000000000000000000000000000000000000000..38e494ae06407930ba9abafddec7c4864c8aa847 GIT binary patch literal 5444 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 literal 0 HcmV?d00001 diff --git a/soulcraft/soulcraft.lua b/soulcraft/soulcraft.lua new file mode 100644 index 0000000..4d24503 --- /dev/null +++ b/soulcraft/soulcraft.lua @@ -0,0 +1,1623 @@ +--- STEAMODDED HEADER +--- MOD_NAME: Soulcraft +--- MOD_ID: soulcraft +--- MOD_AUTHOR: [AMADEUS] +--- MOD_DESCRIPTION: enhance your jokers by souls +--- BADGE_COLOUR: CC99FF +------------------------------ +---------------------------------------------- +------------MOD CODE ------------------------- +function SMODS.INIT.soulcraft() + + G.localization.misc.dictionary["b_break"] = "分解" + G.localization.misc.dictionary["b_upgrade"] = "升级" + G.localization.misc.dictionary["b_soul"] = "灵魂" + G.localization.misc.dictionary["b_crystal"] = "水晶" + G.localization.misc.dictionary["b_misprint"] = "印错" + G.localization.misc.dictionary["b_glass"] = "玻璃" + G.localization.misc.dictionary["b_chips"] = "筹码" + G.localization.misc.dictionary["b_mult"] = "倍率" + G.localization.misc.dictionary["b_freeroll"] = "免费重掷次数" + G.localization.misc.dictionary["b_points"] = "点数" + G.localization.misc.dictionary["b_sellcost"] = "售价" + G.localization.misc.dictionary["b_limit"] = "额度" + +local localization= { + +soul_crystal={ + name = "灵魂水晶", + text= { + "蕴含{C:blue}灵魂{}的水晶" + } + }, +enhance_crystal={ + name = "强化水晶", + text= { + "蕴含{C:purple}神秘力量", + "的{C:attention}特殊{}水晶" + } +}, + +} +local jokers= { +soul_crystal = SMODS.Joker:new("soul_crystal", "soul_crystal", + {extra = "crystal"}, + {x = 0,y = 0}, localization["soul_crystal"], + 2,5,1,1,1,1 + ) +, +enhance_crystal = SMODS.Joker:new("enhance_crystal", "enhance_crystal", + {extra = "crystal"}, + {x = 0,y = 0}, localization["enhance_crystal"], + 2,5,1,1,1,1 + ) +, + +} + +for k,v in pairs(jokers) do + SMODS.Sprite:new("j_"..k, SMODS.findModByID("soulcraft").path, k..".png", 71, 95, "asset_atli"):register(); + jokers[k]:register() +end + +G.localization.descriptions.Other["soul_crystal"] = { + name = "灵魂水晶", + text = { + "通过{C:attention}分解小丑,", + "或{C:attention}使用消耗牌", + "达到一定次数,", + "或其它途径获得", + "能够升级其左侧的一个小丑" + } +} +G.localization.descriptions.Other["enhance_crystal"] = { + name = "强化水晶", + text = { + "通过{C:attention}使用消耗牌", + "达到一定次数,", + "或其它途径获得", + "能够升级其左侧的一个小丑" + } +} + +G.localization.descriptions.Other["consumeable_count"] = { + name = "计数", + text = { + "再使用{C:attention}#1#{}次", + "同名消耗牌", + "获得一张{C:purple}水晶", + "{C:inactive}(必须有空间)" + } +} + +function SMODS.Jokers.j_soul_crystal.tooltip(card,info_queue) + info_queue[#info_queue+1] = { set = 'Other', key ="soul_crystal" } +end +function SMODS.Jokers.j_enhance_crystal.tooltip(card,info_queue) + info_queue[#info_queue+1] = { set = 'Other', key ="enhance_crystal" } +end + + + + end + +-- Soul = { +-- tag = "", +-- name = "", +-- type = "", +-- ability = {}, +-- } + +-- function Soul:new(tag,name,type,ability) + -- o = {} + -- setmetatable(o, self) + -- o.tag=tag + -- o.name=name or " " + -- o.type=type or " " + -- o.ability=ability or {} + -- return o +-- end + + +Souls = {} +Soulss = {} + +soul_break_blacklist ={ +-- j_abstract = true, +} + +joker_soul = { +j_abstract = {tag = "j_abstract", extra = 3, banned = false}, +j_midas_mask = {tag = "j_midas_mask", sole = true}, +j_perkeo = {tag = "j_perkeo"}, +j_madness = {tag = "j_madness", extra = 0.5, value = 6}, +j_vampire = {tag ="j_vampire" , extra = 0.1, value = 6}, +j_mime = {tag = "j_mime", value = 7}, +j_dusk = {tag = "j_dusk", value = 4}, +j_mystic_summit = {tag = "j_mystic_summit", extra = 0.1, value = 4}, +j_baron = {tag = "j_baron", extra = 1.5, value = 5}, +j_rough_gem = {tag = "j_rough_gem", extra = 1}, +j_oops = {tag = "j_oops", extra = 6}, +j_troubadour = {tag = "j_troubadour", value = 3}, +j_glass = {tag = "j_glass", sole = true}, +j_vagabond = {tag = "j_vagabond"}, +j_half = {tag = "j_half", extra = 20}, +j_stencil = {tag = "j_stencil", extra = 1}, +j_egg = {tag = "j_egg", extra = 3}, +j_golden = {tag = "j_golden"}, +j_misprint = {tag = "j_misprint", sole = true}, +j_baseball = {tag = "j_baseball", extra = 1}, +j_credit_card={tag = "j_credit_card", extra = 20}, +j_ceremonial = {tag = "j_ceremonial"}, +j_banner = {tag = "j_banner"}, +j_loyalty_card = {tag = "j_loyalty_card", value = 3}, +j_chaos = {tag = "j_chaos", value = 7}, +j_blackboard = {tag = "j_blackboard",extra = 3, value = 5}, +j_juggler = {tag = "j_juggler", extra = 1, value = 3}, +j_drunkard = {tag = "j_drunkard", extra = 1, value = 3}, +j_cartomancer = {tag = "j_cartomancer", value = 5}, +j_hallucination = {tag = "j_hallucination", extra = 4, dollars = 2, value = 5}, +j_luchador = {tag = "j_luchador", value = 5}, +j_diet_cola = {tag = "j_diet_cola", value = 2}, +} + +consumeable_soul = { +c_strength = {tag = "c_strength", extra = 1, usage = 3}, +c_chariot = {tag = "c_chariot", extra = 1.5, usage = 6}, +c_heirophant = {tag = "c_heirophant", extra = 30, usage = 3}, +c_hermit = {tag = "c_hermit", extra = 2, usage = 3, consumeable = true}, +c_temperance = {tag = "c_temperance", extra = 5,usage = 3, consumeable = true}, +c_emperor = {tag = "c_emperor", extra = 1, usage = 5}, +c_judgement = {tag = "c_judgement", extra = 1, usage = 10}, +} + +rarity_soul = { +common_soul = {tag = "common_soul",name = "普通灵魂" ,chips = 15}, +uncommon_soul = {tag = "uncommon_soul",name = "罕见灵魂",mult = 7}, +rare_soul = {tag = "rare_soul",name = "稀有灵魂", x_mult = 1.2}, +legendary_soul = {tag = "legendary_soul",name = "传奇灵魂", x_chips = 3}, +} + +enhance_soul = { +enhance_soul_eternal = {tag = "enhance_soul_eternal",name = "不毁", sole = true}, +enhance_soul_slot = {tag ="enhance_soul_slot",name = "扩容", extra = 1, consumeable = true}, +enhance_soul_split = {tag = "enhance_soul_split",name = "分裂", extra = 10, sole = true}, +enhance_soul_mutation = {tag ="enhance_soul_mutation", name = "突变", extra = 2, consumeable = true}, +enhance_soul_unwilling = {tag = "enhance_soul_unwilling", name = "蹈节", sole = true, extra = true}, +enhance_soul_source = {tag = "enhance_soul_source", name = "本源", extra = 1, level = 1}, +enhance_soul_clear = {tag = "enhance_soul_clear", name = "虚无", consumeable = true}, +enhance_soul_zhongliu = {tag = "enhance_soul_zhongliu", name = "中流", consumeable = true}, + +} +souls = {} +local _soul = {joker_soul,rarity_soul,enhance_soul,consumeable_soul} +for i = 1, #_soul do + for k,v in pairs(_soul[i]) do + souls[#souls+ 1] = v + Souls[k] = v + Soulss[k] = {} + end +end + + +------------------------ +Souls.common_soul.text={ + "{C:blue}+#1#{}筹码" +} +Souls.uncommon_soul.text={ + "{C:red}+#1#{}倍率" +} +Souls.rare_soul.text={ + "{X:mult,C:white}x#1#{}倍率" +} +Souls.legendary_soul.text={ + "{X:blue,C:white}X#1#{}筹码" +} +------------------------ +Souls.enhance_soul_eternal.text={ + "选择{C:attention}盲注{}时", + "给予小丑牌{C:dark_edition}永恒{}", + "并使得此牌可以", + "{C:attention}无视永恒{}被售出或分解" +} +Souls.enhance_soul_slot.text={ + "{C:attention}+#1#{}{C:blue}灵魂{}槽位" +} +Souls.enhance_soul_split.text={ + "选择{C:attention}盲注{}时", + "{C:green}#2#/#1#{}几率{C:attention}复制{}自身", + "{C:inactive}(必须有空间)" +} +Souls.enhance_soul_mutation.text = { + "此牌的某些数值{C:red}X#1#" +} +Souls.enhance_soul_unwilling.text = { + "每个盲注限{C:attention}一次", + "{C:attention}出售{}此牌时", + "加入一张此牌的{C:attention}复制" +} +Souls.enhance_soul_source.text = { + "可叠加升级", + "每级减少{C:blue}#1#%", + "的盲注分数", + "{C:inactive}(当前:{C:purple}#2#{}{C:inactive}级)" +} +Souls.enhance_soul_clear.text = { + "清除此牌", + "的所有{C:blue}灵魂", + "以及易腐,租用,永恒" +} +Souls.enhance_soul_zhongliu.text = { + "{C:attention}重新触发{}一次", + "此牌加入时的效果", +} +------------------------ +Souls.j_abstract.text = { + "每有一张{C:attention}小丑牌{}", + "{C:mult}+#1#{}倍率" +} +Souls.j_midas_mask.text = { + "打出的所有{C:attention}人头牌", + "在计分时", + "变成{C:attention}黄金牌" +} +Souls.j_perkeo.text = { + "离开商店时", + "随机复制{C:attention}1{}张消耗牌", + "并给予其{C:dark_edition,s:0.9}负片{}效果" +} +Souls.j_madness.text = { + "选择{C:attention}盲注{}时,此牌某些数值{C:mult}+#1#", + "然后{C:attention}摧毁{}一张小丑牌" +} +Souls.j_vampire.text = { + "每打出一张计分的增强牌,此牌某些数值{C:mult}+#1#", + "并移除卡牌的{C:attention}增强效果" +} +Souls.j_mime.text = { + "此牌所有的{C:blue}灵魂{}效果", + "将{C:attention}重新触发{}一次" +} +Souls.j_dusk.text = { + "每回合{C:attention}最后一次{}出牌时", + "此牌所有的{C:blue}灵魂{}效果", + "将{C:attention}重新触发{}两次" +} +Souls.j_mystic_summit.text = { + "每次出牌时", + "若剩余{C:attention}弃牌次数{}为{C:attention}0{}", + "则使此牌的某些数值{C:mult}+#1#" +} +Souls.j_baron.text = { + "每张与打出的", + "{C:attention}第一张{}计分牌", + "{C:attention}点数相同{}的手牌", + "将给予{X:mult,C:white}X#1#{}倍率", +} +Souls.j_rough_gem.text = { + "若打出的记分牌的花色", + "是当前所有记分牌中数量{C:attention}最多{}的花色之一", + "其给予{C:money}$#1#" +} +Souls.j_oops.text = { + "每次出牌时", + "将所有以{C:attention}数字标注{}出的", + "{C:green}几率{}暂时{C:green}X#1#{}", +} +Souls.j_troubadour.text = { + "{C:attention}+2{}手牌上限", + "每回合出牌次数{C:attention}-1" +} +Souls.j_glass.text = { + "打出的所有牌", + "将在计分时变为{C:attention}玻璃牌", +} +Souls.j_vagabond.text = { + "每次出牌时", + "如果当前资金数", + "不大于此牌{C:attention}售价", + "则获得一张{C:purple}塔罗牌", + "{C:inactive}(必须有空间)" +} +Souls.j_half.text = { + "如果此牌拥有的", + "{C:blue}灵魂{}数量不大于{C:attention}2", + "则{C:mult}+#1#{}倍率" +} +Souls.j_stencil.text = { + "每个空的{C:blue}灵魂{}槽位", + "获得{X:mult,C:white}X#1#{}倍率", +} +Souls.j_egg.text = { + "回合结束时", + "此牌的售价{C:money}+#1#", +} +Souls.j_golden.text = { + "回合结束时", + "获得等同于此牌", + "{C:money}售价{}的资金", +} +Souls.j_misprint.text = { + "{C:attention}+1{}{C:blue}灵魂{}槽位", + "选择{C:attention}盲注{}时", + "将此牌的其它{C:blue}灵魂", + "{C:attention}替换{}为除此灵魂外的 {C:blue}灵魂" +} +Souls.j_baseball.text = { + "此牌拥有的每个{C:blue}灵魂{}", + "给予{X:mult,C:white}X#1#{}倍率" +} +Souls.j_credit_card.text = { + "可以负债最多{C:red}-20", + "回合结束时", + "额外获得等同于", + "此牌售价的额度", +} +Souls.j_ceremonial.text = { + "选择{C:attention}盲注{}时", + "摧毁{C:attention}右侧{}的小丑牌", + "并根据此牌的{C:red}稀有度", + "提高被摧毁的牌的购买价格,将之", + "加到此牌的{C:attention}售价{}上", + "{C:inactive}(普通:1倍 罕见:2倍 稀有:3倍){}", + "{C:inactive}(传奇及其他:4倍){}", +} +Souls.j_banner.text = { + "提供等同于本回合中", + "剩余{C:attention}弃牌次数", + "乘此牌{C:money}售价{}的倍率" +} +Souls.j_loyalty_card.text = { + "提供等同于本回合中", + "已使用{C:attention}出牌次数{}的倍率", +} +Souls.j_chaos.text = { + "回合结束时", + "根据此牌{C:red}稀有度{}", + "获得免费重掷次数", + "{C:inactive}(普通:1次 罕见:2次 稀有:3次){}", + "{C:inactive}(传奇及其他:4次){}", +} +Souls.j_blackboard.text = { + "若手牌中不存在", + "与记分牌{C:attention}相同的花色{}", + "则{X:mult,C:white}X#1#{}倍率" +} +Souls.j_drunkard.text = { + "{C:attention}+#1#{}弃牌次数" +} +Souls.j_juggler.text = { + "{C:attention}+#1#{}手牌上限" +} +Souls.j_cartomancer.text = { + "选择{C:attention}盲注{}时", + "随机生成一张{C:purple}水晶", + "{C:inactive}(必须有空间)" +} +Souls.j_hallucination.text = { + "使用消耗牌时", + "有{C:green}#2#/#1#{}几率", + "花费{C:attention}$#3#{}复制此消耗牌", + "{C:inactive}(必须有空间)" +} +Souls.j_luchador.text = { + "每回合{C:attention}第二次{}出牌后", + "会消除当前回合中", + "{C:attention}Boss盲注{}的限制条件" +} +Souls.j_diet_cola.text = { + "出售此牌时", + "{C:attention}重新触发{}一次", + "出售此牌时的效果" +} +------------------------ +Souls.c_strength.text = { + "打出的每一张牌", + "在计分时{C:attention}+#1#{}点数" +} +Souls.c_chariot.text = { + "每张手中的{C:attention}钢铁牌", + "额外给予{X:mult,C:white}X#1#{}倍率" +} +Souls.c_heirophant.text = { + "打出的每一张牌", + "在计分时{C:blue}+#1#{}筹码" +} +Souls.c_hermit.text = { + "售价{C:attention}X#1#" +} +Souls.c_temperance.text = { + "获得等同于此牌", + "{C:attention}#1#倍{}售价的{C:money}资金" +} +Souls.c_emperor.text = { + "{C:attention}+#1#{}消耗牌槽位" +} +Souls.c_judgement.text = { + "{C:attention}+#1#{}小丑牌槽位" +} +function soul_vars(soul) + local seq = {soul.chips,soul.x_chips,soul.mult,soul.x_mult,soul.extra,soul.level,G.GAME.probabilities.normal,soul.dollars} + local vars = {} + for k, v in pairs(seq) do + if v then + table.insert(vars,v) + end + end + return vars +end + +function create_soul_name(tag) + return Souls[tag].name or localize{type = 'name_text', key = tag, set = G.P_CENTERS[tag].set}.."之魂" +end + +for k, v in pairs(Souls) do + local tag = v.tag + G.localization.descriptions.Other[tag] = { + name = create_soul_name(tag), + text = v.text + } +end + +local calculate_jokerref = Card.calculate_joker +function Card.calculate_joker(self, context) + if self.ability.set == "Joker" and not self.debuff then + soul_reps = 1 + souls_calculate(self,{soul_repetitions = true}) + for i=1, soul_reps do + souls_calculate(self,context) + end + soul_reps = nil + end + return calculate_jokerref(self, context) +end + +function souls_calculate(self,context) + for k,v in pairs(self.ability.souls) do + local obj = Soulss[v.tag] + if obj.calculate and type(obj.calculate) == "function" then + obj.calculate(v,self,context) + end + end +end + +Soulss.common_soul.calculate = function(self,card,context) + if hand_chips and SMODS.end_calculate_context(context) and not context.soul_repetitions and context.joker_main then + hand_chips = hand_chips + self.chips + update_hand_text({delay = 0}, {chips = hand_chips}) + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = "+"..tostring(self.chips)..localize("b_chips"), colour = G.C.BLUE}) + end +end + +Soulss.uncommon_soul.calculate = function(self,card,context) + if mult and SMODS.end_calculate_context(context) and not context.soul_repetitions and context.joker_main then + mult = mult + self.mult + update_hand_text({delay = 0}, {mult = mult}) + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = "+"..tostring(self.mult)..localize("b_mult"), colour = G.C.RED}) + end +end + +Soulss.rare_soul.calculate = function(self,card,context) + if mult and SMODS.end_calculate_context(context) and not context.soul_repetitions and context.joker_main then + mult = mult * self.x_mult + update_hand_text({delay = 0}, {mult = mult}) + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = "X"..tostring(self.x_mult)..localize("b_mult"), colour = G.C.RED}) + end +end + +Soulss.legendary_soul.calculate = function(self,card,context) + if hand_chips and SMODS.end_calculate_context(context) and not context.soul_repetitions and context.joker_main then + hand_chips = hand_chips * self.x_chips + update_hand_text({delay = 0}, {chips = hand_chips}) + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = "X"..tostring(self.x_chips)..localize("b_chips"), colour = G.C.BLUE}) + end +end + + + +Soulss.enhance_soul_eternal.calculate = function(self,card,context) + if context.setting_blind and not card.getting_sliced then + card:set_eternal(true) + end +end + +Soulss.enhance_soul_split.calculate = function(self,card,context) + if context.setting_blind and not card.getting_sliced then + if pseudorandom("j_enhance_soul_split") < G.GAME.probabilities.normal / self.extra then + if #G.jokers.cards < G.jokers.config.card_limit then + local card = copy_card(card, nil, nil, nil,nil) + card:add_to_deck() + G.jokers:emplace(card) + end + end + end +end + +Soulss.enhance_soul_unwilling.calculate = function(self,card,context) + if context.selling_self and self.extra then + self.extra = false + local card_ = copy_card(card, nil, nil, nil,nil) + card_:add_to_deck() + G.jokers:emplace(card_) + end + if context.setting_blind and not card.getting_sliced then + self.extra = true + end +end + +Soulss.enhance_soul_source.calculate = function(self,card,context) + if context.setting_blind and not card.getting_sliced then + G.GAME.blind.chips = G.GAME.blind.chips * (100 - math.min(self.extra * self.level,100)) / 100 + end +end + +Soulss.j_abstract.calculate = function(self,card,context) + if SMODS.end_calculate_context(context) and not context.soul_repetitions and context.joker_main then + mult = mult + self.extra * #G.jokers.cards + update_hand_text({delay = 0}, {mult=mult}) + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = "+"..3*#G.jokers.cards..localize("b_mult"), colour = G.C.RED}) + end +end + +Soulss.j_midas_mask.calculate = function(self,card,context) + if context.cardarea == G.jokers and context.before then + local faces = {} + for k, v in ipairs(context.scoring_hand) do + if v:is_face() then + faces[#faces+1] = v + v:set_ability(G.P_CENTERS.m_gold, nil, true) + G.E_MANAGER:add_event(Event({ + func = function() + v:juice_up() + return true + end + })) + end + end + if #faces > 0 then + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = localize('k_gold'), colour = G.C.MONEY}) + end + end +end + +Soulss.j_perkeo.calculate = function(self,card,context) + if context.ending_shop and G.consumeables.cards[1] then + G.E_MANAGER:add_event(Event({ + func = function() + local _card = copy_card(pseudorandom_element(G.consumeables.cards, pseudoseed('perkeo')), nil) + _card:set_edition({negative = true}, true) + _card:add_to_deck() + G.consumeables:emplace(_card) + return true + end})) + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = localize('k_duplicated_ex')}) + end +end + +Soulss.j_madness.calculate = function(self,card,context) + if context.setting_blind and not card.getting_sliced then + local madness_increase = self.extra + soul_increase(card,madness_increase) + card_eval_status_text(card, 'extra', nil, nil, nil, {message = "+"..tostring(madness_increase)}) + local destructable_jokers = {} + for i = 1, #G.jokers.cards do + if G.jokers.cards[i] ~= card and not G.jokers.cards[i].ability.eternal and not G.jokers.cards[i].getting_sliced then destructable_jokers[#destructable_jokers+1] = G.jokers.cards[i] end + end + local joker_to_destroy = #destructable_jokers > 0 and pseudorandom_element(destructable_jokers, pseudoseed('madness')) or nil + if joker_to_destroy and not card.getting_sliced then + joker_to_destroy.getting_sliced = true + G.E_MANAGER:add_event(Event({func = function() + card:juice_up(0.8, 0.8) + joker_to_destroy:start_dissolve({G.C.RED}, nil, 1.6) + return true end })) + end + end +end + +Soulss.j_vampire.calculate = function(self,card,context) + if context.cardarea == G.jokers and context.before then + local vampire_increase=self.extra + local enhanced = {} + for k, v in ipairs(context.scoring_hand) do + if v.config.center ~= G.P_CENTERS.c_base and not v.debuff then + enhanced[#enhanced+1] = v + v:set_ability(G.P_CENTERS.c_base, nil, true) + end + end + if #enhanced > 0 then + for i=1,#enhanced do + soul_increase(card,vampire_increase) + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = "+"..tostring(vampire_increase)}) + end + end + end +end + +Soulss.j_mime.calculate = function(self,card,context) + if context.soul_repetitions then + soul_reps = soul_reps + 1 + end +end + +Soulss.j_dusk.calculate = function(self,card,context) + if context.soul_repetitions and G.GAME.current_round.hands_left == 0 then + soul_reps = soul_reps + 2 + end +end + +Soulss.j_mystic_summit.calculate = function(self,card,context) + if context.cardarea == G.jokers and context.before and G.GAME.current_round.discards_left == 0 then + soul_increase(card,seolf.extra) + end +end + +Soulss.j_baron.calculate = function(self,card,context) + if context.individual and context.cardarea == G.hand and not context.end_of_round then + if context.other_card.debuff then + card_eval_status_text(context.other_card, 'extra', nil, nil, nil, {message = localize('k_debuffed')}) + elseif context.other_card:get_id() == context.scoring_hand[1]:get_id() then + mult = mult * self.extra + update_hand_text({delay = 0}, {mult=mult}) + juice_card(card) + card_eval_status_text(context.other_card, 'extra', nil, nil, nil, {message = "X"..self.extra..localize("b_mult"), colour = G.C.RED}) + end + end +end + +Soulss.j_rough_gem.calculate = function(self,card,context) + if context.individual and context.cardarea == G.play and not context.end_of_round then + local suits={ + Spades = 0, + Hearts = 0, + Clubs = 0, + Diamonds = 0,} + for i=1,#context.scoring_hand do + for k,v in pairs(suits) do + if context.scoring_hand[i]:is_suit(k) then + v = v+1 + end + end + end + local suit_max = math.max(suits["Spades"],suits["Hearts"],suits["Clubs"],suits["Diamonds"]) + for k,v in pairs(suits) do + if v == suit_max then + if context.other_card:is_suit(k) then + ease_dollars(self.extra) + juice_card(card) + card_eval_status_text(context.other_card, 'dollars',1, percent) + break + end + end + end + end +end + +Soulss.j_oops.calculate = function(self,card,context) + if context.before and context.cardarea == G.jokers then + for k, v in pairs(G.GAME.probabilities) do + G.GAME.probabilities[k] = v * self.extra + end + end + if context.after and context.cardarea == G.jokers then + for k, v in pairs(G.GAME.probabilities) do + G.GAME.probabilities[k] = v / self.extra + end + end +end + +Soulss.j_glass.calculate = function(self,card,context) + if context.before and context.cardarea == G.jokers then + for k, v in ipairs(context.scoring_hand) do + v:set_ability(G.P_CENTERS.m_glass, nil, true) + G.E_MANAGER:add_event(Event({ + func = function() + v:juice_up() + return true + end + })) + end + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = localize('b_glass'), colour = G.C.BLUE}) + end +end + +Soulss.j_vagabond.calculate = function(self,card,context) + if context.after and context.cardarea == G.jokers then + if G.GAME.dollars <= card.sell_cost and #G.consumeables.cards < G.consumeables.config.card_limit then + G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1 + G.E_MANAGER:add_event(Event({ + trigger = 'before', + delay = 0.0, + func = (function() + local card = create_card('Tarot',G.consumeables, nil, nil, nil, nil, nil, 'vag') + card:add_to_deck() + G.consumeables:emplace(card) + G.GAME.consumeable_buffer = 0 + return true + end)})) + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = localize('k_plus_tarot')}) + end + end +end + +Soulss.j_half.calculate = function(self,card,context) + if SMODS.end_calculate_context(context) and not context.soul_repetitions and context.joker_main and #card.ability.souls <= 2 then + mult = mult + self.extra + update_hand_text({delay = 0}, {mult=mult}) + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = "+"..tostring(self.extra)..localize("b_mult"), colour = G.C.RED}) + end +end + +Soulss.j_stencil.calculate = function(self,card,context) + if SMODS.end_calculate_context(context) and not context.soul_repetitions and context.joker_main then + local delta = card.ability.soul_slots_max - #card.ability.souls + if delta > 0 then + mult = mult*(delta * self.extra + 1) + update_hand_text({delay = 0}, {mult=mult}) + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = "X"..tostring(delta * self.extra + 1)..localize("b_mult"), colour = G.C.RED}) + end + end +end + +Soulss.j_egg.calculate = function(self,card,context) + if context.end_of_round and not context.individual and not context.repetition then + card.ability.extra_value = card.ability.extra_value + self.extra + card:set_cost() + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = localize('k_val_up'), colour = G.C.MONEY}) + end +end + +Soulss.j_golden.calculate = function(self,card,context) + if context.end_of_round and not context.individual and not context.repetition and not context.blueprint then + ease_dollars(card.sell_cost) + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = "$"..tostring(card.sell_cost), colour = G.C.MONEY}) + end +end + +Soulss.j_misprint.calculate = function(self,card,context) + if context.setting_blind and not card.getting_sliced then + local joker_soul_= {} + for k, v in pairs(joker_soul) do + if v.tag ~= "j_misprint" and not v.banned then + joker_soul_[k] = copy_table(v) + end + end + for k,v in pairs(card.ability.souls) do + if v.tag ~= "j_misprint" then + local random_soul,key = pseudorandom_element(joker_soul_, pseudoseed('j_misprint')) + local soul = copy_table(random_soul) + if random_soul.sole then + joker_soul_[key] = nil + end + local obj = Soulss[v.tag] + if obj.remove and type(obj.remove) == "function" then + obj.remove(v,card) + end + when_upgrade(card,soul) + card.ability.souls[k] = soul + end + end + if #card.ability.souls > 1 then + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = localize('b_misprint'), colour = G.C.RED}) + end + end +end + +Soulss.j_ceremonial.calculate = function(self,card,context) + if context.setting_blind and not card.getting_sliced then + for i = 1, #G.jokers.cards do + if G.jokers.cards[i] == card and i < #G.jokers.cards and not G.jokers.cards[i+1].ability.eternal then + local sliced_card = G.jokers.cards[i+1] + sliced_card.getting_sliced = true + local r = {1,2,3,4} + local multiple = r[card.config.center.rarity] or r[4] + G.E_MANAGER:add_event(Event({func = function() + card.ability.extra_value = card.ability.extra_value + multiple * G.jokers.cards[i+1].cost + card:set_cost() + card:juice_up(0.8, 0.8) + G.jokers.cards[i+1]:start_dissolve({HEX("57ecab")}, nil, 1.6) + play_sound('slice1', 0.96+math.random()*0.08) + return true end })) + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = "+"..tostring(multiple * G.jokers.cards[i+1].cost)..localize("b_sellcost"), colour = G.C.MONEY}) + end + end + end +end + +Soulss.j_credit_card.calculate = function(self,card,context) + if context.end_of_round and not context.individual and not context.repetition and not context.blueprint then + G.GAME.bankrupt_at = G.GAME.bankrupt_at - card.sell_cost + self.extra = self.extra + card.sell_cost + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = "+"..tostring(card.sell_cost)..localize("b_limit"), colour = G.C.MONEY}) + end +end + +Soulss.j_banner.calculate = function(self,card,context) + if mult and SMODS.end_calculate_context(context) and not context.soul_repetitions and context.joker_main then + mult = mult+card.sell_cost * G.GAME.current_round.discards_left + update_hand_text({delay = 0}, {mult = mult}) + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = "+"..tostring(card.sell_cost * G.GAME.current_round.discards_left)..localize("b_mult"), colour = G.C.MULT}) + end +end + +Soulss.j_baseball.calculate = function(self,card,context) + if mult and SMODS.end_calculate_context(context) and not context.soul_repetitions and context.joker_main then + mult = mult * #card.ability.souls * self.extra + update_hand_text({delay = 0}, {mult=mult}) + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = "X"..tostring(#card.ability.souls)..localize("b_mult"), colour = G.C.MULT}) + end +end + +Soulss.j_loyalty_card.calculate = function(self,card,context) + if mult and SMODS.end_calculate_context(context) and not context.soul_repetitions and context.joker_main then + local played = G.GAME.current_round.hands_played + 1 + mult = mult * played + update_hand_text({delay = 0}, {mult=mult}) + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = "X"..tostring(played)..localize("b_mult"), colour = G.C.MULT}) + end +end + +Soulss.j_chaos.calculate = function(self,card,context) + if context.end_of_round and not context.individual and not context.repetition and not context.blueprint then + local r = {1,2,3,4} + local add = r[card.config.center.rarity] or r[4] + G.GAME.current_round.free_rerolls = G.GAME.current_round.free_rerolls + add + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = "+"..tostring(add)..localize("b_freeroll"), colour = G.C.GREEN}) + calculate_reroll_cost(true) + end +end + +Soulss.j_cartomancer.calculate = function(self,card,context) + if context.setting_blind and not card.getting_sliced and #G.jokers.cards < G.jokers.config.card_limit then + slug = pseudorandom("j_cartomancer") < 0.5 and "j_soul_crystal" or "j_enhance_crystal" + G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.4, func = function() + play_sound('timpani') + local card = create_card('Joker', G.jokers, nil, nil, nil, nil,slug,'crystal') + card:add_to_deck() + G.jokers:emplace(card) + return true end })) + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = localize('b_crystal'), colour = G.C.PURPLE}) + end +end + +Soulss.j_blackboard.calculate = function(self,card,context) + if mult and SMODS.end_calculate_context(context) and not context.soul_repetitions and context.joker_main then + local suits = { + Spades = false, + Hearts = false, + Clubs = false, + Diamonds = false, + } + for i = 1, #context.scoring_hand do + for k,v in pairs(suits) do + if context.scoring_hand[i]:is_suit(k) then + suits[k] = true + end + end + end + local have = false + for i = 1, #G.hand.cards do + for k,v in pairs(suits) do + if v and G.hand.cards[i]:is_suit(k) then + have = true + break + end + end + end + if not have then + mult = mult * self.extra + update_hand_text({delay = 0}, {mult = mult}) + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = "X"..tostring(self.extra)..localize("b_mult"), colour = G.C.MULT}) + end + end +end + +Soulss.j_hallucination.calculate = function(self,card,context) + if context.using_consumeable and #G.consumeables.cards < G.consumeables.config.card_limit and pseudorandom("j_cartomancer") < G.GAME.probabilities.normal / self.extra and G.GAME.dollars-G.GAME.bankrupt_at - self.dollars >= 0 then + ease_dollars(-self.dollars) + G.E_MANAGER:add_event(Event({ + func = function() + local _card = copy_card(context.consumeable, nil) + _card:add_to_deck() + G.consumeables:emplace(_card) + return true + end})) + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = localize('k_duplicated_ex')}) + end +end + +Soulss.j_luchador.calculate = function(self,card,context) + if context.after and context.cardarea == G.jokers and G.GAME.blind and G.GAME.blind.boss and not G.GAME.blind.disabled and G.GAME.current_round.hands_played == 1 then + G.GAME.blind:disable() + card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = localize('ph_boss_disabled')}) + end +end + +Soulss.j_diet_cola.calculate = function(self,card,context) + if context.selling_self and not context.from_diet then + card:calculate_joker{selling_self = true,from_diet = true} + card:remove_from_deck() + card.added_to_deck = true + end +end + +Soulss.c_strength.calculate = function(self,card,context) + if context.individual and context.cardarea == G.play and not context.end_of_round then + G.E_MANAGER:add_event(Event({trigger = 'after',delay = 0.1,func = function() + local card = context.other_card + local suit_prefix = string.sub(card.base.suit, 1, 1)..'_' + local rank_suffix = card.base.id == 14 and 2 or math.min(card.base.id+1, 14) + if rank_suffix < 10 then rank_suffix = tostring(rank_suffix) + elseif rank_suffix == 10 then rank_suffix = 'T' + elseif rank_suffix == 11 then rank_suffix = 'J' + elseif rank_suffix == 12 then rank_suffix = 'Q' + elseif rank_suffix == 13 then rank_suffix = 'K' + elseif rank_suffix == 14 then rank_suffix = 'A' + end + card:set_base(G.P_CARDS[suit_prefix..rank_suffix]) + return true end })) + card_eval_status_text(context.other_card, 'extra', nil, nil, nil, {message ="+1"..localize("b_points"), colour = G.C.RED}) + end +end + +Soulss.c_chariot.calculate = function(self,card,context) + if context.individual and context.cardarea == G.hand and not context.end_of_round then + if context.other_card.debuff then + card_eval_status_text(context.other_card, 'extra', nil, nil, nil, {message = localize('k_debuffed')}) + elseif context.other_card.config.center == G.P_CENTERS.m_steel then + mult = mult * self.extra + update_hand_text({delay = 0}, {mult = mult}) + juice_card(card) + card_eval_status_text(context.other_card, 'extra', nil, nil, nil, {message = "X"..self.extra..localize("b_mult"), colour = G.C.RED}) + end + end +end + +Soulss.c_heirophant.calculate = function(self,card,context) + if context.individual and context.cardarea == G.play and not context.end_of_round then + if context.other_card.debuff then + card_eval_status_text(context.other_card, 'extra', nil, nil, nil, {message = localize('k_debuffed')}) + else + hand_chips = hand_chips + self.extra + update_hand_text({delay = 0}, {chips = hand_chips}) + juice_card(card) + card_eval_status_text(context.other_card,"chips",self.extra) + end + end +end + +local new_roundref = new_round +function new_round() + new_roundref() + G.E_MANAGER:add_event(Event({ + trigger = 'immediate', + func = function() + G.GAME.blind.chip_text = number_format(G.GAME.blind.chips) + G.FUNCS.blind_chip_UI_scale(G.hand_text_area.blind_chips) + G.HUD_blind:recalculate() + G.hand_text_area.blind_chips:juice_up() + play_sound('chips2') + return true + end + })) +end + +local add_to_deckref = Card.add_to_deck +function Card.add_to_deck(self, from_debuff) + if not self.added_to_deck then + + if self.ability.name == "soul_crystal" then + if not next(self.ability.souls) then + local soul = create_soul(joker_soul,nil) + table.insert(self.ability.souls,soul) + end + end + + if self.ability.name == "enhance_crystal" then + if not next(self.ability.souls) then + local soul = create_soul(enhance_soul,nil) + table.insert(self.ability.souls,soul) + end + end + + souls_add(self) + end + add_to_deckref(self, from_debuff) +end + +local remove_from_deckref = Card.remove_from_deck +function Card.remove_from_deck(self, from_debuff) + if self.added_to_deck then + souls_remove(self) + end + remove_from_deckref(self, from_debuff) +end + +function souls_add(self) + for k,v in pairs(self.ability.souls) do + when_upgrade(self,v) + end +end + +function souls_remove(self) + for k,v in pairs(self.ability.souls) do + local obj = Soulss[v.tag] + if obj.remove and type(obj.remove) == "function" then + obj.remove(v,self) + end + end +end + +Soulss.j_credit_card.remove = function(self,card) + G.GAME.bankrupt_at = G.GAME.bankrupt_at + self.extra +end + +Soulss.j_troubadour.remove = function(self,card) + G.hand:change_size(-2) + G.GAME.round_resets.hands = G.GAME.round_resets.hands + 1 + G.GAME.current_round.hands_left = G.GAME.current_round.hands_left + 1 +end + +Soulss.j_juggler.remove = function(self,card) + G.hand:change_size(-self.extra) +end + +Soulss.j_drunkard.remove = function(self,card) + G.GAME.current_round.discards_left = G.GAME.current_round.discards_left - self.extra + G.GAME.round_resets.discards = G.GAME.round_resets.discards - self.extra +end + +Soulss.c_emperor.remove = function(self,card) + G.consumeables.config.card_limit = G.consumeables.config.card_limit - self.extra +end + +Soulss.c_judgement.remove = function(self,card) + G.jokers.config.card_limit = G.jokers.config.card_limit - self.extra +end +function when_upgrade(self,soul) + if self.ability.extra == "crystal" and soul.consumeable then return end + if soul.tag == "enhance_soul_slot" then + self.ability.soul_slots_max = self.ability.soul_slots_max + soul.extra + end + if soul.tag == "j_misprint" then + self.ability.soul_slots_max = self.ability.soul_slots_max + 1 + end + if soul.tag == "j_troubadour" then + G.hand:change_size(2) + G.GAME.round_resets.hands = G.GAME.round_resets.hands - 1 + G.GAME.current_round.hands_left = G.GAME.current_round.hands_left - 1 + end + if soul.tag == "j_credit_card" then + G.GAME.bankrupt_at = G.GAME.bankrupt_at - soul.extra + end + if soul.tag == "j_juggler" then + G.hand:change_size(soul.extra) + end + if soul.tag == "j_drunkard" then + G.GAME.current_round.discards_left = G.GAME.current_round.discards_left + soul.extra + G.GAME.round_resets.discards = G.GAME.round_resets.discards + soul.extra + end + if soul.tag == "enhance_soul_mutation" then + soul_increasex(self,soul.extra) + end + if soul.tag == "enhance_soul_clear" then + souls_remove(self) + self.ability.souls = {} + self:set_eternal(nil) + self:set_rental(nil) + self.ability.perishable = nil + end + if soul.tag == "enhance_soul_zhongliu" then + self.added_to_deck = false + self:add_to_deck() + end + if soul.tag == "c_hermit" then + self.ability.extra_value = self.ability.extra_value + self.sell_cost* (soul.extra - 1) + self:set_cost() + end + if soul.tag == "c_temperance" then + ease_dollars(self.sell_cost * soul.extra) + end + if soul.tag == "c_emperor" then + G.consumeables.config.card_limit = G.consumeables.config.card_limit + soul.extra + end + if soul.tag == "c_judgement" then + G.jokers.config.card_limit = G.jokers.config.card_limit + soul.extra + end +end + +function soul_increase(self,var) + local table_extra = {"Xmult","dollars","emult","s_mult","chips","hand_add","chip_mod","increase","size","max","every","max","odds","faces","discards"} + local notable_extra = {"extra","mult","x_mult","t_chips","t_mult"} + if type(self.ability.extra) == "table" then + for k,v in pairs(table_extra) do + if self.ability.extra[v] and type(self.ability.extra[v]) == "number" and self.ability.extra[v] ~= 0 then + if v ~= "emult" then + self.ability.extra[v] = self.ability.extra[v] + var + else + self.ability.extra.mult = self.ability.extra.mult + var + end + end + end + end + for k,v in pairs(notable_extra) do + if v ~= "x_mult" or (v == "x_mult" and self.ability[v] >= 2) then + if self.ability[v] and type(self.ability[v]) == "number" and self.ability[v] ~= 0 then + self.ability[v] = self.ability[v] + var + end + end + end +end + +function soul_increasex(self,var) + local table_extra = {"Xmult","dollars","emult","s_mult","chips","hand_add","chip_mod","increase","size","max","every","max","odds","faces","discards"} + local notable_extra = {"extra","mult","x_mult","t_chips","t_mult"} + if type(self.ability.extra) == "table" then + for k,v in pairs(table_extra) do + if self.ability.extra[v] and type(self.ability.extra[v]) == "number" and self.ability.extra[v] ~= 0 then + if v ~= "emult" then + self.ability.extra[v] = self.ability.extra[v] * var + else + self.ability.extra.mult = self.ability.extra.mult * var + end + end + end + end + for k,v in pairs(notable_extra) do + if v ~= "x_mult" or (v == "x_mult" and self.ability[v] >= 2) then + if self.ability[v] and type(self.ability[v]) == "number" and self.ability[v] ~= 0 then + self.ability[v] = self.ability[v] * var + end + end + end +end + + +function Card:can_soul_break() + if (G.play and #G.play.cards > 0) or + (G.CONTROLLER.locked) or + (G.GAME.STOP_USE and G.GAME.STOP_USE > 0) + then return false end + if next(self.ability.souls) or self.ability.extra == "crystal" or self.ability.eternal and not find_soul(self,"j_enhance_soul_eternal") or (G.GAME.dollars-G.GAME.bankrupt_at - calculate_break_value(self) < 0) or soul_break_blacklist[self.config.center_key] then + return false + end + return true +end + +function Card:can_soul_upgrade() + if (G.play and #G.play.cards > 0) or + (G.CONTROLLER.locked) or + (G.GAME.STOP_USE and G.GAME.STOP_USE > 0) + then return false end + if self.ability.extra == "crystal" then + return false + end + for i=1,#G.jokers.cards do + if G.jokers.cards[i] == self then + if i == #G.jokers.cards then return false end + if G.jokers.cards[i+1].ability.extra ~= "crystal" then return false end + if #self.ability.souls >= self.ability.soul_slots_max then + if G.jokers.cards[i+1].ability.souls[1].level and not find_soul(G.jokers.cards[i],G.jokers.cards[i+1].ability.souls[1].tag) then + return false + end + if not G.jokers.cards[i+1].ability.souls[1].level and not G.jokers.cards[i+1].ability.souls[1].consumeable then + return false + end + end + if G.jokers.cards[i+1].ability.souls[1].sole and find_soul(G.jokers.cards[i],G.jokers.cards[i+1].ability.souls[1].tag) then return false end + end + end + return true +end + +G.FUNCS.can_soul_break = function(e) + if e.config.ref_table:can_soul_break() then + e.config.colour = G.C.BLUE + e.config.button = 'soul_break' + else + e.config.colour = G.C.UI.BACKGROUND_INACTIVE + e.config.button = nil + end +end + + G.FUNCS.can_soul_upgrade= function(e) + if e.config.ref_table:can_soul_upgrade() then + e.config.colour = G.C.PURPLE + e.config.button = 'soul_upgrade' + else + e.config.colour = G.C.UI.BACKGROUND_INACTIVE + e.config.button = nil + end +end + + + +G.FUNCS.soul_break = function(e) + local card = e.config.ref_table + card:soul_break() +end + +G.FUNCS.soul_upgrade = function(e) + local card = e.config.ref_table + card:soul_upgrade() +end + +function Card:soul_break() + G.CONTROLLER.locks.selling_card = true + stop_use() + local area = self.area + G.CONTROLLER:save_cardarea_focus('jokers') + if self.children.use_button then self.children.use_button:remove(); self.children.use_button = nil end + if self.children.sell_button then self.children.sell_button:remove(); self.children.sell_button = nil end + local dollars = calculate_break_value(self) + ease_dollars(-dollars) + self:start_dissolve() + play_sound('glass1') + G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.4, func = function() + play_sound('timpani') + local card = create_card('Joker', G.jokers, nil, nil, nil, nil,"j_soul_crystal",'soul_crystal') + local soul = create_soul(nil,self.config.center_key) + card.ability.souls[#card.ability.souls+1] = soul + card:add_to_deck() + G.jokers:emplace(card) + return true end })) + G.CONTROLLER.locks.selling_card = nil + G.CONTROLLER:recall_cardarea_focus('jokers') +end + +function Card:soul_upgrade() + G.CONTROLLER.locks.selling_card = true + stop_use() + local area = self.area + G.CONTROLLER:save_cardarea_focus('jokers') + if self.children.soul_button then self.children.soul_button:remove(); self.children.soul_button = nil end + if self.children.use_button then self.children.use_button:remove(); self.children.use_button = nil end + if self.children.sell_button then self.children.sell_button:remove(); self.children.sell_button = nil end + + for i=1,#G.jokers.cards do + if G.jokers.cards[i] == self then + local soul = G.jokers.cards[i+1].ability.souls[1] + local same_soul = find_soul(self,soul.tag) + if same_soul and same_soul.level then + same_soul.level = same_soul.level + 1 + elseif not soul.consumeable then + self.ability.souls[#self.ability.souls+1] = soul + end + when_upgrade(self,soul) + play_sound('coin1') + G.jokers.cards[i+1]:start_dissolve() + break + end + end + + G.CONTROLLER.locks.selling_card = nil + G.CONTROLLER:recall_cardarea_focus('jokers') +end + +local highlightref = Card.highlight +function Card:highlight(is_higlighted) + highlightref(self,is_higlighted) + if self.ability.consumeable or self.ability.set == 'Joker' or (self.area and self.area == G.pack_cards) then + if self.highlighted and self.area and self.area.config.type ~= 'shop' then + self.children.soul_button = UIBox{ + definition = G.UIDEF.soul_buttons(self), + config = {align= + ((self.area == G.jokers) or (self.area == G.consumeables)) and "bm" or + "bmi" + , offset = + ((self.area == G.jokers) or (self.area == G.consumeables)) and {x=0,y=-0.25} or + {x=0,y=0.65}, + parent =self} + } + elseif self.children.soul_button then + self.children.soul_button:remove() + self.children.soul_button = nil + end + end +end + +function G.UIDEF.soul_buttons(card) + local soul_break = nil + if card.area and card.area.config.type == 'joker' and card.ability.set == 'Joker' and card.ability.extra ~= "crystal" then + if not next(card.ability.souls) then + local dolloars = calculate_break_value(card) + soul_break = { n=G.UIT.ROOT, config = {ref_table = card, minw = 0.1, maxw = 1.3, padding = 0.1, align = 'bm', colour = G.C.BLUE, shadow = true, r = 0.08, minh = 0.6, one_press = false, button = 'soul_break', func = "can_soul_break", hover = true}, nodes={ + {n=G.UIT.T, config={text = "$"..dolloars..localize('b_break'),colour = G.C.WHITE, scale = 0.4}} + }} + end + end + local t = { + n=G.UIT.ROOT, config = {padding = 0, colour = G.C.CLEAR}, nodes={ + {n=G.UIT.C, config={padding = 0.15, align = 'cl'}, nodes={ + {n=G.UIT.R, config={align = 'cl'}, nodes={ + }}, + }}, + }} + return soul_break or t +end + +local use_and_sell_buttonsref = G.UIDEF.use_and_sell_buttons +function G.UIDEF.use_and_sell_buttons(card) + local retval = use_and_sell_buttonsref(card) + if card.area and card.area.config.type == 'joker' and card.ability.set == 'Joker' and card.ability.extra ~= "crystal" then + local soul_upgrade = { + n=G.UIT.C, config={align = "cr"}, nodes={ + {n=G.UIT.C, config={ref_table = card, align = "cr",maxw = 1.25, padding = 0.1, r=0.08, minw = 1.25, hover = true, shadow = true, colour = G.C.PURPLE, one_press = true, button = 'soul_upgrade', func = 'can_soul_upgrade'}, nodes={ + {n=G.UIT.B, config = {w=0.1,h=0.6}}, + {n=G.UIT.C, config={align = "tm"}, nodes={ + {n=G.UIT.R, config={align = "cm", maxw = 1.25}, nodes={ + {n=G.UIT.T, config={text = localize('b_upgrade'), colour = G.C.UI.TEXT_LIGHT, scale = 0.45, shadow = true}} + }}, + + }} + }} + } + } + retval.nodes[1].nodes[3]={n=G.UIT.R, config={align = 'cl'}, nodes={ + }} + table.insert(retval.nodes[1].nodes[3].nodes, soul_upgrade) + + end + return retval +end + +local set_abilityref = Card.set_ability +function Card:set_ability(center, initial, delay_sprites) + set_abilityref(self,center, initial, delay_sprites) + self.ability.soul_slots_max = G.GAME.soul_slots_max + self.ability.souls={} +end + +local init_game_objectref = Game.init_game_object +function Game:init_game_object() + local t = init_game_objectref(self) + t["soul_consumeable_usage"] = {} + t["soul_slots_max"] = 2 + t["soul_usage"] = 3 + return t +end + +function find_soul(card,soul) + for k,v in pairs(card.ability.souls) do + if v.tag == soul then + return v + end + end + return false +end + +function Card:is_face(from_boss) + if self.debuff and not from_boss then return end + local id = self:get_id() + if 1 then + return true + end +end + +function calculate_break_value(card) + local r = {2,3,4,7} + local value_rarity = r[card.config.center.rarity] or r[4] + local value = joker_soul[card.config.center_key] and joker_soul[card.config.center_key].value or value_rarity + return value +end +function create_soul(area,tag) + local soul = nil + if not area then + if joker_soul[tag] and not joker_soul[tag].banned then + soul = joker_soul[tag] + elseif consumeable_soul[tag] and not consumeable_soul[tag].banned then + soul = consumeable_soul[tag] + elseif enhance_soul[tag] and not enhance_soul[tag].banned then + soul = enhance_soul[tag] + else + local rarity = {"common_soul","uncommon_soul","rare_soul","legendary_soul"} + local rarity_soul_tag = rarity[G.P_CENTERS[tag].rarity] or rarity[4] + soul = rarity_soul[rarity_soul_tag] + end + end + if area then + local area_ = {} + for k, v in pairs(area) do + if not v.banned then + area_[k] = v + end + end + soul = pseudorandom_element(area_, pseudoseed('create_soul')) + end + return copy_table(soul) +end + + + +local use_consumeableref = Card.use_consumeable +function Card:use_consumeable(area, copier) + use_consumeableref(self,area,copier) + local o = consumeable_soul[self.config.center_key] + local usage = o and (o.usage - 1) or (G.GAME.soul_usage - 1) + if G.GAME.soul_consumeable_usage[self.config.center_key] == usage then + if #G.jokers.cards < G.jokers.config.card_limit then + G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.4, func = function() + play_sound('timpani') + local card = {} + if o then + card = create_card('Joker', G.jokers, nil, nil, nil, nil,"j_soul_crystal",'soul_crystal') + local soul = create_soul(nil,self.config.center_key) + card.ability.souls[#card.ability.souls+1] = soul + else + card = create_card('Joker', G.jokers, nil, nil, nil, nil,"j_enhance_crystal",'enhance_crystal') + end + card:add_to_deck() + G.jokers:emplace(card) + return true end })) + G.GAME.soul_consumeable_usage[self.config.center_key] = 0 + else + card_eval_status_text(self, 'extra', nil, nil, nil, {message = localize('k_no_room_ex')}) + end + else + G.GAME.soul_consumeable_usage[self.config.center_key] = (G.GAME.soul_consumeable_usage[self.config.center_key] or 0) + 1 + end +end + +local generate_UIBox_ability_table_ref = Card.generate_UIBox_ability_table +function Card.generate_UIBox_ability_table(self) + local generate_UIBox_ability_table_val = generate_UIBox_ability_table_ref(self) + local main_text = generate_UIBox_ability_table_val.main + local info = generate_UIBox_ability_table_val.info + + if not(soul_info_indicate and soul_info_indicate == 1)then + local souls = self.ability.souls + local souls_tag = {} + for k, v in pairs(self.ability.souls) do + souls_tag[v.tag] = false + end + if not(soul_info_indicater and soul_info_indicater == 1 ) then + for k, v in pairs(self.ability.souls) do + if not souls_tag[v.tag] and G.localization.descriptions.Other[v.tag] then + souls_tag[v.tag] = true + info[#info + 1] = {} + local desc_nodes = info[#info] + local loc_vars = soul_vars(v) + localize{type = 'other', key = v.tag, nodes = desc_nodes,vars = loc_vars} + desc_nodes.name = G.localization.descriptions.Other[v.tag].name + end + end + if self.ability.consumeable then + local o = consumeable_soul[self.config.center_key] + local usage = o and o.usage or G.GAME.soul_usage + local usage_ = usage - (G.GAME.soul_consumeable_usage[self.config.center_key] or 0 ) + info[#info + 1] = {} + local desc_nodes = info[#info] + localize{type = 'other', key = "consumeable_count", nodes = desc_nodes,vars = {usage_ }} + desc_nodes.name = G.localization.descriptions.Other["consumeable_count"].name + end + end + if #self.ability.souls > 0 then + main_text[#main_text + 1] = { + { + n = G.UIT.T, + config = { + text = localize('b_soul').."("..tostring(#self.ability.souls).."/"..tostring(self.ability.soul_slots_max)..")", + colour = G.C.BLUE, + scale = 0.24 + } + }, + } + end + for i = 1, #self.ability.souls do + main_text[#main_text + 1] = { + { + n = G.UIT.T, + config = { + text = create_soul_name(self.ability.souls[i].tag), + colour = G.C.PURPLE, + scale = 0.24 + } + } + } + end + end + return generate_UIBox_ability_table_val +end + + +-- local key_hold_updateref=Controller.key_hold_update +-- function Controller:key_hold_update(key, dt) + -- key_hold_updateref(self,key, dt) + -- if self.held_key_times[key] then + -- if key == "lctrl" and not G.SETTINGS.paused then + -- if self.held_key_times[key] > 0.5 then + -- soul_info_indicate=true + -- else + -- self.held_key_times[key] = self.held_key_times[key] + dt + -- end + -- end + -- end +-- end + +-- local key_release_updateref=Controller.key_release_update +-- function Controller:key_release_update(key, dt) + -- key_release_updateref(self,key, dt) + -- if key == 'lctrl' then + -- soul_info_indicate=-soul_info_indicate or -1 + -- end +-- end + +local controller_key_press_update_ref = Controller.key_press_update +function Controller:key_press_update(key, dt) + controller_key_press_update_ref(self, key, dt) + if key=="lctrl" then + soul_info_indicate = soul_info_indicate and -soul_info_indicate or 1 + end + if key=="rctrl" then + soul_info_indicater = soul_info_indicater and -soul_info_indicater or 1 + end +end + +G.FUNCS.your_collection_souls = function(e) + G.SETTINGS.paused = true + G.FUNCS.overlay_menu{ + definition = create_UIBox_your_collection_souls(), + } +end + +function create_UIBox_your_collection_souls() + local deck_tables = {} + G.your_collection = {} + for j = 1, 3 do + G.your_collection[j] = CardArea( + G.ROOM.T.x + 0.2*G.ROOM.T.w/2,G.ROOM.T.h, + 5*G.CARD_W, + 0.95*G.CARD_H, + {card_limit = 5, type = 'title', highlight_limit = 0, collection = true}) + table.insert(deck_tables, + {n=G.UIT.R, config={align = "cm", padding = 0.07, no_fill = true}, nodes={ + {n=G.UIT.O, config={object = G.your_collection[j]}} + }} + ) + end + + local soul_options = {} + for i = 1, math.ceil(#souls/(5*#G.your_collection)) do + table.insert(soul_options, localize('k_page')..' '..tostring(i)..'/'..tostring(math.ceil(#souls/(5*#G.your_collection)))) + end + for i = 1, 5 do + for j = 1, #G.your_collection do + local center = G.P_CENTERS["j_soul_crystal"] + local card = Card(G.your_collection[j].T.x + G.your_collection[j].T.w/2, G.your_collection[j].T.y, G.CARD_W, G.CARD_H, nil, center) + table.insert(card.ability.souls,souls[i+(j-1)*5]) + G.your_collection[j]:emplace(card) + end + end + + INIT_COLLECTION_CARD_ALERTS() + + local t = create_UIBox_generic_options({ back_func = 'your_collection', contents = { + {n=G.UIT.R, config={align = "cm", r = 0.1, colour = G.C.BLACK, emboss = 0.05}, nodes=deck_tables}, + {n=G.UIT.R, config={align = "cm"}, nodes={ + create_option_cycle({options = soul_options, w = 4.5, cycle_shoulders = true, opt_callback = 'your_collection_souls_page', current_option = 1, colour = G.C.RED, no_pips = true, focus_args = {snap_to = true, nav = 'wide'}}) + }} + }}) + return t +end + +G.FUNCS.your_collection_souls_page = function(args) + if not args or not args.cycle_config then return end + for j = 1, #G.your_collection do + for i = #G.your_collection[j].cards,1, -1 do + local c = G.your_collection[j]:remove_card(G.your_collection[j].cards[i]) + c:remove() + c = nil + end + end + for i = 1, 5 do + for j = 1, #G.your_collection do + local soul = souls[i+(j-1)*5 + (5*#G.your_collection*(args.cycle_config.current_option - 1))] + if not soul then break end + local center = string.sub(soul.tag,1,7) ~= "enhance" and G.P_CENTERS["j_soul_crystal"] or G.P_CENTERS["j_enhance_crystal"] + if not center then break end + local card = Card(G.your_collection[j].T.x + G.your_collection[j].T.w/2, G.your_collection[j].T.y, G.CARD_W, G.CARD_H, G.P_CARDS.empty, center) + table.insert(card.ability.souls,soul) + G.your_collection[j]:emplace(card) + end + end + INIT_COLLECTION_CARD_ALERTS() +end \ No newline at end of file diff --git a/soulcraftlovely/lovely.toml b/soulcraftlovely/lovely.toml index 6153f2e..b753ae6 100644 --- a/soulcraftlovely/lovely.toml +++ b/soulcraftlovely/lovely.toml @@ -11,8 +11,8 @@ position = "before" payload = ''' UIBox_button({button = 'your_collection_souls', label = {localize('b_soul')}, count = {tally = #souls, of = #souls}, minw = 5, id = 'your_collection_souls'}), ''' -match_indent = true -overwrite = true +match_indent = false + [[patches]] [patches.pattern] @@ -22,5 +22,4 @@ position = "at" payload = ''' not self.ability.eternal or (self.ability.eternal and find_soul(self,"enhance_soul_eternal")) then ''' -match_indent = true -overwrite = true \ No newline at end of file +match_indent = false