remove lovely root directory
This commit is contained in:
parent
feefd09596
commit
c41e0ec457
|
@ -1,321 +0,0 @@
|
|||
LOVELY_INTEGRITY = 'd3c881055f5938773f6b44e7c8b207117963612b2eaf889f5b7ef8b61e1143cd'
|
||||
|
||||
--Class
|
||||
Back = Object:extend()
|
||||
|
||||
--Class Methods
|
||||
function Back:init(selected_back)
|
||||
if not selected_back then selected_back = G.P_CENTERS.b_red end
|
||||
self.atlas = selected_back.unlocked and selected_back.atlas or nil
|
||||
self.name = selected_back.name or 'Red Deck'
|
||||
|
||||
self.effect = {
|
||||
center = selected_back,
|
||||
text_UI = '',
|
||||
config = copy_table(selected_back.config)
|
||||
}
|
||||
self.loc_name = localize{type = 'name_text', set = 'Back', key = self.effect.center.key}
|
||||
|
||||
local pos = (self.effect.center.unlocked and self.effect.center.pos) or {x = 4, y = 0}
|
||||
self.pos = self.pos or {}
|
||||
self.pos.x = pos.x
|
||||
self.pos.y = pos.y
|
||||
end
|
||||
|
||||
function Back:get_name()
|
||||
if self.effect.center.unlocked then return self.loc_name else return localize('k_locked') end
|
||||
end
|
||||
|
||||
function Back:generate_UI(other, ui_scale, min_dims, challenge)
|
||||
min_dims = min_dims or 0.7
|
||||
ui_scale = ui_scale or 0.9
|
||||
local back_config = other or self.effect.center
|
||||
local name_to_check = other and other.name or self.name
|
||||
local effect_config = other and other.config or self.effect.config
|
||||
challenge = G.CHALLENGES[get_challenge_int_from_id(challenge or '') or ''] or {name = 'ERROR'}
|
||||
|
||||
local loc_args, loc_nodes = nil, {}
|
||||
|
||||
if not back_config.unlocked then
|
||||
local localized_by_smods
|
||||
local key_override
|
||||
if back_config.locked_loc_vars and type(back_config.locked_loc_vars) == 'function' then
|
||||
local res = back_config:locked_loc_vars() or {}
|
||||
loc_args = res.vars or {}
|
||||
key_override = res.key
|
||||
end
|
||||
if G.localization.descriptions.Back[key_override or back_config.key].unlock_parsed then
|
||||
localize{type = 'unlocks', key = key_override or back_config.key, set = 'Back', nodes = loc_nodes, vars = loc_args}
|
||||
localized_by_smods = true
|
||||
end
|
||||
if not back_config.unlock_condition then
|
||||
if not localized_by_smods then
|
||||
localize{type = 'descriptions', key = 'demo_locked', set = "Other", nodes = loc_nodes, vars = loc_args}
|
||||
end
|
||||
elseif back_config.unlock_condition.type == 'win_deck' then
|
||||
local other_name = localize('k_unknown')
|
||||
if G.P_CENTERS[back_config.unlock_condition.deck].unlocked then
|
||||
other_name = localize{type = 'name_text', set = 'Back', key = back_config.unlock_condition.deck}
|
||||
end
|
||||
loc_args = loc_args or {other_name}
|
||||
localize{type = 'descriptions', key = 'deck_locked_win', set = "Other", nodes = loc_nodes, vars = loc_args}
|
||||
elseif back_config.unlock_condition.type == 'discover_amount' then
|
||||
loc_args = loc_args or {tostring(back_config.unlock_condition.amount)}
|
||||
localize{type = 'descriptions', key = 'deck_locked_discover', set = "Other", nodes = loc_nodes, vars = loc_args}
|
||||
elseif back_config.unlock_condition.type == 'win_stake' then
|
||||
local other_name = localize{type = 'name_text', set = 'Stake', key = G.P_CENTER_POOLS.Stake[back_config.unlock_condition.stake].key}
|
||||
loc_args = loc_args or {other_name, colours = {get_stake_col(back_config.unlock_condition.stake)}}
|
||||
localize{type = 'descriptions', key = 'deck_locked_stake', set = "Other", nodes = loc_nodes, vars = loc_args}
|
||||
end
|
||||
else
|
||||
local key_override
|
||||
if back_config.loc_vars and type(back_config.loc_vars) == 'function' then
|
||||
local res = back_config:loc_vars() or {}
|
||||
loc_args = res.vars or {}
|
||||
key_override = res.key
|
||||
elseif name_to_check == 'Blue Deck' then loc_args = {effect_config.hands}
|
||||
elseif name_to_check == 'Red Deck' then loc_args = {effect_config.discards}
|
||||
elseif name_to_check == 'Yellow Deck' then loc_args = {effect_config.dollars}
|
||||
elseif name_to_check == 'Green Deck' then loc_args = {effect_config.extra_hand_bonus, effect_config.extra_discard_bonus}
|
||||
elseif name_to_check == 'Black Deck' then loc_args = {effect_config.joker_slot, -effect_config.hands}
|
||||
elseif name_to_check == 'Magic Deck' then loc_args = {localize{type = 'name_text', key = 'v_crystal_ball', set = 'Voucher'}, localize{type = 'name_text', key = 'c_fool', set = 'Tarot'}}
|
||||
elseif name_to_check == 'Nebula Deck' then loc_args = {localize{type = 'name_text', key = 'v_telescope', set = 'Voucher'}, -1}
|
||||
elseif name_to_check == 'Ghost Deck' then
|
||||
elseif name_to_check == 'Abandoned Deck' then
|
||||
elseif name_to_check == 'Checkered Deck' then
|
||||
elseif name_to_check == 'Zodiac Deck' then loc_args = {localize{type = 'name_text', key = 'v_tarot_merchant', set = 'Voucher'},
|
||||
localize{type = 'name_text', key = 'v_planet_merchant', set = 'Voucher'},
|
||||
localize{type = 'name_text', key = 'v_overstock_norm', set = 'Voucher'}}
|
||||
elseif name_to_check == 'Painted Deck' then loc_args = {effect_config.hand_size,effect_config.joker_slot}
|
||||
elseif name_to_check == 'Anaglyph Deck' then loc_args = {localize{type = 'name_text', key = 'tag_double', set = 'Tag'}}
|
||||
elseif name_to_check == 'Plasma Deck' then loc_args = {effect_config.ante_scaling}
|
||||
elseif name_to_check == 'Erratic Deck' then
|
||||
end
|
||||
localize{type = 'descriptions', key = key_override or back_config.key, set = 'Back', nodes = loc_nodes, vars = loc_args}
|
||||
end
|
||||
|
||||
return
|
||||
{n=G.UIT.ROOT, config={align = "cm", minw = min_dims*5, minh = min_dims*2.5, id = self.name, colour = G.C.CLEAR}, nodes={
|
||||
name_to_check == 'Challenge Deck' and UIBox_button({button = 'deck_view_challenge', label = {localize(challenge.id, 'challenge_names')}, minw = 2.2, minh = 1, scale = 0.6, id = challenge})
|
||||
or desc_from_rows(loc_nodes, true, min_dims*5)
|
||||
}}
|
||||
end
|
||||
|
||||
function Back:change_to(new_back)
|
||||
if not new_back then new_back = G.P_CENTERS.b_red end
|
||||
self.atlas = new_back.unlocked and new_back.atlas or nil
|
||||
self.name = new_back.name or 'Red Deck'
|
||||
self.effect = {
|
||||
center = new_back,
|
||||
text_UI = '',
|
||||
config = copy_table(new_back.config)
|
||||
}
|
||||
self.loc_name = localize{type = 'name_text', set = 'Back', key = self.effect.center.key}
|
||||
local pos = self.effect.center.unlocked and copy_table(new_back.pos) or {x = 4, y = 0}
|
||||
self.pos.x = pos.x
|
||||
self.pos.y = pos.y
|
||||
end
|
||||
|
||||
function Back:save()
|
||||
local backTable = {
|
||||
name = self.name,
|
||||
pos = self.pos,
|
||||
effect = self.effect,
|
||||
key = self.effect.center.key or 'b_red'
|
||||
}
|
||||
|
||||
return backTable
|
||||
end
|
||||
|
||||
function Back:trigger_effect(args)
|
||||
if not args then return end
|
||||
local obj = self.effect.center
|
||||
if obj.trigger_effect and type(obj.trigger_effect) == 'function' then
|
||||
local o = {obj:trigger_effect(args)}
|
||||
if o then return unpack(o) end
|
||||
end
|
||||
|
||||
if self.name == 'Anaglyph Deck' and args.context == 'eval' and G.GAME.last_blind and G.GAME.last_blind.boss then
|
||||
G.E_MANAGER:add_event(Event({
|
||||
func = (function()
|
||||
add_tag(Tag('tag_double'))
|
||||
play_sound('generic1', 0.9 + math.random()*0.1, 0.8)
|
||||
play_sound('holo1', 1.2 + math.random()*0.1, 0.4)
|
||||
return true
|
||||
end)
|
||||
}))
|
||||
end
|
||||
if self.name == 'Plasma Deck' and args.context == 'blind_amount' then
|
||||
return
|
||||
end
|
||||
|
||||
if self.name == 'Plasma Deck' and args.context == 'final_scoring_step' then
|
||||
local tot = args.chips + args.mult
|
||||
args.chips = math.floor(tot/2)
|
||||
args.mult = math.floor(tot/2)
|
||||
update_hand_text({delay = 0}, {mult = args.mult, chips = args.chips})
|
||||
|
||||
G.E_MANAGER:add_event(Event({
|
||||
func = (function()
|
||||
local text = localize('k_balanced')
|
||||
play_sound('gong', 0.94, 0.3)
|
||||
play_sound('gong', 0.94*1.5, 0.2)
|
||||
play_sound('tarot1', 1.5)
|
||||
ease_colour(G.C.UI_CHIPS, {0.8, 0.45, 0.85, 1})
|
||||
ease_colour(G.C.UI_MULT, {0.8, 0.45, 0.85, 1})
|
||||
attention_text({
|
||||
scale = 1.4, text = text, hold = 2, align = 'cm', offset = {x = 0,y = -2.7},major = G.play
|
||||
})
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = 'after',
|
||||
blockable = false,
|
||||
blocking = false,
|
||||
delay = 4.3,
|
||||
func = (function()
|
||||
ease_colour(G.C.UI_CHIPS, G.C.BLUE, 2)
|
||||
ease_colour(G.C.UI_MULT, G.C.RED, 2)
|
||||
return true
|
||||
end)
|
||||
}))
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = 'after',
|
||||
blockable = false,
|
||||
blocking = false,
|
||||
no_delete = true,
|
||||
delay = 6.3,
|
||||
func = (function()
|
||||
G.C.UI_CHIPS[1], G.C.UI_CHIPS[2], G.C.UI_CHIPS[3], G.C.UI_CHIPS[4] = G.C.BLUE[1], G.C.BLUE[2], G.C.BLUE[3], G.C.BLUE[4]
|
||||
G.C.UI_MULT[1], G.C.UI_MULT[2], G.C.UI_MULT[3], G.C.UI_MULT[4] = G.C.RED[1], G.C.RED[2], G.C.RED[3], G.C.RED[4]
|
||||
return true
|
||||
end)
|
||||
}))
|
||||
return true
|
||||
end)
|
||||
}))
|
||||
|
||||
delay(0.6)
|
||||
return args.chips, args.mult
|
||||
end
|
||||
end
|
||||
|
||||
function Back:apply_to_run()
|
||||
local obj = self.effect.center
|
||||
if obj.apply and type(obj.apply) == 'function' then
|
||||
obj:apply()
|
||||
end
|
||||
|
||||
if self.effect.config.voucher then
|
||||
G.GAME.used_vouchers[self.effect.config.voucher] = true
|
||||
G.GAME.cry_owned_vouchers[self.effect.config.voucher] = true
|
||||
G.GAME.starting_voucher_count = (G.GAME.starting_voucher_count or 0) + 1
|
||||
Card.apply_to_run(nil, G.P_CENTERS[self.effect.config.voucher])
|
||||
end
|
||||
if self.effect.config.hands then
|
||||
G.GAME.starting_params.hands = G.GAME.starting_params.hands + self.effect.config.hands
|
||||
end
|
||||
if self.effect.config.consumables then
|
||||
delay(0.4)
|
||||
G.E_MANAGER:add_event(Event({
|
||||
func = function()
|
||||
for k, v in ipairs(self.effect.config.consumables) do
|
||||
local card = create_card('Tarot', G.consumeables, nil, nil, nil, nil, v, 'deck')
|
||||
card:add_to_deck()
|
||||
G.consumeables:emplace(card)
|
||||
end
|
||||
return true
|
||||
end
|
||||
}))
|
||||
end
|
||||
|
||||
|
||||
if self.effect.config.dollars then
|
||||
G.GAME.starting_params.dollars = G.GAME.starting_params.dollars + self.effect.config.dollars
|
||||
end
|
||||
if self.effect.config.remove_faces then
|
||||
G.GAME.starting_params.no_faces = true
|
||||
end
|
||||
|
||||
if self.effect.config.spectral_rate then
|
||||
G.GAME.spectral_rate = self.effect.config.spectral_rate
|
||||
end
|
||||
if self.effect.config.discards then
|
||||
G.GAME.starting_params.discards = G.GAME.starting_params.discards + self.effect.config.discards
|
||||
end
|
||||
if self.effect.config.reroll_discount then
|
||||
G.GAME.starting_params.reroll_cost = G.GAME.starting_params.reroll_cost - self.effect.config.reroll_discount
|
||||
end
|
||||
|
||||
|
||||
if self.effect.config.edition then
|
||||
G.E_MANAGER:add_event(Event({
|
||||
func = function()
|
||||
local i = 0
|
||||
while i < self.effect.config.edition_count do
|
||||
local card = pseudorandom_element(G.playing_cards, pseudoseed('edition_deck'))
|
||||
if not card.edition then
|
||||
i = i + 1
|
||||
card:set_edition({[self.effect.config.edition] = true}, nil, true)
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
}))
|
||||
end
|
||||
if self.effect.config.vouchers then
|
||||
for k, v in pairs(self.effect.config.vouchers) do
|
||||
G.GAME.used_vouchers[v ] = true
|
||||
G.GAME.cry_owned_vouchers[v ] = true
|
||||
G.GAME.starting_voucher_count = (G.GAME.starting_voucher_count or 0) + 1
|
||||
Card.apply_to_run(nil, G.P_CENTERS[v])
|
||||
end
|
||||
end
|
||||
if self.name == 'Checkered Deck' then
|
||||
G.E_MANAGER:add_event(Event({
|
||||
func = function()
|
||||
for k, v in pairs(G.playing_cards) do
|
||||
if v.base.suit == 'Clubs' then
|
||||
v:change_suit('Spades')
|
||||
end
|
||||
if v.base.suit == 'Diamonds' then
|
||||
v:change_suit('Hearts')
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
}))
|
||||
end
|
||||
if self.effect.config.randomize_rank_suit then
|
||||
G.GAME.starting_params.erratic_suits_and_ranks = true
|
||||
end
|
||||
if self.effect.config.joker_slot then
|
||||
G.GAME.starting_params.joker_slots = G.GAME.starting_params.joker_slots + self.effect.config.joker_slot
|
||||
end
|
||||
if self.effect.config.hand_size then
|
||||
G.GAME.starting_params.hand_size = G.GAME.starting_params.hand_size + self.effect.config.hand_size
|
||||
end
|
||||
if self.effect.config.ante_scaling then
|
||||
G.GAME.starting_params.ante_scaling = self.effect.config.ante_scaling
|
||||
end
|
||||
if self.effect.config.consumable_slot then
|
||||
G.GAME.starting_params.consumable_slots = G.GAME.starting_params.consumable_slots + self.effect.config.consumable_slot
|
||||
end
|
||||
if self.effect.config.no_interest then
|
||||
G.GAME.modifiers.no_interest = true
|
||||
end
|
||||
if self.effect.config.extra_hand_bonus then
|
||||
G.GAME.modifiers.money_per_hand = self.effect.config.extra_hand_bonus
|
||||
end
|
||||
if self.effect.config.extra_discard_bonus then
|
||||
G.GAME.modifiers.money_per_discard = self.effect.config.extra_discard_bonus
|
||||
end
|
||||
end
|
||||
|
||||
function Back:load(backTable)
|
||||
self.name = backTable.name
|
||||
self.pos = backTable.pos
|
||||
self.effect = backTable.effect
|
||||
self.effect.center = G.P_CENTERS[backTable.key] or G.P_CENTERS.b_red
|
||||
|
||||
|
||||
self.loc_name = localize{type = 'name_text', set = 'Back', key = self.effect.center.key}
|
||||
end
|
|
@ -1,865 +0,0 @@
|
|||
LOVELY_INTEGRITY = 'ceaf7d365cb8eac62c7dcf3be1ef07cc6b0dac3977bde52960496d7f844a668d'
|
||||
|
||||
--class
|
||||
Blind = Moveable:extend()
|
||||
|
||||
--class methods
|
||||
function Blind:init(X, Y, W, H)
|
||||
Moveable.init(self,X, Y, W, H)
|
||||
|
||||
self.children = {}
|
||||
self.config = {}
|
||||
self.tilt_var = {mx = 0, my = 0, amt = 0}
|
||||
self.ambient_tilt = 0.3
|
||||
self.chips = 0
|
||||
self.zoom = true
|
||||
self.states.collide.can = true
|
||||
self.colour = copy_table(G.C.BLACK)
|
||||
self.dark_colour = darken(self.colour, 0.2)
|
||||
self.children.animatedSprite = AnimatedSprite(self.T.x, self.T.y, self.T.w, self.T.h, G.ANIMATION_ATLAS['blind_chips'], G.P_BLINDS.bl_small.pos)
|
||||
self.children.animatedSprite.states = self.states
|
||||
self.children.animatedSprite.states.visible = false
|
||||
self.children.animatedSprite.states.drag.can = true
|
||||
self.states.collide.can = true
|
||||
self.states.drag.can = true
|
||||
self.loc_debuff_lines = {'',''}
|
||||
|
||||
self.shadow_height = 0
|
||||
|
||||
if getmetatable(self) == Blind then
|
||||
table.insert(G.I.CARD, self)
|
||||
end
|
||||
end
|
||||
|
||||
function Blind:change_colour(blind_col)
|
||||
blind_col = blind_col or get_blind_main_colour(self.config.blind.key or '')
|
||||
local dark_col = mix_colours(blind_col, G.C.BLACK, 0.4)
|
||||
ease_colour(G.C.DYN_UI.MAIN, blind_col)
|
||||
ease_colour(G.C.DYN_UI.DARK, dark_col)
|
||||
|
||||
if not self.boss and self.name then
|
||||
blind_col = darken(G.C.BLACK, 0.05)
|
||||
dark_col = lighten(G.C.BLACK, 0.07)
|
||||
else
|
||||
dark_col = mix_colours(blind_col, G.C.BLACK, 0.2)
|
||||
end
|
||||
ease_colour(G.C.DYN_UI.BOSS_MAIN, blind_col)
|
||||
ease_colour(G.C.DYN_UI.BOSS_DARK, dark_col)
|
||||
end
|
||||
|
||||
function Blind:set_text()
|
||||
if self.config.blind then
|
||||
if self.disabled then
|
||||
self.loc_name = self.name == '' and self.name or localize{type ='name_text', key = self.config.blind.key, set = 'Blind'}
|
||||
self.loc_debuff_text = ''
|
||||
EMPTY(self.loc_debuff_lines)
|
||||
else
|
||||
local loc_vars = nil
|
||||
if self.name == 'The Ox' then
|
||||
loc_vars = {localize(G.GAME.current_round.most_played_poker_hand, 'poker_hands')}
|
||||
end
|
||||
local target = {type = 'raw_descriptions', key = self.config.blind.key, set = 'Blind', vars = loc_vars or self.config.blind.vars}
|
||||
local obj = self.config.blind
|
||||
if obj.loc_vars and type(obj.loc_vars) == 'function' then
|
||||
local res = obj:loc_vars() or {}
|
||||
target.vars = res.vars or target.vars
|
||||
target.key = res.key or target.key
|
||||
end
|
||||
local loc_target = localize(target)
|
||||
if loc_target then
|
||||
self.loc_name = self.name == '' and self.name or localize{type ='name_text', key = self.config.blind.key, set = 'Blind'}
|
||||
self.loc_debuff_text = ''
|
||||
EMPTY(self.loc_debuff_lines)
|
||||
for k, v in ipairs(loc_target) do
|
||||
self.loc_debuff_text = self.loc_debuff_text..v..(k <= #loc_target and ' ' or '')
|
||||
self.loc_debuff_lines[k] = v
|
||||
end
|
||||
else
|
||||
self.loc_name = ''; self.loc_debuff_text = ''
|
||||
EMPTY(self.loc_debuff_lines)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Blind:set_blind(blind, reset, silent)
|
||||
if not reset then
|
||||
if blind then
|
||||
self.in_blind = true
|
||||
end
|
||||
self.config.blind = blind or {}
|
||||
self.name = blind and blind.name or ''
|
||||
self.dollars = blind and blind.dollars or 0
|
||||
self.sound_pings = self.dollars + 2
|
||||
if G.GAME.modifiers.no_blind_reward and G.GAME.modifiers.no_blind_reward[self:get_type()] then self.dollars = 0 end
|
||||
self.debuff = blind and blind.debuff or {}
|
||||
self.pos = blind and blind.pos
|
||||
self.mult = blind and blind.mult or 0
|
||||
self.disabled = false
|
||||
self.discards_sub = nil
|
||||
self.hands_sub = nil
|
||||
self.boss = blind and not not blind.boss
|
||||
self.blind_set = false
|
||||
self.triggered = nil
|
||||
self.prepped = true
|
||||
self:set_text()
|
||||
|
||||
local obj = self.config.blind
|
||||
self.children.animatedSprite.atlas = G.ANIMATION_ATLAS[obj.atlas] or G.ANIMATION_ATLAS['blind_chips']
|
||||
G.GAME.last_blind = G.GAME.last_blind or {}
|
||||
G.GAME.last_blind.boss = self.boss
|
||||
G.GAME.last_blind.name = self.name
|
||||
|
||||
if blind and blind.name then
|
||||
self:change_colour()
|
||||
else
|
||||
self:change_colour(G.C.BLACK)
|
||||
end
|
||||
|
||||
self.chips = get_blind_amount(G.GAME.round_resets.ante)*self.mult*G.GAME.starting_params.ante_scaling
|
||||
self.chip_text = number_format(self.chips)
|
||||
|
||||
if not blind then self.chips = 0 end
|
||||
|
||||
G.GAME.current_round.dollars_to_be_earned = self.dollars > 0 and (string.rep(localize('$'), self.dollars)..'') or ('')
|
||||
G.HUD_blind.alignment.offset.y = -10
|
||||
G.HUD_blind:recalculate(false)
|
||||
|
||||
if blind and blind.name and blind.name ~= '' then
|
||||
self:alert_debuff(true)
|
||||
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = 'after',
|
||||
delay = 0.05,
|
||||
blockable = false,
|
||||
func = (function()
|
||||
G.HUD_blind:get_UIE_by_ID("HUD_blind_name").states.visible = false
|
||||
G.HUD_blind:get_UIE_by_ID("dollars_to_be_earned").parent.parent.states.visible = false
|
||||
G.HUD_blind.alignment.offset.y = 0
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = 'after',
|
||||
delay = 0.15,
|
||||
blockable = false,
|
||||
func = (function()
|
||||
G.HUD_blind:get_UIE_by_ID("HUD_blind_name").states.visible = true
|
||||
G.HUD_blind:get_UIE_by_ID("dollars_to_be_earned").parent.parent.states.visible = true
|
||||
G.HUD_blind:get_UIE_by_ID("dollars_to_be_earned").config.object:pop_in(0)
|
||||
G.HUD_blind:get_UIE_by_ID("HUD_blind_name").config.object:pop_in(0)
|
||||
G.HUD_blind:get_UIE_by_ID("HUD_blind_count"):juice_up()
|
||||
self.children.animatedSprite:set_sprite_pos(self.config.blind.pos)
|
||||
self.blind_set = true
|
||||
G.ROOM.jiggle = G.ROOM.jiggle + 3
|
||||
if not reset and not silent then
|
||||
self:juice_up()
|
||||
if blind then play_sound('chips1', math.random()*0.1 + 0.55, 0.42);play_sound('gold_seal', math.random()*0.1 + 1.85, 0.26)--play_sound('cancel')
|
||||
end
|
||||
end
|
||||
return true
|
||||
end)
|
||||
}))
|
||||
return true
|
||||
end)
|
||||
}))
|
||||
end
|
||||
|
||||
|
||||
self.config.h_popup_config ={align="tm", offset = {x=0,y=-0.1},parent = self}
|
||||
end
|
||||
|
||||
if self.name == 'The Eye' and not reset then
|
||||
self.hands = {
|
||||
["Flush Five"] = false,
|
||||
["Flush House"] = false,
|
||||
["Five of a Kind"] = false,
|
||||
["Straight Flush"] = false,
|
||||
["Four of a Kind"] = false,
|
||||
["Full House"] = false,
|
||||
["Flush"] = false,
|
||||
["Straight"] = false,
|
||||
["Three of a Kind"] = false,
|
||||
["Two Pair"] = false,
|
||||
["Pair"] = false,
|
||||
["High Card"] = false,
|
||||
}
|
||||
end
|
||||
if self.name == 'The Mouth' and not reset then
|
||||
self.only_hand = false
|
||||
end
|
||||
if self.name == 'The Fish' and not reset then
|
||||
self.prepped = nil
|
||||
end
|
||||
if self.name == 'The Water' and not reset then
|
||||
self.discards_sub = G.GAME.current_round.discards_left
|
||||
ease_discard(-self.discards_sub)
|
||||
end
|
||||
if self.name == 'The Needle' and not reset then
|
||||
self.hands_sub = G.GAME.round_resets.hands - 1
|
||||
ease_hands_played(-self.hands_sub)
|
||||
end
|
||||
if self.name == 'The Manacle' and not reset then
|
||||
G.hand:change_size(-1)
|
||||
end
|
||||
if self.name == 'Amber Acorn' and not reset and #G.jokers.cards > 0 then
|
||||
G.jokers:unhighlight_all()
|
||||
for k, v in ipairs(G.jokers.cards) do
|
||||
v:flip()
|
||||
end
|
||||
if #G.jokers.cards > 1 then
|
||||
G.E_MANAGER:add_event(Event({ trigger = 'after', delay = 0.2, func = function()
|
||||
G.E_MANAGER:add_event(Event({ func = function() G.jokers:shuffle('aajk'); play_sound('cardSlide1', 0.85);return true end }))
|
||||
delay(0.15)
|
||||
G.E_MANAGER:add_event(Event({ func = function() G.jokers:shuffle('aajk'); play_sound('cardSlide1', 1.15);return true end }))
|
||||
delay(0.15)
|
||||
G.E_MANAGER:add_event(Event({ func = function() G.jokers:shuffle('aajk'); play_sound('cardSlide1', 1);return true end }))
|
||||
delay(0.5)
|
||||
return true end }))
|
||||
end
|
||||
end
|
||||
|
||||
if not reset then
|
||||
if blind then
|
||||
self.in_blind = true
|
||||
end
|
||||
local obj = self.config.blind
|
||||
if obj.set_blind and type(obj.set_blind) == 'function' then
|
||||
obj:set_blind()
|
||||
end
|
||||
end
|
||||
--add new debuffs
|
||||
for _, v in ipairs(G.playing_cards) do
|
||||
self:debuff_card(v)
|
||||
end
|
||||
for _, v in ipairs(G.jokers.cards) do
|
||||
if not reset then self:debuff_card(v, true) end
|
||||
end
|
||||
|
||||
G.ARGS.spin.real = (G.SETTINGS.reduced_motion and 0 or 1)*(self.config.blind.boss and (self.config.blind.boss.showdown and 0.5 or 0.25) or 0)
|
||||
end
|
||||
|
||||
function Blind:alert_debuff(first)
|
||||
if self.loc_debuff_text and self.loc_debuff_text ~= '' then
|
||||
self.block_play = true
|
||||
G.E_MANAGER:add_event(Event({
|
||||
blockable = false,
|
||||
blocking = false,
|
||||
func = (function()
|
||||
if self.disabled then self.block_play = nil; return true end
|
||||
if G.STATE == G.STATES.SELECTING_HAND then
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = 'after',
|
||||
delay = G.SETTINGS.GAMESPEED*0.05,
|
||||
blockable = false,
|
||||
func = (function()
|
||||
play_sound('whoosh1', 0.55, 0.62)
|
||||
for i = 1, 4 do
|
||||
local wait_time = (0.1*(i-1))
|
||||
G.E_MANAGER:add_event(Event({ blockable = false, trigger = 'after', delay = G.SETTINGS.GAMESPEED*wait_time,
|
||||
func = function()
|
||||
if i == 1 then self:juice_up() end
|
||||
play_sound('cancel', 0.7 + 0.05*i, 0.7)
|
||||
return true end }))
|
||||
end
|
||||
local hold_time = G.SETTINGS.GAMESPEED*(#self.loc_debuff_text*0.035 + 1.3)
|
||||
local disp_text = self:get_loc_debuff_text()
|
||||
attention_text({
|
||||
scale = 0.7, text = disp_text, maxw = 12, hold = hold_time, align = 'cm', offset = {x = 0,y = -1},major = G.play
|
||||
})
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = 'after',
|
||||
delay = 1,
|
||||
blocking = false,
|
||||
blockable = false,
|
||||
func = (function()
|
||||
self.block_play = nil
|
||||
if G.buttons then
|
||||
local _buttons = G.buttons:get_UIE_by_ID('play_button')
|
||||
_buttons.disable_button = nil
|
||||
end
|
||||
return true
|
||||
end)
|
||||
}))
|
||||
return true
|
||||
end)
|
||||
}))
|
||||
return true
|
||||
end
|
||||
end)
|
||||
}))
|
||||
end
|
||||
end
|
||||
|
||||
function Blind:get_loc_debuff_text()
|
||||
local obj = self.config.blind
|
||||
if obj.get_loc_debuff_text and type(obj.get_loc_debuff_text) == 'function' then
|
||||
return obj:get_loc_debuff_text()
|
||||
end
|
||||
local disp_text = (self.config.blind.name == 'The Wheel' and G.GAME.probabilities.normal or '')..self.loc_debuff_text
|
||||
if (self.config.blind.name == 'The Mouth') and self.only_hand then disp_text = disp_text..' ['..localize(self.only_hand, 'poker_hands')..']' end
|
||||
return disp_text
|
||||
end
|
||||
|
||||
function Blind:defeat(silent)
|
||||
local dissolve_time = 1.3
|
||||
local extra_time = 0
|
||||
self.dissolve = 0
|
||||
self.dissolve_colours = {G.C.BLACK, G.C.RED}
|
||||
self:juice_up()
|
||||
self.children.particles = Particles(0, 0, 0,0, {
|
||||
timer_type = 'TOTAL',
|
||||
timer = 0.01*dissolve_time,
|
||||
scale = 0.1,
|
||||
speed = 1.5,
|
||||
lifespan = 0.7*dissolve_time,
|
||||
attach = self,
|
||||
colours = self.dissolve_colours,
|
||||
fill = true
|
||||
})
|
||||
|
||||
local blind_name_dynatext = G.HUD_blind:get_UIE_by_ID('HUD_blind_name').config.object
|
||||
blind_name_dynatext:pop_out(2)
|
||||
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = 'after',
|
||||
blockable = false,
|
||||
delay = 0.5*dissolve_time,
|
||||
func = (function() self.children.particles.max = 0 return true end)
|
||||
}))
|
||||
if not silent then
|
||||
for i = 1, math.min(self.sound_pings or 3, 7) do
|
||||
extra_time = extra_time + (0.4+0.15*i)*dissolve_time
|
||||
G.E_MANAGER:add_event(Event({ blockable = false, trigger = 'after', delay = (0.15 - 0.01*(self.sound_pings or 3))*i*dissolve_time,
|
||||
func = function()
|
||||
play_sound('cancel', 0.8 - 0.05*i, 1.7)
|
||||
if i == math.min((self.sound_pings or 3)+1, 6) then play_sound('whoosh2', 0.7, 0.42) end
|
||||
return true end }))
|
||||
end
|
||||
end
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = 'ease',
|
||||
blockable = false,
|
||||
ref_table = self,
|
||||
ref_value = 'dissolve',
|
||||
ease_to = 1,
|
||||
delay = 0.7*dissolve_time,
|
||||
func = (function(t) return t end)
|
||||
}))
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = 'after',
|
||||
blockable = false,
|
||||
delay = 0.8*dissolve_time,
|
||||
func = (function()
|
||||
G.HUD_blind.alignment.offset.y = -10
|
||||
return true
|
||||
end)
|
||||
}))
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = 'after',
|
||||
blockable = false,
|
||||
delay = 0.95*dissolve_time,
|
||||
func = (function()
|
||||
self.dissolve = nil
|
||||
self:set_blind(nil, nil, true) return true end)
|
||||
}))
|
||||
for k, v in ipairs(G.jokers.cards) do
|
||||
if v.facing == 'back' then v:flip() end
|
||||
end
|
||||
local obj = self.config.blind
|
||||
if obj.defeat and type(obj.defeat) == 'function' then
|
||||
obj:defeat()
|
||||
end
|
||||
if self.name == 'Crimson Heart' then
|
||||
for _, v in ipairs(G.jokers.cards) do
|
||||
v.ability.crimson_heart_chosen = nil
|
||||
end
|
||||
end
|
||||
if self.name == 'The Manacle' and not self.disabled then
|
||||
G.hand:change_size(1)
|
||||
end
|
||||
end
|
||||
|
||||
function Blind:get_type()
|
||||
if self.name == "Small Blind" then
|
||||
return 'Small'
|
||||
elseif self.name == "Big Blind" then
|
||||
return 'Big'
|
||||
elseif self.name and self.name ~= '' then
|
||||
return 'Boss'
|
||||
end
|
||||
end
|
||||
|
||||
function Blind:disable()
|
||||
self.disabled = true
|
||||
for k, v in ipairs(G.jokers.cards) do
|
||||
if v.facing == 'back' then v:flip() end
|
||||
end
|
||||
local obj = self.config.blind
|
||||
if obj.disable and type(obj.disable) == 'function' then
|
||||
obj:disable()
|
||||
end
|
||||
if self.name == 'Crimson Heart' then
|
||||
for _, v in ipairs(G.jokers.cards) do
|
||||
v.ability.crimson_heart_chosen = nil
|
||||
end
|
||||
end
|
||||
if self.name == 'The Water' then
|
||||
ease_discard(self.discards_sub)
|
||||
end
|
||||
if self.name == 'The Wheel' or self.name == 'The House' or self.name == 'The Mark' or self.name == 'The Fish' then
|
||||
for i = 1, #G.hand.cards do
|
||||
if G.hand.cards[i].facing == 'back' then
|
||||
G.hand.cards[i]:flip()
|
||||
end
|
||||
end
|
||||
for k, v in pairs(G.playing_cards) do
|
||||
v.ability.wheel_flipped = nil
|
||||
end
|
||||
end
|
||||
if self.name == 'The Needle' then
|
||||
ease_hands_played(self.hands_sub)
|
||||
end
|
||||
if self.name == 'The Wall' then
|
||||
self.chips = self.chips/2
|
||||
self.chip_text = number_format(self.chips)
|
||||
end
|
||||
if self.name == 'Cerulean Bell' then
|
||||
for k, v in ipairs(G.playing_cards) do
|
||||
v.ability.forced_selection = nil
|
||||
end
|
||||
end
|
||||
if self.name == 'The Manacle' then
|
||||
G.hand:change_size(1)
|
||||
end
|
||||
if self.name == 'The Serpent' then
|
||||
end
|
||||
if self.name == 'Violet Vessel' then
|
||||
self.chips = self.chips/3
|
||||
self.chip_text = number_format(self.chips)
|
||||
end
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = 'immediate',
|
||||
func = function()
|
||||
if self.boss and to_big(G.GAME.chips) - G.GAME.blind.chips >= to_big(0) then
|
||||
G.STATE = G.STATES.NEW_ROUND
|
||||
G.STATE_COMPLETE = false
|
||||
end
|
||||
return true
|
||||
end
|
||||
}))
|
||||
for _, v in ipairs(G.playing_cards) do
|
||||
self:debuff_card(v)
|
||||
end
|
||||
for _, v in ipairs(G.jokers.cards) do
|
||||
self:debuff_card(v)
|
||||
end
|
||||
self:set_text()
|
||||
self:wiggle()
|
||||
end
|
||||
|
||||
function Blind:wiggle()
|
||||
self.children.animatedSprite:juice_up(0.3)
|
||||
G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.06*G.SETTINGS.GAMESPEED, blockable = false, blocking = false, func = function()
|
||||
play_sound('tarot2', 0.76, 0.4);return true end}))
|
||||
play_sound('tarot2', 1, 0.4)
|
||||
end
|
||||
|
||||
function Blind:juice_up(_a, _b)
|
||||
self.children.animatedSprite:juice_up(_a or 0.2, _b or 0.2)
|
||||
end
|
||||
|
||||
function Blind:hover()
|
||||
if not G.CONTROLLER.dragging.target or G.CONTROLLER.using_touch then
|
||||
if not self.hovering and self.states.visible and self.children.animatedSprite.states.visible then
|
||||
self.hovering = true
|
||||
self.hover_tilt = 2
|
||||
self.children.animatedSprite:juice_up(0.05, 0.02)
|
||||
play_sound('chips1', math.random()*0.1 + 0.55, 0.12)
|
||||
Node.hover(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Blind:stop_hover()
|
||||
self.hovering = false
|
||||
self.hover_tilt = 0
|
||||
Node.stop_hover(self)
|
||||
end
|
||||
|
||||
function Blind:draw()
|
||||
if not self.states.visible then return end
|
||||
self.tilt_var = self.tilt_var or {}
|
||||
self.tilt_var.mx, self.tilt_var.my =G.CONTROLLER.cursor_position.x,G.CONTROLLER.cursor_position.y
|
||||
|
||||
self.children.animatedSprite.role.draw_major = self
|
||||
self.children.animatedSprite:draw_shader('dissolve', 0.1)
|
||||
self.children.animatedSprite:draw_shader('dissolve')
|
||||
|
||||
for k, v in pairs(self.children) do
|
||||
if k ~= 'animatedSprite' then
|
||||
v.VT.scale = self.VT.scale
|
||||
v:draw()
|
||||
end
|
||||
end
|
||||
add_to_drawhash(self)
|
||||
end
|
||||
|
||||
function Blind:press_play()
|
||||
if self.disabled then return end
|
||||
local obj = self.config.blind
|
||||
if obj.press_play and type(obj.press_play) == 'function' then
|
||||
return obj:press_play()
|
||||
end
|
||||
if self.name == "The Hook" then
|
||||
G.E_MANAGER:add_event(Event({ func = function()
|
||||
local any_selected = nil
|
||||
local _cards = {}
|
||||
for k, v in ipairs(G.hand.cards) do
|
||||
_cards[#_cards+1] = v
|
||||
end
|
||||
for i = 1, 2 do
|
||||
if G.hand.cards[i] then
|
||||
local selected_card, card_key = pseudorandom_element(_cards, pseudoseed('hook'))
|
||||
G.hand:add_to_highlighted(selected_card, true)
|
||||
table.remove(_cards, card_key)
|
||||
any_selected = true
|
||||
play_sound('card1', 1)
|
||||
end
|
||||
end
|
||||
if any_selected then G.FUNCS.discard_cards_from_highlighted(nil, true) end
|
||||
return true end }))
|
||||
self.triggered = true
|
||||
delay(0.7)
|
||||
return true
|
||||
end
|
||||
if self.name == 'Crimson Heart' then
|
||||
if G.jokers.cards[1] then
|
||||
self.triggered = true
|
||||
self.prepped = true
|
||||
end
|
||||
end
|
||||
if self.name == 'The Fish' then
|
||||
self.prepped = true
|
||||
end
|
||||
if self.name == "The Tooth" then
|
||||
G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.2, func = function()
|
||||
for i = 1, #G.play.cards do
|
||||
G.E_MANAGER:add_event(Event({func = function() G.play.cards[i]:juice_up(); return true end }))
|
||||
ease_dollars(-1)
|
||||
delay(0.23)
|
||||
end
|
||||
return true end }))
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function Blind:modify_hand(cards, poker_hands, text, mult, hand_chips)
|
||||
if self.disabled then return mult, hand_chips, false end
|
||||
local obj = self.config.blind
|
||||
if obj.modify_hand and type(obj.modify_hand) == 'function' then
|
||||
return obj:modify_hand(cards, poker_hands, text, mult, hand_chips)
|
||||
end
|
||||
if self.name == "The Flint" then
|
||||
self.triggered = true
|
||||
return math.max(math.floor(mult*0.5 + 0.5), 1), math.max(math.floor(hand_chips*0.5 + 0.5), 0), true
|
||||
end
|
||||
return mult, hand_chips, false
|
||||
end
|
||||
|
||||
function Blind:debuff_hand(cards, hand, handname, check)
|
||||
if self.disabled then return end
|
||||
local obj = self.config.blind
|
||||
if obj.debuff_hand and type(obj.debuff_hand) == 'function' then
|
||||
return obj:debuff_hand(cards, hand, handname, check)
|
||||
end
|
||||
if self.debuff then
|
||||
self.triggered = false
|
||||
if self.debuff.hand and next(hand[self.debuff.hand]) then
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
if self.name == "The Psychic" and #cards > 5 then
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
if self.debuff.h_size_ge and #cards < self.debuff.h_size_ge then
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
if self.debuff.h_size_le and #cards > self.debuff.h_size_le then
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
if self.name == "The Eye" then
|
||||
if self.hands[handname] then
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
if not check then self.hands[handname] = true end
|
||||
end
|
||||
if self.name == "The Mouth" then
|
||||
if self.only_hand and self.only_hand ~= handname then
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
if not check then self.only_hand = handname end
|
||||
end
|
||||
end
|
||||
if self.name == 'The Arm' then
|
||||
self.triggered = false
|
||||
if G.GAME.hands[handname].level > 1 then
|
||||
self.triggered = true
|
||||
if not check then
|
||||
level_up_hand(self.children.animatedSprite, handname, nil, -1)
|
||||
self:wiggle()
|
||||
end
|
||||
end
|
||||
end
|
||||
if self.name == 'The Ox' then
|
||||
self.triggered = false
|
||||
if handname == G.GAME.current_round.most_played_poker_hand then
|
||||
self.triggered = true
|
||||
if not check then
|
||||
ease_dollars(-G.GAME.dollars, true)
|
||||
self:wiggle()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Blind:drawn_to_hand()
|
||||
if not self.disabled then
|
||||
local obj = self.config.blind
|
||||
if obj.drawn_to_hand and type(obj.drawn_to_hand) == 'function' then
|
||||
obj:drawn_to_hand()
|
||||
end if self.name == 'Cerulean Bell' then
|
||||
local any_forced = nil
|
||||
for k, v in ipairs(G.hand.cards) do
|
||||
if v.ability.forced_selection then
|
||||
any_forced = true
|
||||
end
|
||||
end
|
||||
if not any_forced then
|
||||
G.hand:unhighlight_all()
|
||||
local forced_card = pseudorandom_element(G.hand.cards, pseudoseed('cerulean_bell'))
|
||||
forced_card.ability.forced_selection = true
|
||||
G.hand:add_to_highlighted(forced_card)
|
||||
end
|
||||
end
|
||||
if self.name == 'Crimson Heart' and self.prepped and G.jokers.cards[1] then
|
||||
local prev_chosen_set = {}
|
||||
local fallback_jokers = {}
|
||||
local jokers = {}
|
||||
for i = 1, #G.jokers.cards do
|
||||
if G.jokers.cards[i].ability.crimson_heart_chosen then
|
||||
prev_chosen_set[G.jokers.cards[i]] = true
|
||||
G.jokers.cards[i].ability.crimson_heart_chosen = nil
|
||||
if G.jokers.cards[i].debuff then SMODS.recalc_debuff(G.jokers.cards[i]) end
|
||||
end
|
||||
end
|
||||
for i = 1, #G.jokers.cards do
|
||||
if not G.jokers.cards[i].debuff then
|
||||
if not prev_chosen_set[G.jokers.cards[i]] then
|
||||
jokers[#jokers+1] = G.jokers.cards[i]
|
||||
end
|
||||
table.insert(fallback_jokers, G.jokers.cards[i])
|
||||
end
|
||||
end
|
||||
if #jokers == 0 then jokers = fallback_jokers end
|
||||
local _card = pseudorandom_element(jokers, pseudoseed('crimson_heart'))
|
||||
if _card then
|
||||
_card.ability.crimson_heart_chosen = true
|
||||
SMODS.recalc_debuff(_card)
|
||||
_card:juice_up()
|
||||
self:wiggle()
|
||||
end
|
||||
end
|
||||
end
|
||||
self.prepped = nil
|
||||
end
|
||||
|
||||
function Blind:stay_flipped(area, card)
|
||||
if not self.disabled then
|
||||
local obj = self.config.blind
|
||||
if obj.stay_flipped and type(obj.stay_flipped) == 'function' then
|
||||
return obj:stay_flipped(area, card)
|
||||
end
|
||||
if area == G.hand then
|
||||
if self.name == 'The Wheel' and pseudorandom(pseudoseed('wheel')) < G.GAME.probabilities.normal/7 then
|
||||
return true
|
||||
end
|
||||
if self.name == 'The House' and G.GAME.current_round.hands_played == 0 and G.GAME.current_round.discards_used == 0 then
|
||||
return true
|
||||
end
|
||||
if self.name == 'The Mark' and card:is_face(true) then
|
||||
return true
|
||||
end
|
||||
if self.name == 'The Fish' and self.prepped then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Blind:debuff_card(card, from_blind)
|
||||
local obj = self.config.blind
|
||||
if not self.disabled and obj.recalc_debuff and type(obj.recalc_debuff) == 'function' then
|
||||
if obj:recalc_debuff(card, from_blind) then
|
||||
card:set_debuff(true)
|
||||
if card.debuff then card.debuffed_by_blind = true end
|
||||
else
|
||||
card:set_debuff(false)
|
||||
end
|
||||
return
|
||||
elseif not self.disabled and obj.debuff_card and type(obj.debuff_card) == 'function' then
|
||||
sendWarnMessage(("Blind object %s has debuff_card function, recalc_debuff is preferred"):format(obj.key), obj.set)
|
||||
if obj:debuff_card(card, from_blind) then
|
||||
card:set_debuff(true)
|
||||
if card.debuff then card.debuffed_by_blind = true end
|
||||
else
|
||||
card:set_debuff(false)
|
||||
end
|
||||
return
|
||||
end
|
||||
if self.debuff and not self.disabled and card.area ~= G.jokers then
|
||||
if self.debuff.suit and card:is_suit(self.debuff.suit, true) then
|
||||
card:set_debuff(true)
|
||||
if card.debuff then card.debuffed_by_blind = true end
|
||||
return
|
||||
end
|
||||
if self.debuff.is_face =='face' and card:is_face(true) then
|
||||
card:set_debuff(true)
|
||||
if card.debuff then card.debuffed_by_blind = true end
|
||||
return
|
||||
end
|
||||
if self.name == 'The Pillar' and card.ability.played_this_ante then
|
||||
card:set_debuff(true)
|
||||
if card.debuff then card.debuffed_by_blind = true end
|
||||
return
|
||||
end
|
||||
if self.debuff.value and self.debuff.value == card.base.value then
|
||||
card:set_debuff(true)
|
||||
if card.debuff then card.debuffed_by_blind = true end
|
||||
return
|
||||
end
|
||||
if self.debuff.nominal and self.debuff.nominal == card.base.nominal then
|
||||
card:set_debuff(true)
|
||||
if card.debuff then card.debuffed_by_blind = true end
|
||||
return
|
||||
end
|
||||
end
|
||||
if self.name == 'Crimson Heart' and not self.disabled and card.area == G.jokers then
|
||||
if card.ability.crimson_heart_chosen then
|
||||
card:set_debuff(true);
|
||||
if card.debuff then card.debuffed_by_blind = true end
|
||||
return
|
||||
end
|
||||
end
|
||||
if self.name == 'Verdant Leaf' and not self.disabled and card.area ~= G.jokers then card:set_debuff(true); if card.debuff then card.debuffed_by_blind = true end; return end
|
||||
card:set_debuff(false)
|
||||
end
|
||||
|
||||
function Blind:move(dt)
|
||||
Moveable.move(self, dt)
|
||||
self:align()
|
||||
end
|
||||
|
||||
function Blind:change_dim(w, h)
|
||||
self.T.w = w or self.T.w
|
||||
self.T.h = h or self.T.h
|
||||
self.children.animatedSprite.T.w = w or self.T.w
|
||||
self.children.animatedSprite.T.h = h or self.T.h
|
||||
self.children.animatedSprite:rescale()
|
||||
end
|
||||
|
||||
function Blind:align()
|
||||
for k, v in pairs(self.children) do
|
||||
if k == 'animatedSprite' then
|
||||
if not v.states.drag.is then
|
||||
v.T.r = 0.02*math.sin(2*G.TIMERS.REAL+self.T.x)
|
||||
v.T.y = self.T.y + 0.03*math.sin(0.666*G.TIMERS.REAL+self.T.x)
|
||||
self.shadow_height = 0.1 - (0.04 + 0.03*math.sin(0.666*G.TIMERS.REAL+self.T.x))
|
||||
v.T.x = self.T.x + 0.03*math.sin(0.436*G.TIMERS.REAL+self.T.x)
|
||||
end
|
||||
else
|
||||
v.T.x = self.T.x
|
||||
v.T.y = self.T.y
|
||||
v.T.r = self.T.r
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Blind:save()
|
||||
local blindTable = {
|
||||
in_blind = self.in_blind,
|
||||
name = self.name,
|
||||
dollars = self.dollars,
|
||||
debuff = self.debuff,
|
||||
pos = self.pos,
|
||||
mult = self.mult,
|
||||
disabled = self.disabled,
|
||||
discards_sub = self.discards_sub,
|
||||
hands_sub = self.hands_sub,
|
||||
boss = self.boss,
|
||||
config_blind = '',
|
||||
chips = self.chips,
|
||||
chip_text =self.chip_text,
|
||||
hands = self.hands,
|
||||
only_hand = self.only_hand,
|
||||
triggered = self.triggered
|
||||
}
|
||||
|
||||
for k, v in pairs(G.P_BLINDS) do
|
||||
if v and v.name and v.name == blindTable.name then
|
||||
blindTable.config_blind = k
|
||||
end
|
||||
end
|
||||
|
||||
return blindTable
|
||||
end
|
||||
|
||||
function Blind:load(blindTable)
|
||||
self.in_blind = blindTable.in_blind
|
||||
self.config.blind = G.P_BLINDS[blindTable.config_blind] or {}
|
||||
|
||||
self.name = blindTable.name
|
||||
self.dollars = blindTable.dollars
|
||||
self.debuff = blindTable.debuff
|
||||
self.pos = blindTable.pos
|
||||
self.mult = blindTable.mult
|
||||
self.disabled = blindTable.disabled
|
||||
self.discards_sub = blindTable.discards_sub
|
||||
self.hands_sub = blindTable.hands_sub
|
||||
self.boss = blindTable.boss
|
||||
self.chips = blindTable.chips
|
||||
self.chip_text = blindTable.chip_text
|
||||
self.hands = blindTable.hands
|
||||
self.only_hand = blindTable.only_hand
|
||||
self.triggered = blindTable.triggered
|
||||
|
||||
G.ARGS.spin.real = (G.SETTINGS.reduced_motion and 0 or 1)*(self.config.blind.boss and (self.config.blind.boss.showdown and 1 or 0.3) or 0)
|
||||
|
||||
if G.P_BLINDS[blindTable.config_blind] then
|
||||
if self.config.blind.atlas then
|
||||
self.children.animatedSprite.atlas = G.ANIMATION_ATLAS[self.config.blind.atlas]
|
||||
end
|
||||
self.blind_set = true
|
||||
self.children.animatedSprite.states.visible = true
|
||||
self.children.animatedSprite:set_sprite_pos(self.config.blind.pos)
|
||||
self.children.animatedSprite:juice_up(0.3)
|
||||
self:align()
|
||||
self.children.animatedSprite:hard_set_VT()
|
||||
else
|
||||
self.children.animatedSprite.states.visible = false
|
||||
end
|
||||
|
||||
self.children.animatedSprite.states = self.states
|
||||
self:change_colour()
|
||||
if self.dollars > 0 then
|
||||
G.GAME.current_round.dollars_to_be_earned = string.rep(localize('$'), self.dollars)..''
|
||||
G.HUD_blind:get_UIE_by_ID("dollars_to_be_earned").config.object:pop_in(0)
|
||||
end
|
||||
if G.GAME.blind.name and G.GAME.blind.name ~= '' then
|
||||
G.HUD_blind.alignment.offset.y = 0
|
||||
end
|
||||
self:set_text()
|
||||
end
|
5351
lovely/dump/card.lua
5351
lovely/dump/card.lua
File diff suppressed because it is too large
Load diff
|
@ -1,727 +0,0 @@
|
|||
LOVELY_INTEGRITY = 'e8693aca875516bf9cb3c84fcb6f392131135da095f221f2ef0e6ac727b926df'
|
||||
|
||||
--Class
|
||||
CardArea = Moveable:extend()
|
||||
|
||||
--Class Methods
|
||||
function CardArea:init(X, Y, W, H, config)
|
||||
Moveable.init(self, X, Y, W, H)
|
||||
|
||||
self.states.drag.can = false
|
||||
self.states.hover.can = false
|
||||
self.states.click.can = false
|
||||
|
||||
|
||||
self.config = config or {}
|
||||
self.card_w = config.card_w or G.CARD_W
|
||||
self.cards = {}
|
||||
self.children = {}
|
||||
self.highlighted = {}
|
||||
self.config.highlighted_limit = config.highlight_limit or G.GAME.modifiers.cry_highlight_limit or 5
|
||||
self.config.card_limit = config.card_limit or 52
|
||||
self.config.temp_limit = self.config.card_limit
|
||||
self.config.card_count = 0
|
||||
self.config.type = config.type or 'deck'
|
||||
self.config.sort = config.sort or 'desc'
|
||||
self.config.lr_padding = config.lr_padding or 0.1
|
||||
self.shuffle_amt = 0
|
||||
|
||||
if getmetatable(self) == CardArea then
|
||||
table.insert(G.I.CARDAREA, self)
|
||||
end
|
||||
end
|
||||
|
||||
function CardArea:emplace(card, location, stay_flipped)
|
||||
if self == G.jokers then
|
||||
Cartomancer.handle_joker_added(card)
|
||||
end
|
||||
if card.edition and card.edition.card_limit and (self == G.hand) then
|
||||
self.config.real_card_limit = (self.config.real_card_limit or self.config.card_limit) + card.edition.card_limit
|
||||
self.config.card_limit = math.max(0, self.config.real_card_limit)
|
||||
end
|
||||
if location == 'front' or self.config.type == 'deck' then
|
||||
table.insert(self.cards, 1, card)
|
||||
else
|
||||
self.cards[#self.cards+1] = card
|
||||
end
|
||||
if card.cry_flipped then card.facing = 'back'; card.sprite_facing = 'back' end
|
||||
if not (card.cry_flipped and (self == G.shop_jokers or self == G.shop_vouchers or self == G.shop_booster)) and card.facing == 'back' and self.config.type ~= 'discard' and self.config.type ~= 'deck' and not stay_flipped then
|
||||
card:flip()
|
||||
end
|
||||
if self == G.hand and stay_flipped then
|
||||
card.ability.wheel_flipped = true
|
||||
end
|
||||
|
||||
if #self.cards > self.config.card_limit then
|
||||
if self == G.deck then
|
||||
self.config.card_limit = #self.cards
|
||||
end
|
||||
end
|
||||
|
||||
card:set_card_area(self)
|
||||
self:set_ranks()
|
||||
self:align_cards()
|
||||
|
||||
if self == G.jokers then
|
||||
local joker_tally = 0
|
||||
for i = 1, #G.jokers.cards do
|
||||
if G.jokers.cards[i].ability.set == 'Joker' then joker_tally = joker_tally + 1 end
|
||||
end
|
||||
if joker_tally > G.GAME.max_jokers then G.GAME.max_jokers = joker_tally end
|
||||
check_for_unlock({type = 'modify_jokers'})
|
||||
end
|
||||
if self == G.deck then check_for_unlock({type = 'modify_deck', deck = self}) end
|
||||
end
|
||||
|
||||
function CardArea:remove_card(card, discarded_only)
|
||||
if not self.cards then return end
|
||||
local _cards = discarded_only and {} or self.cards
|
||||
if discarded_only then
|
||||
for k, v in ipairs(self.cards) do
|
||||
if v.ability and v.ability.discarded then
|
||||
_cards[#_cards+1] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
if self.config.type == 'discard' or self.config.type == 'deck' then
|
||||
card = card or _cards[#_cards]
|
||||
else
|
||||
card = card or _cards[1]
|
||||
end
|
||||
for i = #self.cards,1,-1 do
|
||||
if self.cards[i] == card then
|
||||
if card.edition and card.edition.card_limit and (self == G.hand) then
|
||||
self.config.real_card_limit = (self.config.real_card_limit or self.config.card_limit) - card.edition.card_limit
|
||||
self.config.card_limit = math.max(0, self.config.real_card_limit)
|
||||
end
|
||||
card:remove_from_area()
|
||||
table.remove(self.cards, i)
|
||||
self:remove_from_highlighted(card, true)
|
||||
break
|
||||
end
|
||||
end
|
||||
self:set_ranks()
|
||||
if self == G.deck then check_for_unlock({type = 'modify_deck', deck = self}) end
|
||||
return card
|
||||
end
|
||||
|
||||
function CardArea:change_size(delta)
|
||||
if delta ~= 0 then
|
||||
G.E_MANAGER:add_event(Event({
|
||||
func = function()
|
||||
self.config.real_card_limit = (self.config.real_card_limit or self.config.card_limit) + delta
|
||||
self.config.card_limit = math.max(0, self.config.real_card_limit)
|
||||
if delta > 0 and self.config.real_card_limit > 1 and self == G.hand and self.cards[1] and (G.STATE == G.STATES.DRAW_TO_HAND or G.STATE == G.STATES.SELECTING_HAND) then
|
||||
local card_count = math.abs(delta)
|
||||
for i=1, card_count do
|
||||
draw_card(G.deck,G.hand, i*100/card_count,nil, nil , nil, 0.07)
|
||||
G.E_MANAGER:add_event(Event({func = function() self:sort() return true end}))
|
||||
end
|
||||
end
|
||||
if self == G.hand then check_for_unlock({type = 'min_hand_size'}) end
|
||||
return true
|
||||
end}))
|
||||
end
|
||||
end
|
||||
|
||||
function CardArea:can_highlight(card)
|
||||
if G.CONTROLLER.HID.controller then
|
||||
if self.config.type == 'hand'
|
||||
then
|
||||
return true
|
||||
end
|
||||
else
|
||||
if self.config.type == 'hand' or
|
||||
self.config.type == 'joker' or
|
||||
self.config.type == 'consumeable' or
|
||||
(self.config.type == 'shop' and self.config.highlighted_limit > 0)
|
||||
then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function CardArea:add_to_highlighted(card, silent)
|
||||
--if self.config.highlighted_limit <= #self.highlighted then return end
|
||||
if self.config.type == 'shop' then
|
||||
if self.highlighted[1] then
|
||||
self:remove_from_highlighted(self.highlighted[1])
|
||||
end
|
||||
--if not G.FUNCS.check_for_buy_space(card) then return false end
|
||||
self.highlighted[#self.highlighted+1] = card
|
||||
card:highlight(true)
|
||||
if not silent then play_sound('cardSlide1') end
|
||||
elseif self.config.type == 'joker' or self.config.type == 'consumeable' then
|
||||
if #self.highlighted >= self.config.highlighted_limit then
|
||||
self:remove_from_highlighted(self.highlighted[1])
|
||||
end
|
||||
self.highlighted[#self.highlighted+1] = card
|
||||
card:highlight(true)
|
||||
if not silent then play_sound('cardSlide1') end
|
||||
else
|
||||
if #self.highlighted >= self.config.highlighted_limit then
|
||||
card:highlight(false)
|
||||
else
|
||||
self.highlighted[#self.highlighted+1] = card
|
||||
card:highlight(true)
|
||||
if not silent then play_sound('cardSlide1') end
|
||||
end
|
||||
if self == G.hand and G.STATE == G.STATES.SELECTING_HAND then
|
||||
self:parse_highlighted()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function CardArea:parse_highlighted()
|
||||
G.boss_throw_hand = nil
|
||||
local text,disp_text,poker_hands = G.FUNCS.get_poker_hand_info(self.highlighted)
|
||||
if text == 'NULL' then
|
||||
update_hand_text({immediate = true, nopulse = true, delay = 0}, {mult = 0, chips = 0, level = '', handname = ''})
|
||||
else
|
||||
if G.GAME.blind and G.GAME.blind:debuff_hand(self.highlighted, poker_hands, text, true) then
|
||||
G.boss_throw_hand = true
|
||||
else
|
||||
|
||||
end
|
||||
local backwards = nil
|
||||
for k, v in pairs(self.highlighted) do
|
||||
if v.facing == 'back' then
|
||||
backwards = true
|
||||
end
|
||||
end
|
||||
if backwards then
|
||||
update_hand_text({immediate = true, nopulse = nil, delay = 0}, {handname='????', level='?', mult = '?', chips = '?'})
|
||||
else
|
||||
update_hand_text({immediate = true, nopulse = nil, delay = 0}, {handname=disp_text, level=G.GAME.hands[text].level, mult = cry_ascend(G.GAME.hands[text].mult), chips = cry_ascend(G.GAME.hands[text].chips)})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function CardArea:remove_from_highlighted(card, force)
|
||||
if (not force) and card and card.ability.forced_selection and self == G.hand then return end
|
||||
for i = #self.highlighted,1,-1 do
|
||||
if self.highlighted[i] == card then
|
||||
table.remove(self.highlighted, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
card:highlight(false)
|
||||
if self == G.hand and G.STATE == G.STATES.SELECTING_HAND then
|
||||
self:parse_highlighted()
|
||||
end
|
||||
end
|
||||
|
||||
function CardArea:unhighlight_all()
|
||||
for i = #self.highlighted,1,-1 do
|
||||
if self.highlighted[i].ability.forced_selection and self == G.hand then
|
||||
else
|
||||
self.highlighted[i]:highlight(false)
|
||||
table.remove(self.highlighted, i)
|
||||
end
|
||||
end
|
||||
if self == G.hand and G.STATE == G.STATES.SELECTING_HAND then
|
||||
self:parse_highlighted()
|
||||
end
|
||||
end
|
||||
|
||||
function CardArea:set_ranks()
|
||||
for k, card in ipairs(self.cards) do
|
||||
card.rank = k
|
||||
card.states.collide.can = true
|
||||
if k > 1 and self.config.type == 'deck' then
|
||||
card.states.drag.can = false
|
||||
card.states.collide.can = false
|
||||
elseif self.config.type == 'play' or self.config.type == 'shop' or self.config.type == 'consumeable' then
|
||||
card.states.drag.can = false
|
||||
else
|
||||
card.states.drag.can = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function CardArea:move(dt)
|
||||
--Set sliding up/down for the hand area
|
||||
if self == G.hand then
|
||||
local desired_y = G.TILE_H - G.hand.T.h - 1.9*((not G.deck_preview and (G.STATE == G.STATES.SELECTING_HAND or G.STATE == G.STATES.DRAW_TO_HAND)) and 1 or 0)
|
||||
G.hand.T.y = 15*G.real_dt*desired_y + (1-15*G.real_dt)*G.hand.T.y
|
||||
if math.abs(desired_y - G.hand.T.y) < 0.01 then G.hand.T.y = desired_y end
|
||||
if G.STATE == G.STATES.TUTORIAL then
|
||||
G.play.T.y = G.hand.T.y - (3 + 0.6)
|
||||
end
|
||||
end
|
||||
Moveable.move(self, dt)
|
||||
self:align_cards()
|
||||
end
|
||||
|
||||
function CardArea:update(dt)
|
||||
if self == G.hand then
|
||||
if G.GAME.modifiers.minus_hand_size_per_X_dollar then
|
||||
self.config.last_poll_size = self.config.last_poll_size or 0
|
||||
if math.floor(G.GAME.dollars/G.GAME.modifiers.minus_hand_size_per_X_dollar) ~= self.config.last_poll_size then
|
||||
self:change_size(self.config.last_poll_size - math.floor(G.GAME.dollars/G.GAME.modifiers.minus_hand_size_per_X_dollar))
|
||||
self.config.last_poll_size = math.floor(G.GAME.dollars/G.GAME.modifiers.minus_hand_size_per_X_dollar)
|
||||
end
|
||||
end
|
||||
for k, v in pairs(self.cards) do
|
||||
if v.ability.forced_selection and not self.highlighted[1] then
|
||||
self:add_to_highlighted(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
if self == G.deck then
|
||||
self.states.collide.can = true
|
||||
self.states.hover.can = true
|
||||
self.states.click.can = true
|
||||
end
|
||||
--Check and see if controller is being used
|
||||
if G.CONTROLLER.HID.controller and self ~= G.hand then self:unhighlight_all() end
|
||||
if self == G.deck and self.config.card_limit > #G.playing_cards then self.config.card_limit = #G.playing_cards end
|
||||
self.config.temp_limit = math.max(#self.cards, self.config.card_limit)
|
||||
self.config.card_count = #self.cards
|
||||
end
|
||||
|
||||
function CardArea:draw()
|
||||
if not self.states.visible then return end
|
||||
if G.VIEWING_DECK and (self==G.deck or self==G.hand or self==G.play) then return end
|
||||
|
||||
local state = G.TAROT_INTERRUPT or G.STATE
|
||||
|
||||
self.ARGS.invisible_area_types = self.ARGS.invisible_area_types or {discard=1, voucher=1, play=1, consumeable=1, title = 1, title_2 = 1}
|
||||
if self.ARGS.invisible_area_types[self.config.type] or
|
||||
(self.config.type == 'hand' and ({[G.STATES.SHOP]=1, [G.STATES.TAROT_PACK]=1, [G.STATES.SPECTRAL_PACK]=1, [G.STATES.STANDARD_PACK]=1,[G.STATES.BUFFOON_PACK]=1,[G.STATES.PLANET_PACK]=1, [G.STATES.ROUND_EVAL]=1, [G.STATES.BLIND_SELECT]=1})[state]) or
|
||||
(self.config.type == 'hand' and state == G.STATES.SMODS_BOOSTER_OPENED) or
|
||||
(self.config.type == 'deck' and self ~= G.deck) or
|
||||
(self.config.type == 'shop' and self ~= G.shop_vouchers) then
|
||||
else
|
||||
if not self.children.area_uibox then
|
||||
local card_count = self ~= G.shop_vouchers and {n=G.UIT.R, config={align = self == G.jokers and 'cl' or self == G.hand and 'cm' or 'cr', padding = 0.03, no_fill = true}, nodes={
|
||||
{n=G.UIT.B, config={w = 0.1,h=0.1}},
|
||||
{n=G.UIT.T, config={ref_table = self.config, ref_value = 'card_count', scale = 0.3, colour = G.C.WHITE}},
|
||||
{n=G.UIT.T, config={text = '/', scale = 0.3, colour = G.C.WHITE}},
|
||||
{n=G.UIT.T, config={ref_table = self.config, ref_value = 'card_limit', scale = 0.3, colour = G.C.WHITE}},
|
||||
{n=G.UIT.B, config={w = 0.1,h=0.1}}
|
||||
}} or nil
|
||||
|
||||
self.children.area_uibox = UIBox{
|
||||
definition =
|
||||
{n=G.UIT.ROOT, config = {align = 'cm', colour = G.C.CLEAR}, nodes={
|
||||
{n=G.UIT.R, config={minw = self.T.w,minh = self.T.h,align = "cm", padding = 0.1, mid = true, r = 0.1, colour = self ~= G.shop_vouchers and {0,0,0,0.1} or nil, ref_table = self}, nodes={
|
||||
self == G.shop_vouchers and
|
||||
{n=G.UIT.C, config={align = "cm", paddin = 0.1, func = 'shop_voucher_empty', visible = false}, nodes={
|
||||
{n=G.UIT.R, config={align = "cm"}, nodes={
|
||||
{n=G.UIT.T, config={text = G.GAME.modifiers.cry_no_vouchers and (very_fair_quip[1] or '') or 'DEFEAT', scale = 0.6, colour = G.C.WHITE}}
|
||||
}},
|
||||
{n=G.UIT.R, config={align = "cm"}, nodes={
|
||||
{n=G.UIT.T, config={text = G.GAME.modifiers.cry_no_vouchers and (very_fair_quip[2] or '') or G.GAME.modifiers.cry_voucher_restock_antes and G.GAME.round_resets.ante % G.GAME.modifiers.cry_voucher_restock_antes == 0 and 'TWO BOSS BLINDS' or 'BOSS BLIND', scale = 0.4, colour = G.C.WHITE}}
|
||||
}},
|
||||
{n=G.UIT.R, config={align = "cm"}, nodes={
|
||||
{n=G.UIT.T, config={text = G.GAME.modifiers.cry_no_vouchers and (very_fair_quip[3] or '') or 'TO RESTOCK', scale = 0.4, colour = G.C.WHITE}}
|
||||
}},
|
||||
}} or nil,
|
||||
}},
|
||||
card_count
|
||||
}},
|
||||
config = { align = 'cm', offset = {x=0,y=0}, major = self, parent = self}
|
||||
}
|
||||
end
|
||||
self.children.area_uibox:draw()
|
||||
if self == G.jokers then
|
||||
Cartomancer.add_visibility_controls()
|
||||
end
|
||||
end
|
||||
|
||||
self:draw_boundingrect()
|
||||
add_to_drawhash(self)
|
||||
|
||||
self.ARGS.draw_layers = self.ARGS.draw_layers or self.config.draw_layers or {'shadow', 'card'}
|
||||
for k, v in ipairs(self.ARGS.draw_layers) do
|
||||
if self.config.type == 'deck' then
|
||||
for i = #self.cards, 1, -1 do
|
||||
if self.cards[i] ~= G.CONTROLLER.focused.target then
|
||||
if i == 1 or i%(self.config.thin_draw or 9) == 0 or i == #self.cards or math.abs(self.cards[i].VT.x - self.T.x) > 1 or math.abs(self.cards[i].VT.y - self.T.y) > 1 then
|
||||
if G.CONTROLLER.dragging.target ~= self.cards[i] then self.cards[i]:draw(v) end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if self.config.type == 'joker' or self.config.type == 'consumeable' or self.config.type == 'shop' or self.config.type == 'title_2' then
|
||||
for i = 1, #self.cards do
|
||||
if self.cards[i] ~= G.CONTROLLER.focused.target then
|
||||
if not self.cards[i].highlighted then
|
||||
if G.CONTROLLER.dragging.target ~= self.cards[i] then self.cards[i]:draw(v) end
|
||||
end
|
||||
end
|
||||
end
|
||||
for i = 1, #self.cards do
|
||||
if self.cards[i] ~= G.CONTROLLER.focused.target then
|
||||
if self.cards[i].highlighted then
|
||||
if G.CONTROLLER.dragging.target ~= self.cards[i] then self.cards[i]:draw(v) end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if self.config.type == 'discard' then
|
||||
for i = 1, #self.cards do
|
||||
if self.cards[i] ~= G.CONTROLLER.focused.target then
|
||||
if math.abs(self.cards[i].VT.x - self.T.x) > 1 then
|
||||
if G.CONTROLLER.dragging.target ~= self.cards[i] then self.cards[i]:draw(v) end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if self.config.type == 'hand' or self.config.type == 'play' or self.config.type == 'title' or self.config.type == 'voucher' then
|
||||
for i = 1, #self.cards do
|
||||
if self.cards[i] ~= G.CONTROLLER.focused.target or self == G.hand then
|
||||
if G.CONTROLLER.dragging.target ~= self.cards[i] then self.cards[i]:draw(v) end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if self == G.deck then
|
||||
if G.CONTROLLER.HID.controller and G.STATE == G.STATES.SELECTING_HAND and not self.children.peek_deck then
|
||||
self.children.peek_deck = UIBox{
|
||||
definition =
|
||||
{n=G.UIT.ROOT, config = {align = 'cm', padding = 0.1, r =0.1, colour = G.C.CLEAR}, nodes={
|
||||
{n=G.UIT.R, config={align = "cm", r =0.1, colour = adjust_alpha(G.C.L_BLACK, 0.5),func = 'set_button_pip', focus_args = {button = 'triggerleft', orientation = 'bm', scale = 0.6, type = 'none'}}, nodes={
|
||||
{n=G.UIT.R, config={align = "cm"}, nodes={
|
||||
{n=G.UIT.T, config={text = 'PEEK', scale = 0.48, colour = G.C.WHITE, shadow = true}}
|
||||
}},
|
||||
{n=G.UIT.R, config={align = "cm"}, nodes={
|
||||
{n=G.UIT.T, config={text = 'DECK', scale = 0.38, colour = G.C.WHITE, shadow = true}}
|
||||
}},
|
||||
}},
|
||||
}},
|
||||
config = { align = 'cl', offset = {x=-0.5,y=0.1}, major = self, parent = self}
|
||||
}
|
||||
self.children.peek_deck.states.collide.can = false
|
||||
elseif (not G.CONTROLLER.HID.controller or G.STATE ~= G.STATES.SELECTING_HAND) and self.children.peek_deck then
|
||||
self.children.peek_deck:remove()
|
||||
self.children.peek_deck = nil
|
||||
end
|
||||
if not self.children.view_deck then
|
||||
self.children.view_deck = UIBox{
|
||||
definition =
|
||||
{n=G.UIT.ROOT, config = {align = 'cm', padding = 0.1, r =0.1, colour = G.C.CLEAR}, nodes={
|
||||
{n=G.UIT.R, config={align = "cm", padding = 0.05, r =0.1, colour = adjust_alpha(G.C.BLACK, 0.5),func = 'set_button_pip', focus_args = {button = 'triggerright', orientation = 'bm', scale = 0.6}, button = 'deck_info'}, nodes={
|
||||
{n=G.UIT.R, config={align = "cm", maxw = 2}, nodes={
|
||||
{n=G.UIT.T, config={text = localize('k_view'), scale = 0.48, colour = G.C.WHITE, shadow = true}}
|
||||
}},
|
||||
{n=G.UIT.R, config={align = "cm", maxw = 2}, nodes={
|
||||
{n=G.UIT.T, config={text = localize('k_deck'), scale = 0.38, colour = G.C.WHITE, shadow = true}}
|
||||
}},
|
||||
}},
|
||||
}},
|
||||
config = { align = 'cm', offset = {x=0,y=0}, major = self.cards[1] or self, parent = self}
|
||||
}
|
||||
self.children.view_deck.states.collide.can = false
|
||||
end
|
||||
if G.deck_preview or self.states.collide.is or (G.buttons and G.buttons.states.collide.is and G.CONTROLLER.HID.controller) then self.children.view_deck:draw() end
|
||||
if self.children.peek_deck then self.children.peek_deck:draw() end
|
||||
end
|
||||
end
|
||||
|
||||
function CardArea:align_cards()
|
||||
if self.config.type == 'hand' then
|
||||
self.config.temp_limit = math.min(self.config.card_limit, #G.playing_cards)
|
||||
end
|
||||
if (self == G.hand or self == G.deck or self == G.discard or self == G.play) and G.view_deck and G.view_deck[1] and G.view_deck[1].cards then return end
|
||||
if self.config.type == 'deck' then
|
||||
local display_limit
|
||||
if not Cartomancer.SETTINGS.compact_deck_enabled then
|
||||
display_limit = 999999
|
||||
else
|
||||
display_limit = Cartomancer.SETTINGS.compact_deck_visible_cards
|
||||
end
|
||||
|
||||
local deck_height = (self.config.deck_height or 0.15)/52
|
||||
local total_cards = #self.cards <= display_limit and #self.cards or display_limit -- limit height
|
||||
local fixedX, fixedY, fixedR = nil, nil, nil
|
||||
|
||||
for k, card in ipairs(self.cards) do
|
||||
if card.facing == 'front' then card:flip() end
|
||||
|
||||
if not card.states.drag.is then
|
||||
if fixedX then
|
||||
card.T.x = fixedX
|
||||
card.T.y = fixedY
|
||||
card.T.r = fixedR -- rotation
|
||||
card.states.visible = false
|
||||
else
|
||||
card.T.x = self.T.x + 0.5*(self.T.w - card.T.w) + self.shadow_parrallax.x*deck_height*(total_cards/(self == G.deck and 1 or 2) - k) + 0.9*self.shuffle_amt*(1 - k*0.01)*(k%2 == 1 and 1 or -0)
|
||||
card.T.y = self.T.y + 0.5*(self.T.h - card.T.h) + self.shadow_parrallax.y*deck_height*(total_cards/(self == G.deck and 1 or 2) - k)
|
||||
card.T.r = 0 + 0.3*self.shuffle_amt*(1 + k*0.05)*(k%2 == 1 and 1 or -0)
|
||||
card.T.x = card.T.x + card.shadow_parrallax.x/30
|
||||
card.states.visible = true
|
||||
|
||||
if k >= display_limit then
|
||||
fixedX = card.T.x
|
||||
fixedY = card.T.y
|
||||
fixedR = card.T.r
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if self.config.type == 'discard' then
|
||||
for k, card in ipairs(self.cards) do
|
||||
if card.facing == 'front' then card:flip() end
|
||||
|
||||
if not card.states.drag.is then
|
||||
card.T.x = self.T.x + (self.T.w - card.T.w)*card.discard_pos.x
|
||||
card.T.y = self.T.y + (self.T.h - card.T.h)* card.discard_pos.y
|
||||
card.T.r = card.discard_pos.r
|
||||
end
|
||||
end
|
||||
end
|
||||
if self.config.type == 'hand' and (G.STATE == G.STATES.TAROT_PACK or G.STATE == G.STATES.SPECTRAL_PACK or G.STATE == G.STATES.PLANET_PACK or G.STATE == G.STATES.SMODS_BOOSTER_OPENED) then
|
||||
for k, card in ipairs(self.cards) do
|
||||
if not card.states.drag.is then
|
||||
card.T.r = 0.4*(-#self.cards/2 - 0.5 + k)/(#self.cards)+ (G.SETTINGS.reduced_motion and 0 or 1)*0.02*math.sin(2*G.TIMERS.REAL+card.T.x)
|
||||
local max_cards = math.max(#self.cards, self.config.temp_limit)
|
||||
card.T.x = self.T.x + (self.T.w-self.card_w)*((k-1)/math.max(max_cards-1, 1) - 0.5*(#self.cards-max_cards)/math.max(max_cards-1, 1)) + 0.5*(self.card_w - card.T.w)
|
||||
local highlight_height = G.HIGHLIGHT_H
|
||||
if not card.highlighted then highlight_height = 0 end
|
||||
card.T.y = G.hand.T.y - 1.8*card.T.h - highlight_height + (G.SETTINGS.reduced_motion and 0 or 1)*0.1*math.sin(0.666*G.TIMERS.REAL+card.T.x) + math.abs(1.3*(-#self.cards/2 + k-0.5)/(#self.cards))^2-0.3
|
||||
card.T.x = card.T.x + card.shadow_parrallax.x/30
|
||||
end
|
||||
end
|
||||
table.sort(self.cards, function (a, b) return a.T.x + a.T.w/2 - 100*(a.pinned and a.sort_id or 0) < b.T.x + b.T.w/2 - 100*(b.pinned and b.sort_id or 0) end)
|
||||
end
|
||||
if self.config.type == 'hand' and not (G.STATE == G.STATES.TAROT_PACK or G.STATE == G.STATES.SPECTRAL_PACK or G.STATE == G.STATES.PLANET_PACK or G.STATE == G.STATES.SMODS_BOOSTER_OPENED) then
|
||||
|
||||
for k, card in ipairs(self.cards) do
|
||||
if not card.states.drag.is then
|
||||
card.T.r = 0.2*(-#self.cards/2 - 0.5 + k)/(#self.cards)+ (G.SETTINGS.reduced_motion and 0 or 1)*0.02*math.sin(2*G.TIMERS.REAL+card.T.x)
|
||||
local max_cards = math.max(#self.cards, self.config.temp_limit)
|
||||
card.T.x = self.T.x + (self.T.w-self.card_w)*((k-1)/math.max(max_cards-1, 1) - 0.5*(#self.cards-max_cards)/math.max(max_cards-1, 1)) + 0.5*(self.card_w - card.T.w)
|
||||
|
||||
local highlight_height = G.HIGHLIGHT_H
|
||||
if not card.highlighted then highlight_height = 0 end
|
||||
card.T.y = self.T.y + self.T.h/2 - card.T.h/2 - highlight_height + (G.SETTINGS.reduced_motion and 0 or 1)*0.03*math.sin(0.666*G.TIMERS.REAL+card.T.x) + math.abs(0.5*(-#self.cards/2 + k-0.5)/(#self.cards))-0.2
|
||||
card.T.x = card.T.x + card.shadow_parrallax.x/30
|
||||
end
|
||||
end
|
||||
table.sort(self.cards, function (a, b) return a.T.x + a.T.w/2 - 100*(a.pinned and a.sort_id or 0) < b.T.x + b.T.w/2 - 100*(b.pinned and b.sort_id or 0) end)
|
||||
end
|
||||
if self.config.type == 'title' or (self.config.type == 'voucher' and #self.cards == 1) then
|
||||
for k, card in ipairs(self.cards) do
|
||||
if not card.states.drag.is then
|
||||
card.T.r = 0.2*(-#self.cards/2 - 0.5 + k)/(#self.cards)+ (G.SETTINGS.reduced_motion and 0 or 1)*0.02*math.sin(2*G.TIMERS.REAL+card.T.x)
|
||||
local max_cards = math.max(#self.cards, self.config.temp_limit)
|
||||
card.T.x = self.T.x + (self.T.w-self.card_w)*((k-1)/math.max(max_cards-1, 1) - 0.5*(#self.cards-max_cards)/math.max(max_cards-1, 1)) + 0.5*(self.card_w - card.T.w)
|
||||
local highlight_height = G.HIGHLIGHT_H
|
||||
if not card.highlighted then highlight_height = 0 end
|
||||
card.T.y = self.T.y + self.T.h/2 - card.T.h/2 - highlight_height + (G.SETTINGS.reduced_motion and 0 or 1)*0.03*math.sin(0.666*G.TIMERS.REAL+card.T.x) + math.abs(0.5*(-#self.cards/2 + k-0.5)/(#self.cards))-(#self.cards>1 and 0.2 or 0)
|
||||
card.T.x = card.T.x + card.shadow_parrallax.x/30
|
||||
end
|
||||
end
|
||||
table.sort(self.cards, function (a, b) return a.T.x + a.T.w/2 - 100*(a.pinned and a.sort_id or 0) < b.T.x + b.T.w/2 - 100*(b.pinned and b.sort_id or 0) end)
|
||||
end
|
||||
if self.config.type == 'voucher' and #self.cards > 1 then
|
||||
local self_w = math.max(self.T.w, 3.2)
|
||||
for k, card in ipairs(self.cards) do
|
||||
if not card.states.drag.is then
|
||||
card.T.r = 0.2*(-#self.cards/2 - 0.5 + k)/(#self.cards)+ (G.SETTINGS.reduced_motion and 0 or 1)*0.02*math.sin(2*G.TIMERS.REAL+card.T.x+card.T.y) + (k%2 == 0 and 1 or -1)*0.08
|
||||
local max_cards = math.max(#self.cards, self.config.temp_limit)
|
||||
card.T.x = self.T.x + (self_w-self.card_w)*((k-1)/math.max(max_cards-1, 1) - 0.5*(#self.cards-max_cards)/math.max(max_cards-1, 1)) + 0.5*(self.card_w - card.T.w) + (k%2 == 1 and 1 or -1)*0.27 + (self.T.w-self_w)/2
|
||||
local highlight_height = G.HIGHLIGHT_H
|
||||
if not card.highlighted then highlight_height = 0 end
|
||||
card.T.y = self.T.y + self.T.h/2 - card.T.h/2 - highlight_height + (G.SETTINGS.reduced_motion and 0 or 1)*0.03*math.sin(0.666*G.TIMERS.REAL+card.T.x) + math.abs(0.5*(-#self.cards/2 + k-0.5)/(#self.cards))-(#self.cards>1 and 0.2 or 0)
|
||||
card.T.x = card.T.x + card.shadow_parrallax.x/30
|
||||
end
|
||||
end
|
||||
table.sort(self.cards, function (a, b) return a.ability.order < b.ability.order end)
|
||||
end
|
||||
if self.config.type == 'play' or self.config.type == 'shop' then
|
||||
for k, card in ipairs(self.cards) do
|
||||
if not card.states.drag.is then
|
||||
card.T.r = 0
|
||||
local max_cards = math.max(#self.cards, self.config.temp_limit)
|
||||
card.T.x = self.T.x + (self.T.w-self.card_w)*((k-1)/math.max(max_cards-1, 1) - 0.5*(#self.cards-max_cards)/math.max(max_cards-1, 1)) + 0.5*(self.card_w - card.T.w) + (self.config.card_limit == 1 and 0.5*(self.T.w - card.T.w) or 0)
|
||||
local highlight_height = G.HIGHLIGHT_H
|
||||
if not card.highlighted then highlight_height = 0 end
|
||||
card.T.y = self.T.y + self.T.h/2 - card.T.h/2 - highlight_height
|
||||
card.T.x = card.T.x + card.shadow_parrallax.x/30
|
||||
end
|
||||
end
|
||||
table.sort(self.cards, function (a, b) return a.T.x + a.T.w/2 - 100*(a.pinned and a.sort_id or 0) < b.T.x + b.T.w/2 - 100*(b.pinned and b.sort_id or 0) end)
|
||||
end
|
||||
if self == G.jokers and G.jokers.cart_jokers_expanded then
|
||||
local align_cards = Cartomancer.expand_G_jokers()
|
||||
|
||||
-- This should work fine without cryptid. But because cryptid's patch is priority=0, it has to be this way
|
||||
if not G.GAME.modifiers.cry_conveyor then
|
||||
table.sort(self.cards, function (a, b) return a.T.x + a.T.w/2 - 100*(a.pinned and a.sort_id or 0) < b.T.x + b.T.w/2 - 100*(b.pinned and b.sort_id or 0) end)
|
||||
end
|
||||
|
||||
if align_cards then
|
||||
G.jokers:hard_set_cards()
|
||||
end
|
||||
elseif self.config.type == 'joker' or self.config.type == 'title_2' then
|
||||
for k, card in ipairs(self.cards) do
|
||||
if not card.states.drag.is then
|
||||
card.T.r = 0.1*(-#self.cards/2 - 0.5 + k)/(#self.cards)+ (G.SETTINGS.reduced_motion and 0 or 1)*0.02*math.sin(2*G.TIMERS.REAL+card.T.x)
|
||||
local max_cards = math.max(#self.cards, self.config.temp_limit)
|
||||
card.T.x = self.T.x + (self.T.w-self.card_w)*((k-1)/math.max(max_cards-1, 1) - 0.5*(#self.cards-max_cards)/math.max(max_cards-1, 1)) + 0.5*(self.card_w - card.T.w)
|
||||
if #self.cards > 2 or (#self.cards > 1 and self == G.consumeables) or (#self.cards > 1 and self.config.spread) then
|
||||
card.T.x = self.T.x + (self.T.w-self.card_w)*((k-1)/(#self.cards-1)) + 0.5*(self.card_w - card.T.w)
|
||||
elseif #self.cards > 1 and self ~= G.consumeables then
|
||||
card.T.x = self.T.x + (self.T.w-self.card_w)*((k - 0.5)/(#self.cards)) + 0.5*(self.card_w - card.T.w)
|
||||
else
|
||||
card.T.x = self.T.x + self.T.w/2 - self.card_w/2 + 0.5*(self.card_w - card.T.w)
|
||||
end
|
||||
local highlight_height = G.HIGHLIGHT_H/2
|
||||
if not card.highlighted then highlight_height = 0 end
|
||||
card.T.y = self.T.y + self.T.h/2 - card.T.h/2 - highlight_height+ (G.SETTINGS.reduced_motion and 0 or 1)*0.03*math.sin(0.666*G.TIMERS.REAL+card.T.x)
|
||||
card.T.x = card.T.x + card.shadow_parrallax.x/30
|
||||
end
|
||||
end
|
||||
table.sort(self.cards, function (a, b) return a.T.x + a.T.w/2 - 100*((a.pinned and not a.ignore_pinned) and a.sort_id or 0) < b.T.x + b.T.w/2 - 100*((b.pinned and not b.ignore_pinned) and b.sort_id or 0) end)
|
||||
end
|
||||
if self.config.type == 'consumeable'then
|
||||
for k, card in ipairs(self.cards) do
|
||||
if not card.states.drag.is then
|
||||
if #self.cards > 1 then
|
||||
card.T.x = self.T.x + (self.T.w-self.card_w)*((k-1)/(#self.cards-1)) + 0.5*(self.card_w - card.T.w)
|
||||
else
|
||||
card.T.x = self.T.x + self.T.w/2 - self.card_w/2 + 0.5*(self.card_w - card.T.w)
|
||||
end
|
||||
local highlight_height = G.HIGHLIGHT_H
|
||||
if not card.highlighted then highlight_height = 0 end
|
||||
card.T.y = self.T.y + self.T.h/2 - card.T.h/2 - highlight_height + (not card.highlighted and (G.SETTINGS.reduced_motion and 0 or 1)*0.05*math.sin(2*1.666*G.TIMERS.REAL+card.T.x) or 0)
|
||||
card.T.x = card.T.x + card.shadow_parrallax.x/30
|
||||
end
|
||||
end
|
||||
table.sort(self.cards, function (a, b) return a.T.x + a.T.w/2 - 100*(a.pinned and a.sort_id or 0) < b.T.x + b.T.w/2 - 100*(b.pinned and b.sort_id or 0) end)
|
||||
end
|
||||
for k, card in ipairs(self.cards) do
|
||||
card.rank = k
|
||||
end
|
||||
if self.children.view_deck then
|
||||
self.children.view_deck:set_role{major = self.cards[1] or self}
|
||||
end
|
||||
end
|
||||
|
||||
function CardArea:hard_set_T(X, Y, W, H)
|
||||
local x = (X or self.T.x)
|
||||
local y = (Y or self.T.y)
|
||||
local w = (W or self.T.w)
|
||||
local h = (H or self.T.h)
|
||||
Moveable.hard_set_T(self,x, y, w, h)
|
||||
self:calculate_parrallax()
|
||||
self:align_cards()
|
||||
self:hard_set_cards()
|
||||
end
|
||||
|
||||
function CardArea:hard_set_cards()
|
||||
for k, card in pairs(self.cards) do
|
||||
card:hard_set_T()
|
||||
card:calculate_parrallax()
|
||||
end
|
||||
end
|
||||
|
||||
function CardArea:shuffle(_seed)
|
||||
pseudoshuffle(self.cards, pseudoseed(_seed or 'shuffle'))
|
||||
self:set_ranks()
|
||||
end
|
||||
|
||||
function CardArea:sort(method)
|
||||
self.config.sort = method or self.config.sort
|
||||
if self.config.sort == 'desc' then
|
||||
table.sort(self.cards, function (a, b) return a:get_nominal() > b:get_nominal() end )
|
||||
elseif self.config.sort == 'asc' then
|
||||
table.sort(self.cards, function (a, b) return a:get_nominal() < b:get_nominal() end )
|
||||
elseif self.config.sort == 'suit desc' then
|
||||
table.sort(self.cards, function (a, b) return a:get_nominal('suit') > b:get_nominal('suit') end )
|
||||
elseif self.config.sort == 'suit asc' then
|
||||
table.sort(self.cards, function (a, b) return a:get_nominal('suit') < b:get_nominal('suit') end )
|
||||
elseif self.config.sort == 'order' then
|
||||
table.sort(self.cards, function (a, b) return (a.config.card.order or a.config.center.order) < (b.config.card.order or b.config.center.order) end )
|
||||
end
|
||||
end
|
||||
|
||||
function CardArea:draw_card_from(area, stay_flipped, discarded_only)
|
||||
if area:is(CardArea) then
|
||||
if #self.cards < self.config.card_limit or self == G.deck or self == G.hand then
|
||||
local card = area:remove_card(nil, discarded_only)
|
||||
if card then
|
||||
if area == G.discard then
|
||||
card.T.r = 0
|
||||
end
|
||||
if self == G.hand and not card.states.visible then
|
||||
card.states.visible = true
|
||||
end
|
||||
local stay_flipped = G.GAME and G.GAME.blind and G.GAME.blind:stay_flipped(self, card)
|
||||
if (self == G.hand) and G.GAME.modifiers.flipped_cards then
|
||||
if pseudorandom(pseudoseed('flipped_card')) < 1/G.GAME.modifiers.flipped_cards then
|
||||
stay_flipped = true
|
||||
end
|
||||
end
|
||||
self:emplace(card, nil, stay_flipped)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function CardArea:click()
|
||||
if self == G.deck then
|
||||
G.FUNCS.deck_info()
|
||||
end
|
||||
end
|
||||
|
||||
function CardArea:save()
|
||||
if not self.cards then return end
|
||||
local cardAreaTable = {
|
||||
cards = {},
|
||||
config = self.config,
|
||||
}
|
||||
for i = 1, #self.cards do
|
||||
cardAreaTable.cards[#cardAreaTable.cards + 1] = self.cards[i]:save()
|
||||
end
|
||||
|
||||
return cardAreaTable
|
||||
end
|
||||
|
||||
function CardArea:load(cardAreaTable)
|
||||
|
||||
if self.cards then remove_all(self.cards) end
|
||||
self.cards = {}
|
||||
if self.children then remove_all(self.children) end
|
||||
self.children = {}
|
||||
|
||||
self.config = cardAreaTable.config
|
||||
|
||||
for i = 1, #cardAreaTable.cards do
|
||||
loading = true
|
||||
local card = Card(0, 0, G.CARD_W, G.CARD_H, G.P_CENTERS.j_joker, G.P_CENTERS.c_base)
|
||||
loading = nil
|
||||
card:load(cardAreaTable.cards[i])
|
||||
self.cards[#self.cards + 1] = card
|
||||
if card.highlighted then
|
||||
self.highlighted[#self.highlighted + 1] = card
|
||||
end
|
||||
card:set_card_area(self)
|
||||
end
|
||||
self:set_ranks()
|
||||
self:align_cards()
|
||||
self:hard_set_cards()
|
||||
end
|
||||
|
||||
function CardArea:remove()
|
||||
if self.cards then remove_all(self.cards) end
|
||||
self.cards = nil
|
||||
if self.children then remove_all(self.children) end
|
||||
self.children = nil
|
||||
for k, v in pairs(G.I.CARDAREA) do
|
||||
if v == self then
|
||||
table.remove(G.I.CARDAREA, k)
|
||||
end
|
||||
end
|
||||
Moveable.remove(self)
|
||||
end
|
|
@ -1,109 +0,0 @@
|
|||
LOVELY_INTEGRITY = '8f16206d263b8b20d4f441ae0cdc8450eef3f2bd3b801abb44802f6b1578b809'
|
||||
|
||||
--Class
|
||||
AnimatedSprite = Sprite:extend()
|
||||
|
||||
--Class Methods
|
||||
function AnimatedSprite:init(X, Y, W, H, new_sprite_atlas, sprite_pos)
|
||||
Sprite.init(self,X, Y, W, H, new_sprite_atlas, sprite_pos)
|
||||
self.offset = {x = 0, y = 0}
|
||||
|
||||
table.insert(G.ANIMATIONS, self)
|
||||
if getmetatable(self) == AnimatedSprite then
|
||||
table.insert(G.I.SPRITE, self)
|
||||
end
|
||||
end
|
||||
|
||||
function AnimatedSprite:rescale()
|
||||
self.scale_mag = math.min(self.scale.x/self.T.w,self.scale.y/self.T.h)
|
||||
end
|
||||
|
||||
function AnimatedSprite:reset()
|
||||
self.atlas = G.ANIMATION_ATLAS[self.atlas.name]
|
||||
self:set_sprite_pos({x = self.animation.x, y = self.animation.y})
|
||||
end
|
||||
|
||||
function AnimatedSprite:set_sprite_pos(sprite_pos)
|
||||
self.animation = {
|
||||
x= sprite_pos and sprite_pos.x or 0,
|
||||
y=sprite_pos and sprite_pos.y or 0,
|
||||
frames=self.atlas.frames,current=0,
|
||||
w=self.scale.x, h=self.scale.y}
|
||||
|
||||
self.frame_offset = 0
|
||||
|
||||
self.current_animation = {
|
||||
current = 0,
|
||||
frames = self.animation.frames,
|
||||
w = self.animation.w,
|
||||
h = self.animation.h}
|
||||
|
||||
self.image_dims = self.image_dims or {}
|
||||
self.image_dims[1], self.image_dims[2] = self.atlas.image:getDimensions()
|
||||
|
||||
self.sprite = love.graphics.newQuad(
|
||||
0,
|
||||
self.animation.h*self.animation.y,
|
||||
self.animation.w,
|
||||
self.animation.h,
|
||||
self.image_dims[1], self.image_dims[2])
|
||||
self.offset_seconds = G.TIMERS.REAL
|
||||
end
|
||||
|
||||
function AnimatedSprite:get_pos_pixel()
|
||||
self.RETS.get_pos_pixel = self.RETS.get_pos_pixel or {}
|
||||
self.RETS.get_pos_pixel[1] = self.current_animation.current
|
||||
self.RETS.get_pos_pixel[2] = self.animation.y
|
||||
self.RETS.get_pos_pixel[3] = self.animation.w
|
||||
self.RETS.get_pos_pixel[4] = self.animation.h
|
||||
return self.RETS.get_pos_pixel
|
||||
end
|
||||
|
||||
function AnimatedSprite:draw_self()
|
||||
if not self.states.visible then return end
|
||||
|
||||
prep_draw(self, 1)
|
||||
love.graphics.scale(1/self.scale_mag)
|
||||
love.graphics.setColor(G.C.WHITE)
|
||||
love.graphics.draw(
|
||||
self.atlas.image,
|
||||
self.sprite,
|
||||
0 ,0,
|
||||
0,
|
||||
self.VT.w/(self.T.w),
|
||||
self.VT.h/(self.T.h)
|
||||
)
|
||||
love.graphics.pop()
|
||||
end
|
||||
|
||||
function AnimatedSprite:animate()
|
||||
local new_frame = math.floor(G.ANIMATION_FPS*(G.TIMERS.REAL - self.offset_seconds))%self.current_animation.frames
|
||||
if new_frame ~= self.current_animation.current then
|
||||
self.current_animation.current = new_frame
|
||||
self.frame_offset = math.floor(self.animation.w*(self.current_animation.current))
|
||||
self.sprite:setViewport(
|
||||
self.frame_offset,
|
||||
self.animation.h*self.animation.y,
|
||||
self.animation.w,
|
||||
self.animation.h)
|
||||
end
|
||||
if self.float then
|
||||
self.T.r = 0.02*math.sin(2*G.TIMERS.REAL+self.T.x)
|
||||
self.offset.y = -(1+0.3*math.sin(0.666*G.TIMERS.REAL+self.T.y))*self.shadow_parrallax.y
|
||||
self.offset.x = -(0.7+0.2*math.sin(0.666*G.TIMERS.REAL+self.T.x))*self.shadow_parrallax.x
|
||||
end
|
||||
end
|
||||
|
||||
function AnimatedSprite:remove()
|
||||
for k, v in pairs(G.ANIMATIONS) do
|
||||
if v == self then
|
||||
table.remove(G.ANIMATIONS, k)
|
||||
end
|
||||
end
|
||||
for k, v in pairs(G.I.SPRITE) do
|
||||
if v == self then
|
||||
table.remove(G.I.SPRITE, k)
|
||||
end
|
||||
end
|
||||
Sprite.remove(self)
|
||||
end
|
File diff suppressed because it is too large
Load diff
|
@ -1,520 +0,0 @@
|
|||
LOVELY_INTEGRITY = '2774a24114332371bc4208f854d32c6f93786326d6810fc4139b615d177277e3'
|
||||
|
||||
---@class Moveable: Node
|
||||
Moveable = Node:extend()
|
||||
|
||||
--Moveable represents any game object that has the ability to move about the gamespace.\
|
||||
--All Moveables have a T (transform) that describes their desired transform in game units, as\
|
||||
--well as a VT (Visible Transform) that eases to T over time. This allows for simplified movement where\
|
||||
--we only need to set T.x, T.y, etc. to their final position and the engine will ensure the Moveable\
|
||||
--VT eases to that final location, regargless of any events or timing.
|
||||
--
|
||||
---@param args {T: table, container: Node}
|
||||
--**T** The transform ititializer, with keys of x|1, y|2, w|3, h|4, r|5\
|
||||
--**container** optional container for this Node, defaults to G.ROOM
|
||||
function Moveable:init(X,Y,W,H)
|
||||
local args = (type(X) == 'table') and X or {T ={X or 0,Y or 0,W or 0,H or 0}}
|
||||
Node.init(self, args)
|
||||
|
||||
--The Visible transform is initally set to the same values as the transform T.
|
||||
--Note that the VT has an extra 'scale' factor, this is used to manipulate the center-adjusted
|
||||
--scale of any objects that need to be drawn larger or smaller
|
||||
self.VT = {
|
||||
x = self.T.x,
|
||||
y = self.T.y,
|
||||
w = self.T.w,
|
||||
h = self.T.h,
|
||||
r = self.T.r,
|
||||
scale = self.T.scale
|
||||
}
|
||||
|
||||
--To determine location of VT, we need to keep track of the velocity of VT as it approaches T for the next frame
|
||||
self.velocity = {x = 0, y = 0, r = 0, scale = 0, mag = 0}
|
||||
|
||||
--For more robust drawing, attaching, movement and fewer redundant movement calculations, Moveables each have a 'role'
|
||||
--that describes a heirarchy of move() calls. Any Moveables with 'Major' role type behave normally, essentially recalculating their
|
||||
--VT every frame to ensure smooth movement. Moveables can be set to 'Minor' role and attached to some 'Major' moveable
|
||||
--to weld the Minor moveable to the Major moveable. This makes the dependent moveable set their T and VT to be equal to
|
||||
--the corresponding 'Major' T and VT, plus some defined offset.
|
||||
--For finer control over what parts of T and VT are inherited, xy_bond, wh_bond, and r_bond can be set to one of
|
||||
--'Strong' or 'Weak'. Strong simply copies the values, Weak allows the 'Minor' moveable to calculate their own.
|
||||
self.role = {
|
||||
role_type = 'Major', --Major dictates movement, Minor is welded to some major
|
||||
offset = {x = 0, y = 0}, --Offset from Minor to Major
|
||||
major = nil,
|
||||
draw_major = self,
|
||||
xy_bond = 'Strong',
|
||||
wh_bond = 'Strong',
|
||||
r_bond = 'Strong',
|
||||
scale_bond = 'Strong'
|
||||
}
|
||||
|
||||
self.alignment = {
|
||||
type = 'a',
|
||||
offset = {x = 0, y = 0},
|
||||
prev_type = '',
|
||||
prev_offset = {x = 0, y = 0},
|
||||
}
|
||||
|
||||
--the pinch table is used to modify the VT.w and VT.h compared to T.w and T.h. If either x or y pinch is
|
||||
--set to true, the VT width and or height will ease to 0. If pinch is false, they ease to T.w or T.h
|
||||
self.pinch = {x = false, y = false}
|
||||
|
||||
--Keep track of the last time this Moveable was moved via :move(dt). When it is successfully moved, set to equal
|
||||
--the current G.TIMERS.REAL, and if it is called again this frame, doesn't recalculate move(dt)
|
||||
self.last_moved = -1
|
||||
self.last_aligned = -1
|
||||
|
||||
self.static_rotation = false
|
||||
|
||||
self.offset = {x=0, y=0}
|
||||
self.Mid = self
|
||||
|
||||
self.shadow_parrallax = {x = 0, y = -1.5}
|
||||
self.layered_parallax = {x = 0, y = 0}
|
||||
self.shadow_height = 0.2
|
||||
|
||||
self:calculate_parrallax()
|
||||
|
||||
table.insert(G.MOVEABLES, self)
|
||||
if getmetatable(self) == Moveable then
|
||||
table.insert(G.I.MOVEABLE, self)
|
||||
end
|
||||
end
|
||||
function Moveable:draw()
|
||||
Node.draw(self)
|
||||
self:draw_boundingrect()
|
||||
end
|
||||
|
||||
--Sets the alignment of moveable using roles
|
||||
--
|
||||
---@param args {major: Moveable, bond: string, offset: table, type: string}
|
||||
--**major** The moveable this moveable will attach to\
|
||||
--**bond** The bond type, either 'Strong' or 'Weak'. Strong instantly adjusts VT, Weak manually calculates VT changes\
|
||||
--**offset** {x , y} offset from the alignment\
|
||||
--**type** the alignment type. Vertical options: c - center, t - top, b - bottom. Horizontal options: l - left, m - middle, r - right. i for inner
|
||||
function Moveable:set_alignment(args)
|
||||
args = args or {}
|
||||
if args.major then
|
||||
self:set_role({
|
||||
role_type = 'Minor',
|
||||
major = args.major,
|
||||
xy_bond = args.bond or args.xy_bond or 'Weak',
|
||||
wh_bond = args.wh_bond or self.role.wh_bond,
|
||||
r_bond = args.r_bond or self.role.r_bond,
|
||||
scale_bond = args.scale_bond or self.role.scale_bond,
|
||||
})
|
||||
end
|
||||
self.alignment.type = args.type or self.alignment.type
|
||||
if args.offset and (type(args.offset)=='table' and not (args.offset.y and args.offset.x)) or type(args.offset) ~= 'table' then
|
||||
args.offset = nil
|
||||
end
|
||||
self.alignment.offset = args.offset or self.alignment.offset
|
||||
self.alignment.lr_clamp = args.lr_clamp
|
||||
end
|
||||
|
||||
function Moveable:align_to_major()
|
||||
if self.alignment.type ~= self.alignment.prev_type then
|
||||
self.alignment.type_list = {
|
||||
a = self.alignment.type == 'a',
|
||||
m = string.find(self.alignment.type, "m"),
|
||||
c = string.find(self.alignment.type, "c"),
|
||||
b = string.find(self.alignment.type, "b"),
|
||||
t = string.find(self.alignment.type, "t"),
|
||||
l = string.find(self.alignment.type, "l"),
|
||||
r = string.find(self.alignment.type, "r"),
|
||||
i = string.find(self.alignment.type, "i"),
|
||||
}
|
||||
end
|
||||
|
||||
if not self.alignment.type_list then return end
|
||||
self.NEW_ALIGNMENT = true
|
||||
|
||||
if self.alignment.type ~= self.alignment.prev_type then
|
||||
self.alignment.prev_type = self.alignment.type
|
||||
end
|
||||
|
||||
if self.alignment.type_list.a or not self.role.major then return end
|
||||
|
||||
if self.alignment.type_list.m then
|
||||
self.role.offset.x = 0.5*self.role.major.T.w - (self.Mid.T.w)/2 + self.alignment.offset.x - self.Mid.T.x + self.T.x
|
||||
end
|
||||
|
||||
if self.alignment.type_list.c then
|
||||
self.role.offset.y = 0.5*self.role.major.T.h - (self.Mid.T.h)/2 + self.alignment.offset.y - self.Mid.T.y + self.T.y
|
||||
end
|
||||
|
||||
if self.alignment.type_list.b then
|
||||
if self.alignment.type_list.i then
|
||||
self.role.offset.y = self.alignment.offset.y + self.role.major.T.h - self.T.h
|
||||
else
|
||||
self.role.offset.y = self.alignment.offset.y + self.role.major.T.h
|
||||
end
|
||||
end
|
||||
|
||||
if self.alignment.type_list.r then
|
||||
if self.alignment.type_list.i then
|
||||
self.role.offset.x = self.alignment.offset.x + self.role.major.T.w - self.T.w
|
||||
else
|
||||
self.role.offset.x = self.alignment.offset.x + self.role.major.T.w
|
||||
end
|
||||
end
|
||||
|
||||
if self.alignment.type_list.t then
|
||||
if self.alignment.type_list.i then
|
||||
self.role.offset.y = self.alignment.offset.y
|
||||
else
|
||||
self.role.offset.y = self.alignment.offset.y - self.T.h
|
||||
end
|
||||
end
|
||||
|
||||
if self.alignment.type_list.l then
|
||||
if self.alignment.type_list.i then
|
||||
self.role.offset.x = self.alignment.offset.x
|
||||
else
|
||||
self.role.offset.x = self.alignment.offset.x - self.T.w
|
||||
end
|
||||
end
|
||||
|
||||
self.role.offset.x = self.role.offset.x or 0
|
||||
self.role.offset.y = self.role.offset.y or 0
|
||||
|
||||
self.T.x = self.role.major.T.x + self.role.offset.x
|
||||
self.T.y = self.role.major.T.y + self.role.offset.y
|
||||
|
||||
self.alignment.prev_offset = self.alignment.prev_offset or {}
|
||||
self.alignment.prev_offset.x, self.alignment.prev_offset.y = self.alignment.offset.x, self.alignment.offset.y
|
||||
end
|
||||
|
||||
function Moveable:hard_set_T(X, Y, W, H)
|
||||
self.T.x = X
|
||||
self.T.y = Y
|
||||
self.T.w = W
|
||||
self.T.h = H
|
||||
|
||||
self.velocity.x = 0
|
||||
self.velocity.y = 0
|
||||
self.velocity.r = 0
|
||||
self.velocity.scale = 0
|
||||
|
||||
self.VT.x = X
|
||||
self.VT.y = Y
|
||||
self.VT.w = W
|
||||
self.VT.h = H
|
||||
self.VT.r = self.T.r
|
||||
self.VT.scale = self.T.scale
|
||||
self:calculate_parrallax()
|
||||
end
|
||||
|
||||
function Moveable:hard_set_VT()
|
||||
self.VT.x = self.T.x
|
||||
self.VT.y = self.T.y
|
||||
self.VT.w = self.T.w
|
||||
self.VT.h = self.T.h
|
||||
end
|
||||
|
||||
function Moveable:drag(offset)
|
||||
if self.states.drag.can or offset then
|
||||
self.ARGS.drag_cursor_trans = self.ARGS.drag_cursor_trans or {}
|
||||
self.ARGS.drag_translation = self.ARGS.drag_translation or {}
|
||||
local _p = self.ARGS.drag_cursor_trans
|
||||
local _t = self.ARGS.drag_translation
|
||||
_p.x = G.CONTROLLER.cursor_position.x/(G.TILESCALE*G.TILESIZE)
|
||||
_p.y = G.CONTROLLER.cursor_position.y/(G.TILESCALE*G.TILESIZE)
|
||||
|
||||
_t.x, _t.y = -self.container.T.w/2, -self.container.T.h/2
|
||||
point_translate(_p, _t)
|
||||
|
||||
point_rotate(_p, self.container.T.r)
|
||||
|
||||
_t.x, _t.y = self.container.T.w/2-self.container.T.x, self.container.T.h/2-self.container.T.y
|
||||
point_translate(_p, _t)
|
||||
|
||||
if not offset then
|
||||
offset = self.click_offset
|
||||
end
|
||||
|
||||
self.T.x = _p.x - offset.x
|
||||
self.T.y = _p.y - offset.y
|
||||
self.NEW_ALIGNMENT = true
|
||||
for k, v in pairs(self.children) do
|
||||
v:drag(offset)
|
||||
end
|
||||
end
|
||||
if self.states.drag.can then
|
||||
Node.drag(self)
|
||||
end
|
||||
end
|
||||
|
||||
function Moveable:juice_up(amount, rot_amt)
|
||||
if G.SETTINGS.reduced_motion then return end
|
||||
local amount = amount or 0.4
|
||||
|
||||
local end_time = G.TIMERS.REAL + 0.4
|
||||
local start_time = G.TIMERS.REAL
|
||||
self.juice = {
|
||||
scale = 0,
|
||||
scale_amt = amount,
|
||||
r = 0,
|
||||
r_amt = ((rot_amt or pseudorandom_element({0.6*amount, -0.6*amount})) or 0),
|
||||
start_time = start_time,
|
||||
end_time = end_time
|
||||
}
|
||||
self.VT.scale = 1-0.6*amount
|
||||
end
|
||||
|
||||
function Moveable:move_juice(dt)
|
||||
if self.juice and not self.juice.handled_elsewhere then
|
||||
if self.juice.end_time < G.TIMERS.REAL then
|
||||
self.juice = nil
|
||||
else
|
||||
self.juice.scale = self.juice.scale_amt*math.sin(50.8*(G.TIMERS.REAL-self.juice.start_time))*math.max(0, ((self.juice.end_time - G.TIMERS.REAL)/(self.juice.end_time - self.juice.start_time))^3)
|
||||
self.juice.r = self.juice.r_amt*math.sin(40.8*(G.TIMERS.REAL-self.juice.start_time))*math.max(0, ((self.juice.end_time - G.TIMERS.REAL)/(self.juice.end_time - self.juice.start_time))^2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Moveable:move(dt)
|
||||
if self.FRAME.MOVE >= G.FRAMES.MOVE then return end
|
||||
self.FRAME.OLD_MAJOR = self.FRAME.MAJOR
|
||||
self.FRAME.MAJOR = nil
|
||||
self.FRAME.MOVE = G.FRAMES.MOVE
|
||||
if not self.created_on_pause and G.SETTINGS.paused then return end
|
||||
|
||||
--WHY ON EARTH DOES THIS LINE MAKE IT RUN 2X AS FAST???
|
||||
-------------------------------------------------------
|
||||
--local timestart = love.timer.getTime()
|
||||
-------------------------------------------------------
|
||||
|
||||
self:align_to_major()
|
||||
|
||||
self.CALCING = nil
|
||||
if self.role.role_type == 'Glued' then
|
||||
if self.role.major then self:glue_to_major(self.role.major) end
|
||||
elseif self.role.role_type == 'Minor' and self.role.major then
|
||||
if self.role.major.FRAME.MOVE < G.FRAMES.MOVE then self.role.major:move(dt) end
|
||||
self.STATIONARY = self.role.major.STATIONARY
|
||||
if (not self.STATIONARY) or self.NEW_ALIGNMENT or
|
||||
self.config.refresh_movement or
|
||||
self.juice or
|
||||
self.role.xy_bond == 'Weak' or
|
||||
self.role.r_bond == 'Weak' then
|
||||
self.CALCING = true
|
||||
self:move_with_major(dt)
|
||||
end
|
||||
elseif self.role.role_type == 'Major' then
|
||||
self.STATIONARY = true
|
||||
self:move_juice(dt)
|
||||
self:move_xy(dt)
|
||||
self:move_r(dt, self.velocity)
|
||||
self:move_scale(dt)
|
||||
self:move_wh(dt)
|
||||
self:calculate_parrallax()
|
||||
end
|
||||
if self.alignment and self.alignment.lr_clamp then
|
||||
self:lr_clamp()
|
||||
end
|
||||
|
||||
self.NEW_ALIGNMENT = false
|
||||
end
|
||||
|
||||
function Moveable:lr_clamp()
|
||||
if self.T.x < 0 then self.T.x = 0 end
|
||||
if self.VT.x < 0 then self.VT.x = 0 end
|
||||
if (self.T.x + self.T.w) > G.ROOM.T.w then self.T.x = G.ROOM.T.w - self.T.w end
|
||||
if (self.VT.x + self.VT.w) > G.ROOM.T.w then self.VT.x = G.ROOM.T.w - self.VT.w end
|
||||
end
|
||||
|
||||
function Moveable:glue_to_major(major_tab)
|
||||
self.T = major_tab.T
|
||||
|
||||
self.VT.x = major_tab.VT.x + (0.5*(1 - major_tab.VT.w/(major_tab.T.w))*self.T.w)
|
||||
self.VT.y = major_tab.VT.y
|
||||
self.VT.w = major_tab.VT.w
|
||||
self.VT.h = major_tab.VT.h
|
||||
self.VT.r = major_tab.VT.r
|
||||
self.VT.scale = major_tab.VT.scale
|
||||
|
||||
self.pinch = major_tab.pinch
|
||||
self.shadow_parrallax = major_tab.shadow_parrallax
|
||||
end
|
||||
|
||||
MWM = {
|
||||
rotated_offset = {},
|
||||
angles = {},
|
||||
WH = {},
|
||||
offs = {},
|
||||
}
|
||||
|
||||
function Moveable:move_with_major(dt)
|
||||
if self.role.role_type ~= 'Minor' then return end
|
||||
local major_tab = self.role.major:get_major()
|
||||
|
||||
self:move_juice(dt)
|
||||
|
||||
if self.role.r_bond == 'Weak' then
|
||||
MWM.rotated_offset.x, MWM.rotated_offset.y = self.role.offset.x + major_tab.offset.x,self.role.offset.y+major_tab.offset.y
|
||||
else
|
||||
if major_tab.major.VT.r < 0.0001 and major_tab.major.VT.r > -0.0001 then
|
||||
MWM.rotated_offset.x = self.role.offset.x + major_tab.offset.x
|
||||
MWM.rotated_offset.y = self.role.offset.y + major_tab.offset.y
|
||||
else
|
||||
MWM.angles.cos, MWM.angles.sin = math.cos(major_tab.major.VT.r),math.sin(major_tab.major.VT.r)
|
||||
MWM.WH.w, MWM.WH.h = -self.T.w/2 + major_tab.major.T.w/2,-self.T.h/2 + major_tab.major.T.h/2
|
||||
MWM.offs.x, MWM.offs.y = self.role.offset.x + major_tab.offset.x - MWM.WH.w,self.role.offset.y + major_tab.offset.y - MWM.WH.h
|
||||
|
||||
MWM.rotated_offset.x = MWM.offs.x*MWM.angles.cos - MWM.offs.y*MWM.angles.sin + MWM.WH.w
|
||||
MWM.rotated_offset.y = MWM.offs.x*MWM.angles.sin + MWM.offs.y*MWM.angles.cos + MWM.WH.h
|
||||
end
|
||||
end
|
||||
|
||||
self.T.x = major_tab.major.T.x + MWM.rotated_offset.x
|
||||
self.T.y = major_tab.major.T.y + MWM.rotated_offset.y
|
||||
|
||||
if self.role.xy_bond == 'Strong' then
|
||||
self.VT.x = major_tab.major.VT.x + MWM.rotated_offset.x
|
||||
self.VT.y = major_tab.major.VT.y + MWM.rotated_offset.y
|
||||
elseif self.role.xy_bond == 'Weak' then
|
||||
self:move_xy(dt)
|
||||
end
|
||||
|
||||
if self.role.r_bond == 'Strong' then
|
||||
self.VT.r = self.T.r + major_tab.major.VT.r + (self.juice and self.juice.r or 0)
|
||||
elseif self.role.r_bond == 'Weak' then
|
||||
self:move_r(dt, self.velocity)
|
||||
end
|
||||
|
||||
if self.role.scale_bond == 'Strong' then
|
||||
self.VT.scale = self.T.scale*(major_tab.major.VT.scale/major_tab.major.T.scale) + (self.juice and self.juice.scale or 0)
|
||||
elseif self.role.scale_bond == 'Weak' then
|
||||
self:move_scale(dt)
|
||||
end
|
||||
|
||||
if self.role.wh_bond == 'Strong' then
|
||||
self.VT.x = self.VT.x + (0.5*(1 - major_tab.major.VT.w/(major_tab.major.T.w))*self.T.w)
|
||||
self.VT.w = (self.T.w)*(major_tab.major.VT.w/major_tab.major.T.w)
|
||||
self.VT.h = (self.T.h)*(major_tab.major.VT.h/major_tab.major.T.h)
|
||||
elseif self.role.wh_bond == 'Weak' then
|
||||
self:move_wh(dt)
|
||||
end
|
||||
|
||||
self:calculate_parrallax()
|
||||
end
|
||||
|
||||
function Moveable:move_xy(dt)
|
||||
if (self.T.x ~= self.VT.x or math.abs(self.velocity.x) > 0.01) or
|
||||
(self.T.y ~= self.VT.y or math.abs(self.velocity.y) > 0.01) then
|
||||
self.velocity.x = G.exp_times.xy*self.velocity.x + (1-G.exp_times.xy)*(self.T.x - self.VT.x)*35*dt
|
||||
self.velocity.y = G.exp_times.xy*self.velocity.y + (1-G.exp_times.xy)*(self.T.y - self.VT.y)*35*dt
|
||||
if self.velocity.x*self.velocity.x + self.velocity.y*self.velocity.y > G.exp_times.max_vel*G.exp_times.max_vel then
|
||||
local actual_vel = math.sqrt(self.velocity.x*self.velocity.x + self.velocity.y*self.velocity.y)
|
||||
self.velocity.x = G.exp_times.max_vel*self.velocity.x/actual_vel
|
||||
self.velocity.y = G.exp_times.max_vel*self.velocity.y/actual_vel
|
||||
end
|
||||
self.STATIONARY = false
|
||||
self.VT.x = self.VT.x + self.velocity.x
|
||||
self.VT.y = self.VT.y + self.velocity.y
|
||||
if math.abs(self.VT.x - self.T.x) < 0.01 and math.abs(self.velocity.x) < 0.01 then self.VT.x = self.T.x; self.velocity.x = 0 end
|
||||
if math.abs(self.VT.y - self.T.y) < 0.01 and math.abs(self.velocity.y) < 0.01 then self.VT.y = self.T.y; self.velocity.y = 0 end
|
||||
end
|
||||
end
|
||||
|
||||
function Moveable:move_scale(dt)
|
||||
local des_scale = self.T.scale + (self.zoom and ((self.states.drag.is and 0.1 or 0) + (self.states.hover.is and 0.05 or 0)) or 0) + (self.juice and self.juice.scale or 0)
|
||||
|
||||
if des_scale ~= self.VT.scale or
|
||||
math.abs(self.velocity.scale) > 0.001 then
|
||||
self.STATIONARY = false
|
||||
self.velocity.scale = G.exp_times.scale*self.velocity.scale + (1-G.exp_times.scale)*(des_scale - self.VT.scale)
|
||||
self.VT.scale = self.VT.scale + self.velocity.scale
|
||||
end
|
||||
end
|
||||
|
||||
function Moveable:move_wh(dt)
|
||||
if Big and G.STATE == G.STATES.MENU then self.T.w = to_big(self.T.w):to_number()
|
||||
self.T.h = to_big(self.T.h):to_number()
|
||||
self.VT.w = to_big(self.VT.w):to_number()
|
||||
self.VT.h = to_big(self.VT.h):to_number() end
|
||||
if (self.T.w ~= self.VT.w and not self.pinch.x) or
|
||||
(self.T.h ~= self.VT.h and not self.pinch.y) or
|
||||
(self.VT.w > 0 and self.pinch.x) or
|
||||
(self.VT.h > 0 and self.pinch.y) then
|
||||
self.STATIONARY = false
|
||||
self.VT.w = self.VT.w + (8*dt)*(self.pinch.x and -1 or 1)*self.T.w
|
||||
self.VT.h = self.VT.h + (8*dt)*(self.pinch.y and -1 or 1)*self.T.h
|
||||
self.VT.w = math.max(math.min(self.VT.w, self.T.w), 0)
|
||||
self.VT.h = math.max(math.min(self.VT.h, self.T.h), 0)
|
||||
end
|
||||
end
|
||||
|
||||
function Moveable:move_r(dt, vel)
|
||||
local des_r = self.T.r +0.015*vel.x/dt + (self.juice and self.juice.r*2 or 0)
|
||||
|
||||
if des_r ~= self.VT.r or
|
||||
math.abs(self.velocity.r) > 0.001 then
|
||||
self.STATIONARY = false
|
||||
self.velocity.r = G.exp_times.r*self.velocity.r + (1-G.exp_times.r)*(des_r - self.VT.r)
|
||||
self.VT.r = self.VT.r + self.velocity.r
|
||||
end
|
||||
if math.abs(self.VT.r - self.T.r) < 0.001 and math.abs(self.velocity.r) < 0.001 then self.VT.r = self.T.r; self.velocity.r = 0 end
|
||||
end
|
||||
|
||||
function Moveable:calculate_parrallax()
|
||||
if not G.ROOM then return end
|
||||
self.shadow_parrallax.x = (self.T.x + self.T.w/2 - G.ROOM.T.w/2)/(G.ROOM.T.w/2)*1.5
|
||||
end
|
||||
|
||||
function Moveable:set_role(args)
|
||||
if args.major and not args.major.set_role then return end
|
||||
if args.offset and (type(args.offset)=='table' and not (args.offset.y and args.offset.x)) or type(args.offset) ~= 'table' then
|
||||
args.offset = nil
|
||||
end
|
||||
self.role = {
|
||||
role_type = args.role_type or self.role.role_type,
|
||||
offset = args.offset or self.role.offset,
|
||||
major = args.major or self.role.major,
|
||||
xy_bond = args.xy_bond or self.role.xy_bond,
|
||||
wh_bond = args.wh_bond or self.role.wh_bond,
|
||||
r_bond = args.r_bond or self.role.r_bond,
|
||||
scale_bond = args.scale_bond or self.role.scale_bond,
|
||||
draw_major = args.draw_major or self.role.draw_major,
|
||||
}
|
||||
if self.role.role_type == 'Major' then self.role.major = nil end
|
||||
end
|
||||
|
||||
function Moveable:get_major()
|
||||
if ( self.role.role_type ~= 'Major' and self.role.major ~= self) and (self.role.xy_bond ~= 'Weak' and self.role.r_bond ~= 'Weak') then
|
||||
--First, does the major already have their offset precalculated for this frame?
|
||||
if not self.FRAME.MAJOR or (G.REFRESH_FRAME_MAJOR_CACHE) then
|
||||
self.FRAME.MAJOR = self.FRAME.MAJOR or EMPTY(self.FRAME.OLD_MAJOR)
|
||||
self.temp_offs = EMPTY(self.temp_offs)
|
||||
local major = self.role.major:get_major()
|
||||
self.FRAME.MAJOR.major = major.major
|
||||
self.FRAME.MAJOR.offset = self.FRAME.MAJOR.offset or self.temp_offs
|
||||
self.FRAME.MAJOR.offset.x, self.FRAME.MAJOR.offset.y = major.offset.x + self.role.offset.x + self.layered_parallax.x, major.offset.y + self.role.offset.y + self.layered_parallax.y
|
||||
end
|
||||
return self.FRAME.MAJOR
|
||||
else
|
||||
self.ARGS.get_major = self.ARGS.get_major or {}
|
||||
self.ARGS.get_major.major = self
|
||||
self.ARGS.get_major.offset = self.ARGS.get_major.offset or {}
|
||||
self.ARGS.get_major.offset.x, self.ARGS.get_major.offset.y = 0,0
|
||||
return self.ARGS.get_major
|
||||
end
|
||||
end
|
||||
|
||||
function Moveable:remove()
|
||||
for k, v in pairs(G.MOVEABLES) do
|
||||
if v == self then
|
||||
table.remove(G.MOVEABLES, k)
|
||||
break;
|
||||
end
|
||||
end
|
||||
for k, v in pairs(G.I.MOVEABLE) do
|
||||
if v == self then
|
||||
table.remove(G.I.MOVEABLE, k)
|
||||
break;
|
||||
end
|
||||
end
|
||||
Node.remove(self)
|
||||
end
|
|
@ -1,222 +0,0 @@
|
|||
LOVELY_INTEGRITY = 'a89ca7b9273fee523938c932a6467dfa383c8e44b527c8da74869b0ae75efe92'
|
||||
|
||||
require "love.audio"
|
||||
require "love.sound"
|
||||
require "love.system"
|
||||
|
||||
if (love.system.getOS() == 'OS X' )and (jit.arch == 'arm64' or jit.arch == 'arm') then jit.off() end
|
||||
|
||||
--vars needed for sound manager thread
|
||||
CHANNEL = love.thread.getChannel("sound_request")
|
||||
LOAD_CHANNEL = love.thread.getChannel('load_channel')
|
||||
LOAD_CHANNEL:push('audio thread start')
|
||||
DISABLE_SFX = false
|
||||
SMODS_Sounds = {}
|
||||
|
||||
--create all sounds from resources and play one each to load into mem
|
||||
SOURCES = {}
|
||||
local sound_files = love.filesystem.getDirectoryItems("resources/sounds")
|
||||
|
||||
for _, filename in ipairs(sound_files) do
|
||||
local extension = string.sub(filename, -4)
|
||||
for i = 1, 1 do
|
||||
if extension == '.ogg' then
|
||||
LOAD_CHANNEL:push('audio file - '..filename)
|
||||
local sound_code = string.sub(filename, 1, -5)
|
||||
local s = {
|
||||
sound = love.audio.newSource("resources/sounds/"..filename,string.find(sound_code,'music') and "stream" or 'static'),
|
||||
filepath = "resources/sounds/"..filename
|
||||
}
|
||||
SOURCES[sound_code] = {}
|
||||
table.insert(SOURCES[sound_code], s)
|
||||
s.sound_code = sound_code
|
||||
s.sound:setVolume(0)
|
||||
love.audio.play(s.sound)
|
||||
s.sound:stop()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PLAY_SOUND(args)
|
||||
args.per = args.per or 1
|
||||
args.vol = args.vol or 1
|
||||
SOURCES[args.sound_code] = SOURCES[args.sound_code] or {}
|
||||
|
||||
for _, s in ipairs(SOURCES[args.sound_code]) do
|
||||
if s.sound and not s.sound:isPlaying() then
|
||||
s.original_pitch = args.per
|
||||
s.original_volume = args.vol
|
||||
s.created_on_pause = args.overlay_menu
|
||||
s.created_on_state = args.state
|
||||
s.sfx_handled = 0
|
||||
s.transition_timer = 0
|
||||
SET_SFX(s, args)
|
||||
love.audio.play(s.sound)
|
||||
return s
|
||||
end
|
||||
end
|
||||
|
||||
local should_stream = (string.find(args.sound_code,'music') or string.find(args.sound_code,'ambient'))
|
||||
local c = SMODS_Sounds[args.sound_code]
|
||||
local s = c and
|
||||
{sound = love.audio.newSource(love.sound.newDecoder(c.data), c.should_stream and 'stream' or 'static'), per = c.per, vol = c.vol } or
|
||||
{sound = love.audio.newSource("resources/sounds/"..args.sound_code..'.ogg', should_stream and "stream" or 'static')}
|
||||
table.insert(SOURCES[args.sound_code], s)
|
||||
s.sound_code = args.sound_code
|
||||
s.original_pitch = ((args.type ~= "sound") and s.per) or args.per or 1
|
||||
s.original_volume = ((args.type ~= "sound") and s.vol) or args.vol or 1
|
||||
s.created_on_pause = (args.overlay_menu and true or false)
|
||||
s.created_on_state = args.state
|
||||
s.sfx_handled = 0
|
||||
s.transition_timer = 0
|
||||
SET_SFX(s, args)
|
||||
love.audio.play(s.sound)
|
||||
return s
|
||||
end
|
||||
|
||||
function STOP_AUDIO()
|
||||
for _, source in pairs(SOURCES) do
|
||||
for _, s in pairs(source) do
|
||||
if s.sound:isPlaying() then
|
||||
s.sound:stop()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function SET_SFX(s, args)
|
||||
if string.find(s.sound_code,'music') then
|
||||
if s.sound_code == args.desired_track then
|
||||
s.current_volume = s.current_volume or 1
|
||||
s.current_volume = 1*(args.dt*3) + (1-(args.dt*3))*s.current_volume
|
||||
else
|
||||
s.current_volume = s.current_volume or 0
|
||||
s.current_volume = 0*(args.dt*3) + (1-(args.dt*3))*s.current_volume
|
||||
end
|
||||
s.sound:setVolume(s.current_volume*s.original_volume*(args.sound_settings.volume/100.0)*(args.sound_settings.music_volume/100.0))
|
||||
s.sound:setPitch(s.original_pitch*args.pitch_mod)
|
||||
else
|
||||
if s.temp_pitch ~= s.original_pitch then
|
||||
s.sound:setPitch(s.original_pitch)
|
||||
s.temp_pitch = s.original_pitch
|
||||
end
|
||||
local sound_vol = s.original_volume*(args.sound_settings.volume/100.0)*(args.sound_settings.game_sounds_volume/100.0)
|
||||
if s.created_on_state == 13 then sound_vol = sound_vol*args.splash_vol end
|
||||
if sound_vol <= 0 then
|
||||
s.sound:stop()
|
||||
else
|
||||
s.sound:setVolume(sound_vol)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function MODULATE(args)
|
||||
if args.desired_track ~= '' then
|
||||
local sound = ((SOURCES[current_track or {}] or {})[1] or {}).sound
|
||||
if not sound or not sound:isPlaying() then
|
||||
RESTART_MUSIC(args)
|
||||
end
|
||||
end
|
||||
|
||||
for k, v in pairs(SOURCES) do
|
||||
local i=1
|
||||
while i <= #v do
|
||||
if not v[i].sound:isPlaying() then
|
||||
v[i].sound:release()
|
||||
table.remove(v, i)
|
||||
else
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
|
||||
current_track = args.desired_track
|
||||
for _, s in pairs(v) do
|
||||
if s.sound and s.sound:isPlaying() and s.original_volume then
|
||||
SET_SFX(s, args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function RESTART_MUSIC(args)
|
||||
for k, v in pairs(SOURCES) do
|
||||
if string.find(k,'music') then
|
||||
for i, s in ipairs(v) do
|
||||
s.sound:stop()
|
||||
end
|
||||
SOURCES[k] = {}
|
||||
args.per = 0.7
|
||||
args.vol = 0.6
|
||||
args.sound_code = k
|
||||
local s = PLAY_SOUND(args)
|
||||
s.initialized = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function AMBIENT(args)
|
||||
for k, v in pairs(SOURCES) do
|
||||
if args.ambient_control[k] then
|
||||
local start_ambient = args.ambient_control[k].vol*(args.sound_settings.volume/100.0)*(args.sound_settings.game_sounds_volume/100.0) > 0
|
||||
|
||||
for i, s in ipairs(v) do
|
||||
if s.sound and s.sound:isPlaying() and s.original_volume then
|
||||
s.original_volume = args.ambient_control[k].vol
|
||||
SET_SFX(s, args)
|
||||
start_ambient = false
|
||||
end
|
||||
end
|
||||
|
||||
if start_ambient then
|
||||
args.sound_code = k
|
||||
args.vol = args.ambient_control[k].vol
|
||||
args.per = args.ambient_control[k].per
|
||||
PLAY_SOUND(args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function RESET_STATES(state)
|
||||
for k, v in pairs(SOURCES) do
|
||||
for i, s in ipairs(v) do
|
||||
s.created_on_state = state
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
LOAD_CHANNEL:push('finished')
|
||||
|
||||
while true do
|
||||
--Monitor the channel for any new requests
|
||||
local request = CHANNEL:demand() -- Value from channel
|
||||
if request then
|
||||
if request.type == 'kill' then return end
|
||||
--If the request is for an update to the music track, handle it here
|
||||
if false then elseif request.type == 'sound' then
|
||||
PLAY_SOUND(request)
|
||||
elseif request.type == 'sound_source' then
|
||||
SMODS_Sounds[request.sound_code] = {
|
||||
sound_code = request.sound_code,
|
||||
data = request.data,
|
||||
sound = sound,
|
||||
per = request.per,
|
||||
vol = request.vol,
|
||||
}
|
||||
SOURCES[request.sound_code] = {}
|
||||
elseif request.type == 'stop' then
|
||||
STOP_AUDIO()
|
||||
elseif request.type == 'modulate' then
|
||||
MODULATE(request)
|
||||
if request.ambient_control then AMBIENT(request) end
|
||||
elseif request.type == 'restart_music' then
|
||||
RESTART_MUSIC(request)
|
||||
elseif request.type == 'reset_states' then
|
||||
for k, v in pairs(SOURCES) do
|
||||
for i, s in ipairs(v) do
|
||||
s.created_on_state = request.state
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,232 +0,0 @@
|
|||
LOVELY_INTEGRITY = '3d0395906e098682391897a81b05df12cd2dc6e39322ebd87a281c6c9d1caebc'
|
||||
|
||||
--Class
|
||||
Sprite = Moveable:extend()
|
||||
|
||||
--Class Methods
|
||||
function Sprite:init(X, Y, W, H, new_sprite_atlas, sprite_pos)
|
||||
Moveable.init(self,X, Y, W, H)
|
||||
self.CT = self.VT
|
||||
self.atlas = new_sprite_atlas
|
||||
self.scale = {x=self.atlas.px, y=self.atlas.py}
|
||||
self.scale_mag = math.min(self.scale.x/W,self.scale.y/H)
|
||||
self.zoom = true
|
||||
|
||||
self:set_sprite_pos(sprite_pos)
|
||||
|
||||
if getmetatable(self) == Sprite then
|
||||
table.insert(G.I.SPRITE, self)
|
||||
end
|
||||
end
|
||||
|
||||
function Sprite:reset()
|
||||
self.atlas = G.ASSET_ATLAS[self.atlas.name]
|
||||
self:set_sprite_pos(self.sprite_pos)
|
||||
end
|
||||
|
||||
function Sprite:set_sprite_pos(sprite_pos)
|
||||
if sprite_pos and sprite_pos.v then
|
||||
self.sprite_pos = {x = (math.random(sprite_pos.v)-1), y = sprite_pos.y}
|
||||
else
|
||||
self.sprite_pos = sprite_pos or {x=0,y=0}
|
||||
end
|
||||
self.sprite_pos_copy = {x = self.sprite_pos.x, y = self.sprite_pos.y}
|
||||
|
||||
self.sprite = love.graphics.newQuad(
|
||||
self.sprite_pos.x*self.atlas.px,
|
||||
self.sprite_pos.y*self.atlas.py,
|
||||
self.scale.x,
|
||||
self.scale.y, self.atlas.image:getDimensions())
|
||||
|
||||
self.image_dims = {}
|
||||
self.image_dims[1], self.image_dims[2] = self.atlas.image:getDimensions()
|
||||
end
|
||||
|
||||
function Sprite:get_pos_pixel()
|
||||
self.RETS.get_pos_pixel = self.RETS.get_pos_pixel or {}
|
||||
self.RETS.get_pos_pixel[1] = self.sprite_pos.x
|
||||
self.RETS.get_pos_pixel[2] = self.sprite_pos.y
|
||||
self.RETS.get_pos_pixel[3] = self.atlas.px --self.scale.x
|
||||
self.RETS.get_pos_pixel[4] = self.atlas.py --self.scale.y
|
||||
return self.RETS.get_pos_pixel
|
||||
end
|
||||
|
||||
function Sprite:get_image_dims()
|
||||
return self.image_dims
|
||||
end
|
||||
|
||||
function Sprite:define_draw_steps(draw_step_definitions)
|
||||
self.draw_steps = EMPTY(self.draw_steps)
|
||||
for k, v in ipairs(draw_step_definitions) do
|
||||
self.draw_steps[#self.draw_steps+1] = {
|
||||
shader = v.shader or 'dissolve',
|
||||
shadow_height = v.shadow_height or nil,
|
||||
send = v.send or nil,
|
||||
no_tilt = v.no_tilt or nil,
|
||||
other_obj = v.other_obj or nil,
|
||||
ms = v.ms or nil,
|
||||
mr = v.mr or nil,
|
||||
mx = v.mx or nil,
|
||||
my = v.my or nil
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function Sprite:draw_shader(_shader, _shadow_height, _send, _no_tilt, other_obj, ms, mr, mx, my, custom_shader, tilt_shadow)
|
||||
if G.SETTINGS.reduced_motion then _no_tilt = true end
|
||||
local _draw_major = self.role.draw_major or self
|
||||
if _shadow_height then
|
||||
self.VT.y = self.VT.y - _draw_major.shadow_parrallax.y*_shadow_height
|
||||
self.VT.x = self.VT.x - _draw_major.shadow_parrallax.x*_shadow_height
|
||||
self.VT.scale = self.VT.scale*(1-0.2*_shadow_height)
|
||||
end
|
||||
|
||||
if custom_shader then
|
||||
if _send then
|
||||
for k, v in ipairs(_send) do
|
||||
G.SHADERS[_shader]:send(v.name, v.val or (v.func and v.func()) or v.ref_table[v.ref_value])
|
||||
end
|
||||
end
|
||||
elseif _shader == 'vortex' then
|
||||
G.SHADERS['vortex']:send('vortex_amt', G.TIMERS.REAL - (G.vortex_time or 0))
|
||||
else
|
||||
self.ARGS.prep_shader = self.ARGS.prep_shader or {}
|
||||
self.ARGS.prep_shader.cursor_pos = self.ARGS.prep_shader.cursor_pos or {}
|
||||
self.ARGS.prep_shader.cursor_pos[1] = _draw_major.tilt_var and _draw_major.tilt_var.mx*G.CANV_SCALE or G.CONTROLLER.cursor_position.x*G.CANV_SCALE
|
||||
self.ARGS.prep_shader.cursor_pos[2] = _draw_major.tilt_var and _draw_major.tilt_var.my*G.CANV_SCALE or G.CONTROLLER.cursor_position.y*G.CANV_SCALE
|
||||
|
||||
G.SHADERS[_shader or 'dissolve']:send('mouse_screen_pos', self.ARGS.prep_shader.cursor_pos)
|
||||
G.SHADERS[_shader or 'dissolve']:send('screen_scale', G.TILESCALE*G.TILESIZE*(_draw_major.mouse_damping or 1)*G.CANV_SCALE)
|
||||
G.SHADERS[_shader or 'dissolve']:send('hovering',((_shadow_height and not tilt_shadow) or _no_tilt) and 0 or (_draw_major.hover_tilt or 0)*(tilt_shadow or 1))
|
||||
G.SHADERS[_shader or 'dissolve']:send("dissolve",math.abs(_draw_major.dissolve or 0))
|
||||
G.SHADERS[_shader or 'dissolve']:send("time",123.33412*(_draw_major.ID/1.14212 or 12.5123152)%3000)
|
||||
G.SHADERS[_shader or 'dissolve']:send("texture_details",self:get_pos_pixel())
|
||||
G.SHADERS[_shader or 'dissolve']:send("image_details",self:get_image_dims())
|
||||
G.SHADERS[_shader or 'dissolve']:send("burn_colour_1",_draw_major.dissolve_colours and _draw_major.dissolve_colours[1] or G.C.CLEAR)
|
||||
G.SHADERS[_shader or 'dissolve']:send("burn_colour_2",_draw_major.dissolve_colours and _draw_major.dissolve_colours[2] or G.C.CLEAR)
|
||||
G.SHADERS[_shader or 'dissolve']:send("shadow",(not not _shadow_height))
|
||||
if _send then
|
||||
G.SHADERS[_shader or 'dissolve']:send((SMODS.Shaders[_shader or 'dissolve'] and SMODS.Shaders[_shader or 'dissolve'].original_key) or _shader,_send)
|
||||
end
|
||||
end
|
||||
|
||||
local p_shader = SMODS.Shader.obj_table[_shader or 'dissolve']
|
||||
if p_shader and type(p_shader.send_vars) == "function" then
|
||||
local sh = G.SHADERS[_shader or 'dissolve']
|
||||
local parent_card = self.role.major and self.role.major:is(Card) and self.role.major
|
||||
local send_vars = p_shader.send_vars(self, parent_card)
|
||||
|
||||
if type(send_vars) == "table" then
|
||||
for key, value in pairs(send_vars) do
|
||||
sh:send(key, value)
|
||||
end
|
||||
end
|
||||
end
|
||||
love.graphics.setShader( G.SHADERS[_shader or 'dissolve'], G.SHADERS[_shader or 'dissolve'])
|
||||
|
||||
if other_obj then
|
||||
self:draw_from(other_obj, ms, mr, mx, my)
|
||||
else
|
||||
self:draw_self()
|
||||
end
|
||||
|
||||
love.graphics.setShader()
|
||||
|
||||
if _shadow_height then
|
||||
self.VT.y = self.VT.y + _draw_major.shadow_parrallax.y*_shadow_height
|
||||
self.VT.x = self.VT.x + _draw_major.shadow_parrallax.x*_shadow_height
|
||||
self.VT.scale = self.VT.scale/(1-0.2*_shadow_height)
|
||||
end
|
||||
end
|
||||
|
||||
function Sprite:draw_self(overlay)
|
||||
if not self.states.visible then return end
|
||||
if self.sprite_pos.x ~= self.sprite_pos_copy.x or self.sprite_pos.y ~= self.sprite_pos_copy.y then
|
||||
self:set_sprite_pos(self.sprite_pos)
|
||||
end
|
||||
prep_draw(self, 1)
|
||||
love.graphics.scale(1/(self.scale.x/self.VT.w), 1/(self.scale.y/self.VT.h))
|
||||
love.graphics.setColor(overlay or G.BRUTE_OVERLAY or G.C.WHITE)
|
||||
if self.video then
|
||||
self.video_dims = self.video_dims or {
|
||||
w = self.video:getWidth(),
|
||||
h = self.video:getHeight(),
|
||||
}
|
||||
love.graphics.draw(
|
||||
self.video,
|
||||
0 ,0,
|
||||
0,
|
||||
self.VT.w/(self.T.w)/(self.video_dims.w/self.scale.x),
|
||||
self.VT.h/(self.T.h)/(self.video_dims.h/self.scale.y)
|
||||
)
|
||||
else
|
||||
love.graphics.draw(
|
||||
self.atlas.image,
|
||||
self.sprite,
|
||||
0 ,0,
|
||||
0,
|
||||
self.VT.w/(self.T.w),
|
||||
self.VT.h/(self.T.h)
|
||||
)
|
||||
end
|
||||
love.graphics.pop()
|
||||
add_to_drawhash(self)
|
||||
self:draw_boundingrect()
|
||||
if self.shader_tab then love.graphics.setShader() end
|
||||
end
|
||||
|
||||
function Sprite:draw(overlay)
|
||||
if not self.states.visible then return end
|
||||
if self.draw_steps then
|
||||
for k, v in ipairs(self.draw_steps) do
|
||||
self:draw_shader(v.shader, v.shadow_height, v.send, v.no_tilt, v.other_obj, v.ms, v.mr, v.mx, v.my, not not v.send)
|
||||
end
|
||||
else
|
||||
self:draw_self(overlay)
|
||||
end
|
||||
|
||||
add_to_drawhash(self)
|
||||
for k, v in pairs(self.children) do
|
||||
if k ~= 'h_popup' then v:draw() end
|
||||
end
|
||||
add_to_drawhash(self)
|
||||
self:draw_boundingrect()
|
||||
end
|
||||
|
||||
function Sprite:draw_from(other_obj, ms, mr, mx, my)
|
||||
self.ARGS.draw_from_offset = self.ARGS.draw_from_offset or {}
|
||||
self.ARGS.draw_from_offset.x = mx or 0
|
||||
self.ARGS.draw_from_offset.y = my or 0
|
||||
prep_draw(other_obj, (1 + (ms or 0)), (mr or 0), self.ARGS.draw_from_offset, true)
|
||||
love.graphics.scale(1/(other_obj.scale_mag or other_obj.VT.scale))
|
||||
love.graphics.setColor(G.BRUTE_OVERLAY or G.C.WHITE)
|
||||
love.graphics.draw(
|
||||
self.atlas.image,
|
||||
self.sprite,
|
||||
-(other_obj.T.w/2 -other_obj.VT.w/2)*10,
|
||||
0,
|
||||
0,
|
||||
other_obj.VT.w/(other_obj.T.w),
|
||||
other_obj.VT.h/(other_obj.T.h)
|
||||
)
|
||||
self:draw_boundingrect()
|
||||
love.graphics.pop()
|
||||
end
|
||||
|
||||
function Sprite:remove()
|
||||
if self.video then
|
||||
self.video:release()
|
||||
end
|
||||
for k, v in pairs(G.ANIMATIONS) do
|
||||
if v == self then
|
||||
table.remove(G.ANIMATIONS, k)
|
||||
end
|
||||
end
|
||||
for k, v in pairs(G.I.SPRITE) do
|
||||
if v == self then
|
||||
table.remove(G.I.SPRITE, k)
|
||||
end
|
||||
end
|
||||
|
||||
Moveable.remove(self)
|
||||
end
|
|
@ -1,83 +0,0 @@
|
|||
LOVELY_INTEGRITY = '5d0771786fa792673ea7fd08a5f7ef9bfec9d89cc6a2d2f4ee8e7ff3faee05ec'
|
||||
|
||||
--[[
|
||||
MIT License
|
||||
Copyright (c) 2017 Robert Herlihy
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
|
||||
--I modified this A LOT. Needed to make it quicker if it is being saved to file every few seconds during a game
|
||||
function STR_PACK(data, recursive)
|
||||
local ret_str = (recursive and "" or "return ").."{"
|
||||
|
||||
for i, v in pairs(data) do
|
||||
local type_i, type_v = type(i), type(v)
|
||||
assert((type_i ~= "table"), "Data table cannot have an table as a key reference")
|
||||
if type_i == "string" then
|
||||
i = '['..string.format("%q",i)..']'
|
||||
else
|
||||
i = "["..i.."]"
|
||||
end
|
||||
if type_v == "table" then
|
||||
if v.m and v.e then
|
||||
v = "to_big("..v.m..","..v.e..")"
|
||||
elseif v.array and v.sign then
|
||||
local v0 = "to_big({"
|
||||
for qi = 1,#v.array do
|
||||
v0 = v0 .. v.array[qi] .. ", "
|
||||
end
|
||||
v0 = v0 .. "},"..v.sign..")"
|
||||
v = v0
|
||||
elseif v.is and v:is(Object) then
|
||||
v = [["]].."MANUAL_REPLACE"..[["]]
|
||||
else
|
||||
v = STR_PACK(v, true)
|
||||
end
|
||||
else
|
||||
if type_v == "string" then v = string.format("%q", v) end
|
||||
if type_v == "boolean" then v = v and "true" or "false" end
|
||||
end
|
||||
ret_str = ret_str..i.."="..v..","
|
||||
end
|
||||
|
||||
return ret_str.."}"
|
||||
end
|
||||
|
||||
function STR_UNPACK(str)
|
||||
return assert(loadstring(str))()
|
||||
end
|
||||
|
||||
function get_compressed(_file)
|
||||
local file_data = love.filesystem.getInfo(_file)
|
||||
if file_data ~= nil then
|
||||
local file_string = love.filesystem.read(_file)
|
||||
if file_string ~= '' then
|
||||
if string.sub(file_string, 1, 6) ~= 'return' then
|
||||
local success = nil
|
||||
success, file_string = pcall(love.data.decompress, 'string', 'deflate', file_string)
|
||||
if not success then return nil end
|
||||
end
|
||||
return file_string
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function compress_and_save(_file, _data)
|
||||
local save_string = type(_data) == 'table' and STR_PACK(_data) or _data
|
||||
save_string = love.data.compress('string', 'deflate', save_string, 1)
|
||||
love.filesystem.write(_file,save_string)
|
||||
end
|
|
@ -1,360 +0,0 @@
|
|||
LOVELY_INTEGRITY = '3f32eb39deebe597f05c1629610525603e46d33168f8992920aef2aab6c8d63a'
|
||||
|
||||
--Class
|
||||
DynaText = Moveable:extend()
|
||||
|
||||
--Class Methods
|
||||
function DynaText:init(config)
|
||||
config = config or {}
|
||||
self.config = config
|
||||
self.shadow = config.shadow
|
||||
self.scale = config.scale or 1
|
||||
self.pop_in_rate = config.pop_in_rate or 3
|
||||
self.bump_rate = config.bump_rate or 2.666
|
||||
self.bump_amount = config.bump_amount or 1
|
||||
self.font = config.font or G.LANG.font
|
||||
if config.string and type(config.string) ~= 'table' then config.string = {config.string} end
|
||||
self.string = (config.string and type(config.string) == 'table' and config.string[1]) or {'HELLO WORLD'}
|
||||
self.text_offset = {
|
||||
x = self.font.TEXT_OFFSET.x*self.scale + (self.config.x_offset or 0),
|
||||
y = self.font.TEXT_OFFSET.y*self.scale + (self.config.y_offset or 0),
|
||||
}
|
||||
self.colours = config.colours or {G.C.RED}
|
||||
self.created_time = G.TIMERS.REAL
|
||||
self.silent = (config.silent)
|
||||
|
||||
self.start_pop_in = self.config.pop_in
|
||||
|
||||
config.W = 0
|
||||
config.H = 0
|
||||
|
||||
self.strings = {}
|
||||
self.focused_string = 1
|
||||
|
||||
self:update_text(true)
|
||||
if self.config.maxw and self.config.W > self.config.maxw then
|
||||
self.start_pop_in = self.config.pop_in
|
||||
self.scale = self.scale*(self.config.maxw/self.config.W)
|
||||
self:update_text(true)
|
||||
end
|
||||
|
||||
if #self.strings > 1 then
|
||||
self.pop_delay = self.config.pop_delay or 1.5
|
||||
self:pop_out(4)
|
||||
end
|
||||
|
||||
Moveable.init(self,config.X or 0, config.Y or 0, config.W, config.H)
|
||||
|
||||
self.T.r = self.config.text_rot or 0
|
||||
|
||||
self.states.hover.can = false
|
||||
self.states.click.can = false
|
||||
self.states.collide.can = false
|
||||
self.states.drag.can = false
|
||||
self.states.release_on.can = false
|
||||
|
||||
self:set_role{
|
||||
wh_bond = 'Weak',
|
||||
scale_bond = 'Weak'
|
||||
}
|
||||
|
||||
if getmetatable(self) == DynaText then
|
||||
table.insert(G.I.MOVEABLE, self)
|
||||
end
|
||||
end
|
||||
|
||||
function DynaText:update(dt)
|
||||
self:update_text()
|
||||
self:align_letters()
|
||||
end
|
||||
|
||||
function DynaText:update_text(first_pass)
|
||||
self.config.W = 0
|
||||
self.config.H = 0
|
||||
self.scale = self.config.scale_function and self.config.scale_function() or self.scale
|
||||
|
||||
for k, v in ipairs(self.config.string) do
|
||||
if (type(v) == 'table' and v.ref_table) or first_pass then
|
||||
local part_a, part_b = 0,1000000
|
||||
local new_string = v
|
||||
local outer_colour = nil
|
||||
local inner_colour = nil
|
||||
local part_scale = 1
|
||||
if type(v) == 'table' and (v.ref_table or v.string) then
|
||||
new_string = (v.prefix or '')..format_ui_value(v.ref_table and v.ref_table[v.ref_value] or v.string)..(v.suffix or '')
|
||||
part_a = #(v.prefix or '')
|
||||
part_b = #new_string - #(v.suffix or '')
|
||||
if v.scale then part_scale = v.scale end
|
||||
if first_pass then
|
||||
outer_colour = v.outer_colour or nil
|
||||
inner_colour = v.colour or nil
|
||||
end
|
||||
v = new_string
|
||||
end
|
||||
|
||||
self.strings[k] = self.strings[k] or {}
|
||||
local old_string = self.strings[k].string
|
||||
if old_string ~= new_string or first_pass then
|
||||
if self.start_pop_in then self.reset_pop_in = true end
|
||||
self.reset_pop_in = self.reset_pop_in or self.config.reset_pop_in
|
||||
if not self.reset_pop_in then
|
||||
self.config.pop_out = nil
|
||||
self.config.pop_in = nil
|
||||
else
|
||||
self.config.pop_in = self.config.pop_in or 0
|
||||
self.created_time = G.TIMERS.REAL
|
||||
end
|
||||
self.strings[k].string = v
|
||||
local old_letters = self.strings[k].letters
|
||||
local tempW = 0
|
||||
local tempH = 0
|
||||
local current_letter = 1
|
||||
self.strings[k].letters = {}--EMPTY(self.strings[k].letters)
|
||||
|
||||
for _, c in utf8.chars(v) do
|
||||
local old_letter = old_letters and old_letters[current_letter] or nil
|
||||
local let_tab = {letter = love.graphics.newText(self.font.FONT, c), char = c, scale = old_letter and old_letter.scale or part_scale}
|
||||
self.strings[k].letters[current_letter] = let_tab
|
||||
local tx = self.font.FONT:getWidth(c)*self.scale*part_scale*G.TILESCALE*self.font.FONTSCALE + 2.7*(self.config.spacing or 0)*G.TILESCALE*self.font.FONTSCALE
|
||||
local ty = self.font.FONT:getHeight(c)*self.scale*part_scale*G.TILESCALE*self.font.FONTSCALE*self.font.TEXT_HEIGHT_SCALE
|
||||
let_tab.offset = old_letter and old_letter.offset or {x = 0, y = 0}
|
||||
let_tab.dims = {x = tx/(self.font.FONTSCALE*G.TILESCALE), y = ty/(self.font.FONTSCALE*G.TILESCALE)}
|
||||
let_tab.pop_in = first_pass and (old_letter and old_letter.pop_in or (self.config.pop_in and 0 or 1)) or 1
|
||||
let_tab.prefix = current_letter <= part_a and outer_colour or nil
|
||||
let_tab.suffix = current_letter > part_b and outer_colour or nil
|
||||
let_tab.colour = inner_colour or nil
|
||||
if k > 1 then let_tab.pop_in = 0 end
|
||||
tempW = tempW + tx/(G.TILESIZE*G.TILESCALE)
|
||||
tempH = math.max(ty/(G.TILESIZE*G.TILESCALE), tempH)
|
||||
current_letter = current_letter + 1
|
||||
end
|
||||
|
||||
self.strings[k].W = tempW
|
||||
self.strings[k].H = tempH
|
||||
end
|
||||
end
|
||||
|
||||
if Big then
|
||||
if type(self.strings[k].W) == 'table' then
|
||||
self.strings[k].W = self.strings[k].W:to_number()
|
||||
end
|
||||
if type(self.strings[k].H) == 'table' then
|
||||
self.strings[k].H = self.strings[k].H:to_number()
|
||||
end
|
||||
end
|
||||
if self.strings[k].W > self.config.W then self.config.W = self.strings[k].W; self.strings[k].W_offset = 0 end
|
||||
if self.strings[k].H > self.config.H then self.config.H = self.strings[k].H; self.strings[k].H_offset = 0 end
|
||||
end
|
||||
|
||||
if self.T then
|
||||
if (self.T.w ~= self.config.W or self.T.h ~= self.config.H) and (not first_pass or self.reset_pop_in) then
|
||||
self.ui_object_updated = true
|
||||
self.non_recalc = self.config.non_recalc
|
||||
end
|
||||
self.T.w = self.config.W
|
||||
self.T.h = self.config.H
|
||||
end
|
||||
|
||||
self.reset_pop_in = false
|
||||
self.start_pop_in = false
|
||||
|
||||
for k, v in ipairs(self.strings) do
|
||||
v.W_offset = 0.5*(self.config.W - v.W)
|
||||
v.H_offset = 0.5*(self.config.H - v.H + (self.config.offset_y or 0))
|
||||
end
|
||||
end
|
||||
|
||||
function DynaText:pop_out(pop_out_timer)
|
||||
self.config.pop_out = pop_out_timer or 1
|
||||
self.pop_out_time = G.TIMERS.REAL + (self.pop_delay or 0)
|
||||
end
|
||||
|
||||
function DynaText:pop_in(pop_in_timer)
|
||||
self.reset_pop_in = true
|
||||
self.config.pop_out = nil
|
||||
self.config.pop_in = pop_in_timer or 0
|
||||
self.created_time = G.TIMERS.REAL
|
||||
|
||||
for k, letter in ipairs(self.strings[self.focused_string].letters) do
|
||||
if Big then
|
||||
letter.dims.x = to_big(letter.dims.x):to_number()
|
||||
letter.dims.y = to_big(letter.dims.y):to_number()
|
||||
letter.offset.x = to_big(letter.offset.x):to_number()
|
||||
letter.offset.y = to_big(letter.offset.y):to_number()
|
||||
end
|
||||
letter.pop_in = 0
|
||||
end
|
||||
|
||||
self:update_text()
|
||||
end
|
||||
|
||||
function DynaText:align_letters()
|
||||
if self.pop_cycle then
|
||||
self.focused_string = (self.config.random_element and math.random(1, #self.strings)) or self.focused_string == #self.strings and 1 or self.focused_string+1
|
||||
self.pop_cycle = false
|
||||
for k, letter in ipairs(self.strings[self.focused_string].letters) do
|
||||
if Big then
|
||||
letter.dims.x = to_big(letter.dims.x):to_number()
|
||||
letter.dims.y = to_big(letter.dims.y):to_number()
|
||||
letter.offset.x = to_big(letter.offset.x):to_number()
|
||||
letter.offset.y = to_big(letter.offset.y):to_number()
|
||||
end
|
||||
letter.pop_in = 0
|
||||
end
|
||||
self.config.pop_in = 0.1
|
||||
self.config.pop_out = nil
|
||||
self.created_time = G.TIMERS.REAL
|
||||
end
|
||||
self.string = self.strings[self.focused_string].string
|
||||
for k, letter in ipairs(self.strings[self.focused_string].letters) do
|
||||
if Big then
|
||||
letter.dims.x = to_big(letter.dims.x):to_number()
|
||||
letter.dims.y = to_big(letter.dims.y):to_number()
|
||||
letter.offset.x = to_big(letter.offset.x):to_number()
|
||||
letter.offset.y = to_big(letter.offset.y):to_number()
|
||||
end
|
||||
if self.config.pop_out then
|
||||
letter.pop_in = math.min(1, math.max((self.config.min_cycle_time or 1)-(G.TIMERS.REAL - self.pop_out_time)*self.config.pop_out/(self.config.min_cycle_time or 1), 0))
|
||||
letter.pop_in = letter.pop_in*letter.pop_in
|
||||
if k == #self.strings[self.focused_string].letters and letter.pop_in <= 0 and #self.strings > 1 then self.pop_cycle = true end
|
||||
elseif self.config.pop_in then
|
||||
local prev_pop_in = letter.pop_in
|
||||
letter.pop_in = math.min(1, math.max((G.TIMERS.REAL - self.config.pop_in - self.created_time)*#self.string*self.pop_in_rate - k + 1, self.config.min_cycle_time == 0 and 1 or 0))
|
||||
letter.pop_in = letter.pop_in*letter.pop_in
|
||||
if prev_pop_in <=0 and letter.pop_in > 0 and not self.silent and
|
||||
(#self.string < 10 or k%2 == 0) then
|
||||
if self.T.x > G.ROOM.T.w+2 or
|
||||
self.T.y > G.ROOM.T.h+2 or
|
||||
self.T.x <-2 or
|
||||
self.T.y <-2 then else
|
||||
play_sound('paper1', 0.45+0.05*math.random()+(0.3/#self.string)*k + (self.config.pitch_shift or 0))
|
||||
end
|
||||
end
|
||||
if k == #self.strings[self.focused_string].letters and letter.pop_in >= 1 then
|
||||
if #self.strings > 1 then
|
||||
self.pop_delay = (G.TIMERS.REAL - self.config.pop_in - self.created_time + (self.config.pop_delay or 1.5))
|
||||
self:pop_out(4)
|
||||
else
|
||||
self.config.pop_in = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
letter.r = 0
|
||||
letter.scale = 1
|
||||
if self.config.rotate then letter.r = (self.config.rotate == 2 and -1 or 1)*(0.2*(-#self.strings[self.focused_string].letters/2 - 0.5 + k)/(#self.strings[self.focused_string].letters)+ (G.SETTINGS.reduced_motion and 0 or 1)*0.02*math.sin(2*G.TIMERS.REAL+k)) end
|
||||
if self.config.pulse then
|
||||
letter.scale = letter.scale + (G.SETTINGS.reduced_motion and 0 or 1)*(1/self.config.pulse.width)*self.config.pulse.amount*(math.max(
|
||||
math.min((self.config.pulse.start - G.TIMERS.REAL)*self.config.pulse.speed + k + self.config.pulse.width,
|
||||
(G.TIMERS.REAL - self.config.pulse.start)*self.config.pulse.speed - k + self.config.pulse.width+ 2),
|
||||
0))
|
||||
letter.r = letter.r + (G.SETTINGS.reduced_motion and 0 or 1)*(letter.scale - 1)*(0.02*(-#self.strings[self.focused_string].letters/2 - 0.5 + k))
|
||||
if self.config.pulse.start > G.TIMERS.REAL + 2*self.config.pulse.speed*#self.strings[self.focused_string].letters then
|
||||
self.config.pulse = nil
|
||||
end
|
||||
end
|
||||
if self.config.quiver then
|
||||
letter.scale = letter.scale + (G.SETTINGS.reduced_motion and 0 or 1)*(0.1*self.config.quiver.amount)
|
||||
letter.r = letter.r + (G.SETTINGS.reduced_motion and 0 or 1)*0.3*self.config.quiver.amount*(
|
||||
math.sin(41.12342*G.TIMERS.REAL*self.config.quiver.speed + k*1223.2) +
|
||||
math.cos(63.21231*G.TIMERS.REAL*self.config.quiver.speed + k*1112.2)*math.sin(36.1231*G.TIMERS.REAL*self.config.quiver.speed) +
|
||||
math.cos(95.123*G.TIMERS.REAL*self.config.quiver.speed + k*1233.2) -
|
||||
math.sin(30.133421*G.TIMERS.REAL*self.config.quiver.speed + k*123.2))
|
||||
end
|
||||
if self.config.float then letter.offset.y = (G.SETTINGS.reduced_motion and 0 or 1)*math.sqrt(self.scale)*(2+(self.font.FONTSCALE/G.TILESIZE)*2000*math.sin(2.666*G.TIMERS.REAL+200*k)) + 60*(letter.scale-1) end
|
||||
if self.config.bump then letter.offset.y = (G.SETTINGS.reduced_motion and 0 or 1)*self.bump_amount*math.sqrt(self.scale)*7*math.max(0, (5+self.bump_rate)*math.sin(self.bump_rate*G.TIMERS.REAL+200*k) - 3 - self.bump_rate) end
|
||||
end
|
||||
end
|
||||
|
||||
function DynaText:set_quiver(amt)
|
||||
self.config.quiver = {
|
||||
speed = 0.5,
|
||||
amount = amt or 0.7,
|
||||
silent = false
|
||||
}
|
||||
end
|
||||
|
||||
function DynaText:pulse(amt)
|
||||
self.config.pulse = {
|
||||
speed = 40,
|
||||
width = 2.5,
|
||||
start = G.TIMERS.REAL,
|
||||
amount = amt or 0.2,
|
||||
silent = false
|
||||
}
|
||||
end
|
||||
|
||||
function DynaText:draw()
|
||||
if Big then
|
||||
self.scale = to_big(self.scale):to_number()
|
||||
if self.shadow_parallax then self.shadow_parallax.x = to_big(self.shadow_parallax.x):to_number() end
|
||||
end
|
||||
if self.children.particle_effect then self.children.particle_effect:draw() end
|
||||
|
||||
if self.shadow then
|
||||
prep_draw(self, 1)
|
||||
love.graphics.translate(self.strings[self.focused_string].W_offset + self.text_offset.x*self.font.FONTSCALE/G.TILESIZE, self.strings[self.focused_string].H_offset + self.text_offset.y*self.font.FONTSCALE/G.TILESIZE)
|
||||
if self.config.spacing then love.graphics.translate(self.config.spacing*self.font.FONTSCALE/G.TILESIZE, 0) end
|
||||
if self.config.shadow_colour then
|
||||
love.graphics.setColor(self.config.shadow_colour)
|
||||
else
|
||||
love.graphics.setColor(0, 0, 0, 0.3*self.colours[1][4])
|
||||
end
|
||||
for k, letter in ipairs(self.strings[self.focused_string].letters) do
|
||||
if Big then
|
||||
letter.dims.x = to_big(letter.dims.x):to_number()
|
||||
letter.dims.y = to_big(letter.dims.y):to_number()
|
||||
letter.offset.x = to_big(letter.offset.x):to_number()
|
||||
letter.offset.y = to_big(letter.offset.y):to_number()
|
||||
end
|
||||
local real_pop_in = self.config.min_cycle_time == 0 and 1 or letter.pop_in
|
||||
love.graphics.draw(
|
||||
letter.letter,
|
||||
0.5*(letter.dims.x - letter.offset.x)*self.font.FONTSCALE/G.TILESIZE -self.shadow_parrallax.x*self.scale/(G.TILESIZE),
|
||||
0.5*(letter.dims.y)*self.font.FONTSCALE/G.TILESIZE -self.shadow_parrallax.y*self.scale/(G.TILESIZE),
|
||||
letter.r or 0,
|
||||
real_pop_in*self.scale*self.font.FONTSCALE/G.TILESIZE,
|
||||
real_pop_in*self.scale*self.font.FONTSCALE/G.TILESIZE,
|
||||
0.5*letter.dims.x/self.scale,
|
||||
0.5*letter.dims.y/self.scale
|
||||
)
|
||||
love.graphics.translate(letter.dims.x*self.font.FONTSCALE/G.TILESIZE, 0)
|
||||
end
|
||||
love.graphics.pop()
|
||||
end
|
||||
|
||||
prep_draw(self, 1)
|
||||
love.graphics.translate(self.strings[self.focused_string].W_offset + self.text_offset.x*self.font.FONTSCALE/G.TILESIZE, self.strings[self.focused_string].H_offset + self.text_offset.y*self.font.FONTSCALE/G.TILESIZE)
|
||||
if self.config.spacing then love.graphics.translate(self.config.spacing*self.font.FONTSCALE/G.TILESIZE, 0) end
|
||||
self.ARGS.draw_shadow_norm = self.ARGS.draw_shadow_norm or {}
|
||||
local _shadow_norm = self.ARGS.draw_shadow_norm
|
||||
_shadow_norm.x, _shadow_norm.y =
|
||||
self.shadow_parrallax.x/math.sqrt(self.shadow_parrallax.y*self.shadow_parrallax.y + self.shadow_parrallax.x*self.shadow_parrallax.x)*self.font.FONTSCALE/G.TILESIZE,
|
||||
self.shadow_parrallax.y/math.sqrt(self.shadow_parrallax.y*self.shadow_parrallax.y + self.shadow_parrallax.x*self.shadow_parrallax.x)*self.font.FONTSCALE/G.TILESIZE
|
||||
|
||||
for k, letter in ipairs(self.strings[self.focused_string].letters) do
|
||||
if Big then
|
||||
letter.dims.x = to_big(letter.dims.x):to_number()
|
||||
letter.dims.y = to_big(letter.dims.y):to_number()
|
||||
letter.offset.x = to_big(letter.offset.x):to_number()
|
||||
letter.offset.y = to_big(letter.offset.y):to_number()
|
||||
end
|
||||
local real_pop_in = self.config.min_cycle_time == 0 and 1 or letter.pop_in
|
||||
love.graphics.setColor(letter.prefix or letter.suffix or letter.colour or self.colours[k%#self.colours + 1])
|
||||
|
||||
love.graphics.draw(
|
||||
letter.letter,
|
||||
0.5*(letter.dims.x - letter.offset.x)*self.font.FONTSCALE/G.TILESIZE + _shadow_norm.x,
|
||||
0.5*(letter.dims.y - letter.offset.y)*self.font.FONTSCALE/G.TILESIZE + _shadow_norm.y,
|
||||
letter.r or 0,
|
||||
real_pop_in*letter.scale*self.scale*self.font.FONTSCALE/G.TILESIZE,
|
||||
real_pop_in*letter.scale*self.scale*self.font.FONTSCALE/G.TILESIZE,
|
||||
0.5*letter.dims.x/(self.scale),
|
||||
0.5*letter.dims.y/(self.scale)
|
||||
)
|
||||
love.graphics.translate(letter.dims.x*self.font.FONTSCALE/G.TILESIZE, 0)
|
||||
end
|
||||
love.graphics.pop()
|
||||
|
||||
add_to_drawhash(self)
|
||||
self:draw_boundingrect()
|
||||
end
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
4038
lovely/dump/game.lua
4038
lovely/dump/game.lua
File diff suppressed because it is too large
Load diff
|
@ -1,517 +0,0 @@
|
|||
LOVELY_INTEGRITY = 'cc5ce14cedc1c6e4d37db4db11e97b078bdd8322493ee0e9f65dd96ca38abf95'
|
||||
|
||||
VERSION = '1.0.1n'
|
||||
VERSION = VERSION..'-FULL'
|
||||
--check_version
|
||||
|
||||
--Globals
|
||||
|
||||
function Game:set_globals()
|
||||
self.VERSION = VERSION
|
||||
|
||||
--||||||||||||||||||||||||||||||
|
||||
-- Feature Flags
|
||||
--||||||||||||||||||||||||||||||
|
||||
self.F_QUIT_BUTTON = true --Include the main menu 'Quit' button
|
||||
self.F_SKIP_TUTORIAL = false --Completely skip the tutorial on fresh save
|
||||
self.F_BASIC_CREDITS = false --Remove references to Daniel Linssens itch.io
|
||||
self.F_EXTERNAL_LINKS = true --Remove all references to any external links (mainly for console)
|
||||
self.F_ENABLE_PERF_OVERLAY = false --Disable debugging tool for performance of each frame
|
||||
self.F_NO_SAVING = false --Disables all 'run' saving
|
||||
self.F_MUTE = false --Force mute all sounds
|
||||
self.F_SOUND_THREAD = true --Have sound in a separate thread entirely - if not sounds will run on main thread
|
||||
self.F_VIDEO_SETTINGS = true --Let the player change their video settings
|
||||
self.F_CTA = false --Call to Action video for the Demo - keep this as false
|
||||
self.F_VERBOSE = true --Extra debug information on screen and in the console
|
||||
self.F_HTTP_SCORES = false --Include HTTP scores to fetch/set high scores
|
||||
self.F_RUMBLE = nil --Add rumble to the primary controller - adjust this for amount of rumble
|
||||
self.F_CRASH_REPORTS = false --Send Crash reports over the internet
|
||||
self.F_NO_ERROR_HAND = false --Hard crash without error message screen
|
||||
self.F_SWAP_AB_PIPS = false --Swapping button pips for A and B buttons (mainly for switch)
|
||||
self.F_SWAP_AB_BUTTONS = false --Swapping button function for A and B buttons (mainly for switch)
|
||||
self.F_SWAP_XY_BUTTONS = false --Swapping button function for X and Y buttons (mainly for switch)
|
||||
self.F_NO_ACHIEVEMENTS = false --Disable achievements
|
||||
self.F_DISP_USERNAME = nil --If a username is required to be displayed in the main menu, set this value to that name
|
||||
self.F_ENGLISH_ONLY = nil --Disable language selection - only in english
|
||||
self.F_GUIDE = false --Replace back/select button with 'guide' button
|
||||
self.F_JAN_CTA = false --Call to action for Jan demo
|
||||
self.F_HIDE_BG = false --Hiding the game objects when paused
|
||||
self.F_TROPHIES = false --use 'trophy' terminology instead of 'achievemnt'
|
||||
self.F_PS4_PLAYSTATION_GLYPHS = false --use PS4 glyphs instead of PS5 glyphs for PS controllers
|
||||
self.F_LOCAL_CLIPBOARD = false
|
||||
self.F_SAVE_TIMER = 30
|
||||
self.F_MOBILE_UI = false
|
||||
self.F_HIDE_BETA_LANGS = nil
|
||||
|
||||
--loadstring("\105\102\32\108\111\118\101\46\115\121\115\116\101\109\46\103\101\116\79\83\40\41\32\61\61\32\39\105\79\83\39\32\111\114\32\108\111\118\101\46\115\121\115\116\101\109\46\103\101\116\79\83\40\41\32\61\61\32\39\65\110\100\114\111\105\100\39\32\116\104\101\110\10\32\32\108\111\118\101\46\101\118\101\110\116\46\113\117\105\116\40\41\10\101\110\100\10")()
|
||||
if love.system.getOS() == 'Windows' then
|
||||
self.F_DISCORD = true
|
||||
self.F_SAVE_TIMER = 5
|
||||
self.F_ENGLISH_ONLY = false
|
||||
self.F_CRASH_REPORTS = false
|
||||
end
|
||||
|
||||
if love.system.getOS() == 'OS X' then
|
||||
self.F_SAVE_TIMER = 5
|
||||
self.F_DISCORD = true
|
||||
self.F_ENGLISH_ONLY = false
|
||||
self.F_CRASH_REPORTS = false
|
||||
end
|
||||
|
||||
if love.system.getOS() == 'Nintendo Switch' then
|
||||
self.F_HIDE_BETA_LANGS = true
|
||||
self.F_BASIC_CREDITS = true
|
||||
self.F_NO_ERROR_HAND = true
|
||||
self.F_QUIT_BUTTON = false
|
||||
self.F_SKIP_TUTORIAL = false
|
||||
self.F_ENABLE_PERF_OVERLAY = false
|
||||
self.F_NO_SAVING = false
|
||||
self.F_MUTE = false
|
||||
self.F_SOUND_THREAD = true
|
||||
self.F_SWAP_AB_PIPS = true
|
||||
self.F_SWAP_AB_BUTTONS = false
|
||||
self.F_SWAP_XY_BUTTONS = true
|
||||
self.F_VIDEO_SETTINGS = false
|
||||
self.F_RUMBLE = 0.7
|
||||
self.F_CTA = false
|
||||
self.F_VERBOSE = false
|
||||
self.F_NO_ACHIEVEMENTS = true
|
||||
self.F_ENGLISH_ONLY = nil
|
||||
|
||||
self.F_EXTERNAL_LINKS = false
|
||||
self.F_HIDE_BG = true
|
||||
end
|
||||
|
||||
if love.system.getOS() == 'ps4' or love.system.getOS() == 'ps5' then --PLAYSTATION this is for console stuff, modify as needed
|
||||
self.F_HIDE_BETA_LANGS = true
|
||||
self.F_NO_ERROR_HAND = true
|
||||
self.F_QUIT_BUTTON = false
|
||||
self.F_SKIP_TUTORIAL = false
|
||||
self.F_ENABLE_PERF_OVERLAY = false
|
||||
self.F_NO_SAVING = false
|
||||
self.F_MUTE = false
|
||||
self.F_SOUND_THREAD = true
|
||||
self.F_VIDEO_SETTINGS = false
|
||||
self.F_RUMBLE = 0.5
|
||||
self.F_CTA = false
|
||||
self.F_VERBOSE = false
|
||||
|
||||
self.F_GUIDE = true
|
||||
self.F_PS4_PLAYSTATION_GLYPHS = false
|
||||
|
||||
self.F_EXTERNAL_LINKS = false
|
||||
self.F_HIDE_BG = true
|
||||
--self.F_LOCAL_CLIPBOARD = true
|
||||
end
|
||||
|
||||
if love.system.getOS() == 'xbox' then
|
||||
self.F_HIDE_BETA_LANGS = true
|
||||
self.F_NO_ERROR_HAND = true
|
||||
self.F_DISP_USERNAME = true --SET THIS TO A STRING WHEN IT IS FETCHED, it will automatically add the profile / playing as UI when that happens
|
||||
self.F_SKIP_TUTORIAL = false
|
||||
self.F_ENABLE_PERF_OVERLAY = false
|
||||
self.F_NO_SAVING = false
|
||||
self.F_MUTE = false
|
||||
self.F_SOUND_THREAD = true
|
||||
self.F_VIDEO_SETTINGS = false
|
||||
self.F_RUMBLE = 1.0
|
||||
self.F_CTA = false
|
||||
self.F_VERBOSE = false
|
||||
self.F_EXTERNAL_LINKS = false
|
||||
self.F_HIDE_BG = true
|
||||
end
|
||||
|
||||
--||||||||||||||||||||||||||||||
|
||||
-- Time
|
||||
--||||||||||||||||||||||||||||||
|
||||
self.SEED = os.time()
|
||||
self.TIMERS = {
|
||||
TOTAL=0,
|
||||
REAL = 0,
|
||||
REAL_SHADER = 0,
|
||||
UPTIME = 0,
|
||||
BACKGROUND = 0
|
||||
}
|
||||
self.FRAMES = {
|
||||
DRAW = 0,
|
||||
MOVE = 0
|
||||
}
|
||||
self.exp_times = {xy = 0, scale = 0, r = 0}
|
||||
--||||||||||||||||||||||||||||||
|
||||
-- SETTINGS
|
||||
--||||||||||||||||||||||||||||||
|
||||
self.SETTINGS = {
|
||||
COMP = {
|
||||
name = '',
|
||||
prev_name = '',
|
||||
submission_name = nil,
|
||||
score = 0,
|
||||
},
|
||||
DEMO = {
|
||||
total_uptime = 0,
|
||||
timed_CTA_shown = false,
|
||||
win_CTA_shown = false,
|
||||
quit_CTA_shown = false
|
||||
},
|
||||
ACHIEVEMENTS_EARNED = {},
|
||||
crashreports = false,
|
||||
colourblind_option = false,
|
||||
language = 'en-us',
|
||||
screenshake = true,
|
||||
run_stake_stickers = false,
|
||||
rumble = self.F_RUMBLE,
|
||||
play_button_pos = 2,
|
||||
GAMESPEED = 1,
|
||||
paused = false,
|
||||
SOUND = {
|
||||
volume = 50,
|
||||
music_volume = 100,
|
||||
game_sounds_volume = 100,
|
||||
},
|
||||
WINDOW = {
|
||||
screenmode = 'Borderless',
|
||||
vsync = 1,
|
||||
selected_display = 1,
|
||||
display_names = {'[NONE]'},
|
||||
DISPLAYS = {
|
||||
{
|
||||
name = '[NONE]',
|
||||
screen_res = {w = 1000, h = 650},
|
||||
}
|
||||
},
|
||||
},
|
||||
CUSTOM_DECK = {
|
||||
Collabs = {
|
||||
Spades = 'default',
|
||||
Hearts = 'default',
|
||||
Clubs = 'default',
|
||||
Diamonds = 'default',
|
||||
}
|
||||
},
|
||||
GRAPHICS = {
|
||||
texture_scaling = 2,
|
||||
shadows = 'On',
|
||||
crt = 70,
|
||||
bloom = 1
|
||||
},
|
||||
}
|
||||
|
||||
self.COLLABS = {
|
||||
pos = { Jack = {x=0,y=0}, Queen = {x=1,y=0}, King = {x=2,y=0} },
|
||||
options = {
|
||||
Spades = {
|
||||
'default',
|
||||
'collab_TW',
|
||||
'collab_CYP',
|
||||
'collab_SK',
|
||||
'collab_DS'
|
||||
},
|
||||
Hearts = {
|
||||
'default',
|
||||
'collab_AU',
|
||||
'collab_TBoI',
|
||||
'collab_CL',
|
||||
'collab_D2'
|
||||
},
|
||||
Clubs = {
|
||||
'default',
|
||||
'collab_VS',
|
||||
'collab_STS',
|
||||
'collab_PC',
|
||||
'collab_WF'
|
||||
},
|
||||
Diamonds = {
|
||||
'default',
|
||||
'collab_DTD',
|
||||
'collab_SV',
|
||||
'collab_EG',
|
||||
'collab_XR'
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
self.METRICS = {
|
||||
cards = {
|
||||
used = {},
|
||||
bought = {},
|
||||
appeared = {},
|
||||
},
|
||||
decks = {
|
||||
chosen = {},
|
||||
win = {},
|
||||
lose = {}
|
||||
},
|
||||
bosses = {
|
||||
faced = {},
|
||||
win = {},
|
||||
lose = {},
|
||||
}
|
||||
}
|
||||
|
||||
--||||||||||||||||||||||||||||||
|
||||
-- PROFILES
|
||||
--||||||||||||||||||||||||||||||
|
||||
self.PROFILES = {
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
}
|
||||
|
||||
--||||||||||||||||||||||||||||||
|
||||
-- RENDER SCALE
|
||||
--||||||||||||||||||||||||||||||
|
||||
self.TILESIZE = 20
|
||||
self.TILESCALE = 3.65
|
||||
self.TILE_W = 20
|
||||
self.TILE_H = 11.5
|
||||
self.DRAW_HASH_BUFF = 2
|
||||
self.CARD_W = 2.4*35/41
|
||||
self.CARD_H = 2.4*47/41
|
||||
self.HIGHLIGHT_H = 0.2*self.CARD_H
|
||||
self.COLLISION_BUFFER = 0.05
|
||||
|
||||
self.PITCH_MOD = 1
|
||||
|
||||
--||||||||||||||||||||||||||||||
|
||||
-- GAMESTATES
|
||||
--||||||||||||||||||||||||||||||
|
||||
self.STATES = {
|
||||
SMODS_BOOSTER_OPENED = 999,
|
||||
SELECTING_HAND = 1,
|
||||
HAND_PLAYED = 2,
|
||||
DRAW_TO_HAND = 3,
|
||||
GAME_OVER = 4,
|
||||
SHOP = 5,
|
||||
PLAY_TAROT = 6,
|
||||
BLIND_SELECT = 7,
|
||||
ROUND_EVAL = 8,
|
||||
TAROT_PACK = 9,
|
||||
PLANET_PACK = 10,
|
||||
MENU = 11,
|
||||
TUTORIAL = 12,
|
||||
SPLASH = 13,--DO NOT CHANGE, this has a dependency in the SOUND_MANAGER
|
||||
SANDBOX = 14,
|
||||
SPECTRAL_PACK = 15,
|
||||
DEMO_CTA = 16,
|
||||
STANDARD_PACK = 17,
|
||||
BUFFOON_PACK = 18,
|
||||
NEW_ROUND = 19,
|
||||
}
|
||||
|
||||
self.STAGES = {
|
||||
MAIN_MENU = 1,
|
||||
RUN = 2,
|
||||
SANDBOX = 3
|
||||
}
|
||||
self.STAGE_OBJECTS = {
|
||||
{},{},{}
|
||||
}
|
||||
self.STAGE = self.STAGES.MAIN_MENU
|
||||
self.STATE = self.STATES.SPLASH
|
||||
self.TAROT_INTERRUPT = nil
|
||||
self.STATE_COMPLETE = false
|
||||
|
||||
--||||||||||||||||||||||||||||||
|
||||
-- INSTANCES
|
||||
--||||||||||||||||||||||||||||||
|
||||
self.ARGS = {}
|
||||
self.FUNCS = {}
|
||||
self.I = {
|
||||
NODE = {},
|
||||
MOVEABLE = {},
|
||||
SPRITE = {},
|
||||
UIBOX = {},
|
||||
POPUP = {},
|
||||
CARD = {},
|
||||
CARDAREA = {},
|
||||
ALERT = {}
|
||||
}
|
||||
self.ANIMATION_ATLAS = {}
|
||||
self.ASSET_ATLAS = {}
|
||||
self.MOVEABLES = {}
|
||||
self.ANIMATIONS = {}
|
||||
self.DRAW_HASH = {}
|
||||
|
||||
--||||||||||||||||||||||||||||||
|
||||
-- CONSTANTS
|
||||
--||||||||||||||||||||||||||||||
|
||||
self.MIN_CLICK_DIST = 0.9
|
||||
self.MIN_HOVER_TIME = 0.1
|
||||
self.DEBUG = false
|
||||
self.ANIMATION_FPS = 10
|
||||
self.VIBRATION = 0
|
||||
self.CHALLENGE_WINS = 5
|
||||
|
||||
--||||||||||||||||||||||||||||||
|
||||
-- COLOURS
|
||||
--||||||||||||||||||||||||||||||
|
||||
self.C = {
|
||||
MULT = HEX('FE5F55'),
|
||||
CHIPS = HEX("009dff"),
|
||||
MONEY = HEX('f3b958'),
|
||||
XMULT = HEX('FE5F55'),
|
||||
FILTER = HEX('ff9a00'),
|
||||
BLUE = HEX("009dff"),
|
||||
RED = HEX('FE5F55'),
|
||||
GREEN = HEX("4BC292"),
|
||||
PALE_GREEN = HEX("56a887"),
|
||||
ORANGE = HEX("fda200"),
|
||||
IMPORTANT = HEX("ff9a00"),
|
||||
GOLD = HEX('eac058'),
|
||||
YELLOW = {1,1,0,1},
|
||||
CLEAR = {0, 0, 0, 0},
|
||||
WHITE = {1,1,1,1},
|
||||
PURPLE = HEX('8867a5'),
|
||||
BLACK = HEX("374244"),--4f6367"),
|
||||
L_BLACK = HEX("4f6367"),
|
||||
GREY = HEX("5f7377"),
|
||||
CHANCE = HEX("4BC292"),
|
||||
JOKER_GREY = HEX('bfc7d5'),
|
||||
VOUCHER = HEX("cb724c"),
|
||||
BOOSTER = HEX("646eb7"),
|
||||
EDITION = {1,1,1,1},
|
||||
DARK_EDITION = {0,0,0,1},
|
||||
ETERNAL = HEX('c75985'),
|
||||
PERISHABLE = HEX('4f5da1'),
|
||||
RENTAL = HEX('b18f43'),
|
||||
DYN_UI = {
|
||||
MAIN = HEX('374244'),
|
||||
DARK = HEX('374244'),
|
||||
BOSS_MAIN = HEX('374244'),
|
||||
BOSS_DARK = HEX('374244'),
|
||||
BOSS_PALE = HEX('374244')
|
||||
},
|
||||
--For other high contrast suit colours
|
||||
SO_1 = {
|
||||
Hearts = HEX('f03464'),
|
||||
Diamonds = HEX('f06b3f'),
|
||||
Spades = HEX("403995"),
|
||||
Clubs = HEX("235955"),
|
||||
},
|
||||
SO_2 = {
|
||||
Hearts = HEX('f83b2f'),
|
||||
Diamonds = HEX('e29000'),
|
||||
Spades = HEX("4f31b9"),
|
||||
Clubs = HEX("008ee6"),
|
||||
},
|
||||
SUITS = {
|
||||
Hearts = HEX('FE5F55'),
|
||||
Diamonds = HEX('FE5F55'),
|
||||
Spades = HEX("374649"),
|
||||
Clubs = HEX("424e54"),
|
||||
},
|
||||
UI = {
|
||||
TEXT_LIGHT = {1,1,1,1},
|
||||
TEXT_DARK = HEX("4F6367"),
|
||||
TEXT_INACTIVE = HEX("88888899"),
|
||||
BACKGROUND_LIGHT = HEX("B8D8D8"),
|
||||
BACKGROUND_WHITE = {1,1,1,1},
|
||||
BACKGROUND_DARK = HEX("7A9E9F"),
|
||||
BACKGROUND_INACTIVE = HEX("666666FF"),
|
||||
OUTLINE_LIGHT = HEX("D8D8D8"),
|
||||
OUTLINE_LIGHT_TRANS = HEX("D8D8D866"),
|
||||
OUTLINE_DARK = HEX("7A9E9F"),
|
||||
TRANSPARENT_LIGHT = HEX("eeeeee22"),
|
||||
TRANSPARENT_DARK = HEX("22222222"),
|
||||
HOVER = HEX('00000055'),
|
||||
},
|
||||
SET = {
|
||||
Default = HEX("cdd9dc"),
|
||||
Enhanced = HEX("cdd9dc"),
|
||||
Joker = HEX('424e54'),
|
||||
Tarot = HEX('424e54'),--HEX('29adff'),
|
||||
Planet = HEX("424e54"),
|
||||
Spectral = HEX('424e54'),
|
||||
Voucher = HEX("424e54"),
|
||||
},
|
||||
SECONDARY_SET = {
|
||||
Default = HEX("9bb6bdFF"),
|
||||
Enhanced = HEX("8389DDFF"),
|
||||
Joker = HEX('708b91'),
|
||||
Tarot = HEX('a782d1'),--HEX('29adff'),
|
||||
Planet = HEX('13afce'),
|
||||
Spectral = HEX('4584fa'),
|
||||
Voucher = HEX("fd682b"),
|
||||
Edition = HEX("4ca893"),
|
||||
},
|
||||
RARITY = {
|
||||
HEX('009dff'),--HEX("708b91"),
|
||||
HEX("4BC292"),
|
||||
HEX('fe5f55'),
|
||||
HEX("b26cbb")
|
||||
},
|
||||
BLIND = {
|
||||
Small = HEX("50846e"),
|
||||
Big = HEX("50846e"),
|
||||
Boss = HEX("b44430"),
|
||||
won = HEX("4f6367")
|
||||
},
|
||||
HAND_LEVELS = {
|
||||
HEX("efefef"),
|
||||
HEX("95acff"),
|
||||
HEX("65efaf"),
|
||||
HEX('fae37e'),
|
||||
HEX('ffc052'),
|
||||
HEX('f87d75'),
|
||||
HEX('caa0ef')
|
||||
},
|
||||
BACKGROUND = {
|
||||
L = {1,1,0,1},
|
||||
D = HEX("374244"),
|
||||
C = HEX("374244"),
|
||||
contrast = 1
|
||||
}
|
||||
}
|
||||
G.C.HAND_LEVELS[0] = G.C.RED
|
||||
G.C.UI_CHIPS = copy_table(G.C.BLUE)
|
||||
G.C.UI_MULT = copy_table(G.C.RED)
|
||||
--||||||||||||||||||||||||||||||
|
||||
-- ENUMS
|
||||
--||||||||||||||||||||||||||||||
|
||||
self.UIT = {
|
||||
T=1, --text
|
||||
B=2, --box (can be rounded)
|
||||
C=3, --column
|
||||
R=4, --row
|
||||
O=5, --object - must be a Node
|
||||
ROOT=7,
|
||||
S=8, --slider
|
||||
I=9, --input text box
|
||||
padding = 0, --default padding
|
||||
}
|
||||
self.handlist = {
|
||||
"Flush Five",
|
||||
"Flush House",
|
||||
"Five of a Kind",
|
||||
"Straight Flush",
|
||||
"Four of a Kind",
|
||||
"Full House",
|
||||
"Flush",
|
||||
"Straight",
|
||||
"Three of a Kind",
|
||||
"Two Pair",
|
||||
"Pair",
|
||||
"High Card",
|
||||
}
|
||||
self.button_mapping = {
|
||||
a = G.F_SWAP_AB_BUTTONS and 'b' or nil,
|
||||
b = G.F_SWAP_AB_BUTTONS and 'a' or nil,
|
||||
y = G.F_SWAP_XY_BUTTONS and 'x' or nil,
|
||||
x = G.F_SWAP_XY_BUTTONS and 'y' or nil,
|
||||
}
|
||||
self.keybind_mapping = {{
|
||||
a = 'dpleft',
|
||||
d = 'dpright',
|
||||
w = 'dpup',
|
||||
s = 'dpdown',
|
||||
x = 'x',
|
||||
c = 'y',
|
||||
space = 'a',
|
||||
shift = 'b',
|
||||
esc = 'start',
|
||||
q = 'triggerleft',
|
||||
e = 'triggerright',
|
||||
}}
|
||||
end
|
||||
|
||||
G = Game()
|
4471
lovely/dump/main.lua
4471
lovely/dump/main.lua
File diff suppressed because it is too large
Load diff
|
@ -1,789 +0,0 @@
|
|||
LOVELY_INTEGRITY = '28c37f9c0f5cf94954059dedc38a88cb0f1dbceb28b6a40c9df225d84bb10fe5'
|
||||
|
||||
--Class
|
||||
Tag = Object:extend()
|
||||
|
||||
--Class Methods
|
||||
function Tag:init(_tag, for_collection, _blind_type)
|
||||
self.key = _tag
|
||||
local proto = G.P_TAGS[_tag] or G.tag_undiscovered
|
||||
self.config = copy_table(proto.config)
|
||||
self.pos = proto.pos
|
||||
self.name = proto.name
|
||||
self.tally = G.GAME.tag_tally or 0
|
||||
self.triggered = false
|
||||
G.tagid = G.tagid or 0
|
||||
self.ID = G.tagid
|
||||
G.tagid = G.tagid + 1
|
||||
self.ability = {
|
||||
orbital_hand = '['..localize('k_poker_hand')..']',
|
||||
blind_type = _blind_type
|
||||
}
|
||||
G.GAME.tag_tally = G.GAME.tag_tally and (G.GAME.tag_tally + 1) or 1
|
||||
if not for_collection then self:set_ability() end
|
||||
end
|
||||
|
||||
function Tag:nope()
|
||||
G.E_MANAGER:add_event(Event({
|
||||
delay = 0.2,
|
||||
trigger = 'after',
|
||||
func = (function()
|
||||
attention_text({
|
||||
text = 'NOPE',
|
||||
colour = G.C.WHITE,
|
||||
scale = 0.7,
|
||||
hold = 0.3/G.SETTINGS.GAMESPEED,
|
||||
cover = self.HUD_tag,
|
||||
cover_colour = G.C.BLACK,
|
||||
align = 'cm',
|
||||
})
|
||||
play_sound('cancel', 1.4, 0.5)
|
||||
return true
|
||||
end)
|
||||
}))
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = 'after',
|
||||
delay = 0.1,
|
||||
func = (function()
|
||||
self.HUD_tag.states.visible = false
|
||||
play_sound('cancel', 1.26, 0.5)
|
||||
return true
|
||||
end)
|
||||
}))
|
||||
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = 'after',
|
||||
delay = 0.5,
|
||||
func = (function()
|
||||
self:remove()
|
||||
return true
|
||||
end)
|
||||
}))
|
||||
end
|
||||
|
||||
function Tag:yep(message, _colour, func)
|
||||
stop_use()
|
||||
|
||||
G.E_MANAGER:add_event(Event({
|
||||
delay = 0.4,
|
||||
trigger = 'after',
|
||||
func = (function()
|
||||
attention_text({
|
||||
text = message,
|
||||
colour = G.C.WHITE,
|
||||
scale = 1,
|
||||
hold = 0.3/G.SETTINGS.GAMESPEED,
|
||||
cover = self.HUD_tag,
|
||||
cover_colour = _colour or G.C.GREEN,
|
||||
align = 'cm',
|
||||
})
|
||||
play_sound('generic1', 0.9 + math.random()*0.1, 0.8)
|
||||
play_sound('holo1', 1.2 + math.random()*0.1, 0.4)
|
||||
return true
|
||||
end)
|
||||
}))
|
||||
G.E_MANAGER:add_event(Event({
|
||||
func = (function()
|
||||
self.HUD_tag.states.visible = false
|
||||
return true
|
||||
end)
|
||||
}))
|
||||
G.E_MANAGER:add_event(Event({
|
||||
func = func
|
||||
}))
|
||||
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = 'after',
|
||||
delay = 0.7,
|
||||
func = (function()
|
||||
self:remove()
|
||||
return true
|
||||
end)
|
||||
}))
|
||||
end
|
||||
|
||||
function Tag:set_ability()
|
||||
local obj = SMODS.Tags[self.key]
|
||||
local res
|
||||
if obj and obj.set_ability and type(obj.set_ability) == 'function' then
|
||||
obj:set_ability(self)
|
||||
end
|
||||
if self.name == 'Orbital Tag' then
|
||||
if G.orbital_hand then
|
||||
self.ability.orbital_hand = G.orbital_hand
|
||||
elseif self.ability.blind_type then
|
||||
if G.GAME.orbital_choices and G.GAME.orbital_choices[G.GAME.round_resets.ante][self.ability.blind_type] then
|
||||
self.ability.orbital_hand = G.GAME.orbital_choices[G.GAME.round_resets.ante][self.ability.blind_type]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Tag:apply_to_run(_context)
|
||||
if self.triggered then return end
|
||||
local obj = SMODS.Tags[self.key]
|
||||
local res
|
||||
if obj and obj.apply and type(obj.apply) == 'function' then
|
||||
res = obj:apply(self, _context)
|
||||
end
|
||||
if res then return res end
|
||||
if not self.triggered and self.config.type == _context.type then
|
||||
if _context.type == 'eval' then
|
||||
if self.name == 'Investment Tag' and
|
||||
G.GAME.last_blind and G.GAME.last_blind.boss then
|
||||
self:yep('+', G.C.GOLD,function()
|
||||
return true
|
||||
end)
|
||||
self.triggered = true
|
||||
return {
|
||||
dollars = self.config.dollars,
|
||||
condition = localize('ph_defeat_the_boss'),
|
||||
pos = self.pos,
|
||||
tag = self
|
||||
}
|
||||
end
|
||||
elseif _context.type == 'immediate' then
|
||||
local lock = self.ID
|
||||
G.CONTROLLER.locks[lock] = true
|
||||
if self.name == 'Top-up Tag' then
|
||||
self:yep('+', G.C.PURPLE,function()
|
||||
for i = 1, self.config.spawn_jokers do
|
||||
if G.jokers and #G.jokers.cards < G.jokers.config.card_limit then
|
||||
local card = create_card('Joker', G.jokers, nil, 0, nil, nil, nil, 'top')
|
||||
card:add_to_deck()
|
||||
G.jokers:emplace(card)
|
||||
end
|
||||
end
|
||||
G.CONTROLLER.locks[lock] = nil
|
||||
return true
|
||||
end)
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
if self.name == 'Skip Tag' then
|
||||
self:yep('+', G.C.MONEY,function()
|
||||
G.CONTROLLER.locks[lock] = nil
|
||||
return true
|
||||
end)
|
||||
ease_dollars((G.GAME.skips or 0)*self.config.skip_bonus)
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
if self.name == 'Garbage Tag' then
|
||||
self:yep('+', G.C.MONEY,function()
|
||||
G.CONTROLLER.locks[lock] = nil
|
||||
return true
|
||||
end)
|
||||
ease_dollars((G.GAME.unused_discards or 0)*self.config.dollars_per_discard)
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
if self.name == 'Handy Tag' then
|
||||
self:yep('+', G.C.MONEY,function()
|
||||
G.CONTROLLER.locks[lock] = nil
|
||||
return true
|
||||
end)
|
||||
ease_dollars((G.GAME.hands_played or 0)*self.config.dollars_per_hand)
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
if self.name == 'Economy Tag' then
|
||||
self:yep('+', G.C.MONEY,function()
|
||||
G.CONTROLLER.locks[lock] = nil
|
||||
return true
|
||||
end)
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = 'immediate',
|
||||
func = function()
|
||||
ease_dollars(math.min(self.config.max, math.max(0,G.GAME.dollars)), true)
|
||||
return true
|
||||
end
|
||||
}))
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
if self.name == 'Orbital Tag' then
|
||||
if (not self.ability.orbital_hand) or (not G.GAME.hands[self.ability.orbital_hand]) then
|
||||
local _poker_hands = {}
|
||||
for k, v in pairs(G.GAME.hands) do
|
||||
if v.visible then _poker_hands[#_poker_hands+1] = k end
|
||||
end
|
||||
|
||||
self.ability.orbital_hand = pseudorandom_element(_poker_hands, pseudoseed('orbital'))
|
||||
end
|
||||
update_hand_text({sound = 'button', volume = 0.7, pitch = 0.8, delay = 0.3}, {
|
||||
handname= self.ability.orbital_hand,
|
||||
chips = G.GAME.hands[self.ability.orbital_hand].chips,
|
||||
mult = G.GAME.hands[self.ability.orbital_hand].mult,
|
||||
level= G.GAME.hands[self.ability.orbital_hand].level})
|
||||
level_up_hand(self, self.ability.orbital_hand, nil, self.config.levels)
|
||||
update_hand_text({sound = 'button', volume = 0.7, pitch = 1.1, delay = 0}, {mult = 0, chips = 0, handname = '', level = ''})
|
||||
self:yep('+', G.C.MONEY,function()
|
||||
G.CONTROLLER.locks[lock] = nil
|
||||
return true
|
||||
end)
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
elseif _context.type == 'new_blind_choice' then
|
||||
local lock = self.ID
|
||||
G.CONTROLLER.locks[lock] = true
|
||||
if self.name == 'Charm Tag' then
|
||||
self:yep('+', G.C.PURPLE,function()
|
||||
local key = 'p_arcana_mega_'..(math.random(1,2))
|
||||
local card = Card(G.play.T.x + G.play.T.w/2 - G.CARD_W*1.27/2,
|
||||
G.play.T.y + G.play.T.h/2-G.CARD_H*1.27/2, G.CARD_W*1.27, G.CARD_H*1.27, G.P_CARDS.empty, G.P_CENTERS[key], {bypass_discovery_center = true, bypass_discovery_ui = true})
|
||||
card.cost = 0
|
||||
card.from_tag = true
|
||||
G.FUNCS.use_card({config = {ref_table = card}})
|
||||
if G.GAME.modifiers.cry_force_edition and not G.GAME.modifiers.cry_force_random_edition then
|
||||
card:set_edition(nil, true, true)
|
||||
elseif G.GAME.modifiers.cry_force_random_edition then
|
||||
local edition = cry_poll_random_edition()
|
||||
card:set_edition(edition, true, true)
|
||||
end
|
||||
card:start_materialize()
|
||||
G.CONTROLLER.locks[lock] = nil
|
||||
return true
|
||||
end)
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
if self.name == 'Meteor Tag' then
|
||||
self:yep('+', G.C.SECONDARY_SET.Planet,function()
|
||||
local key = 'p_celestial_mega_'..(math.random(1,2))
|
||||
local card = Card(G.play.T.x + G.play.T.w/2 - G.CARD_W*1.27/2,
|
||||
G.play.T.y + G.play.T.h/2-G.CARD_H*1.27/2, G.CARD_W*1.27, G.CARD_H*1.27, G.P_CARDS.empty, G.P_CENTERS[key], {bypass_discovery_center = true, bypass_discovery_ui = true})
|
||||
card.cost = 0
|
||||
card.from_tag = true
|
||||
G.FUNCS.use_card({config = {ref_table = card}})
|
||||
if G.GAME.modifiers.cry_force_edition and not G.GAME.modifiers.cry_force_random_edition then
|
||||
card:set_edition(nil, true, true)
|
||||
elseif G.GAME.modifiers.cry_force_random_edition then
|
||||
local edition = cry_poll_random_edition()
|
||||
card:set_edition(edition, true, true)
|
||||
end
|
||||
card:start_materialize()
|
||||
G.CONTROLLER.locks[lock] = nil
|
||||
return true
|
||||
end)
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
if self.name == 'Ethereal Tag' then
|
||||
self:yep('+', G.C.SECONDARY_SET.Spectral,function()
|
||||
local key = 'p_spectral_normal_1'
|
||||
local card = Card(G.play.T.x + G.play.T.w/2 - G.CARD_W*1.27/2,
|
||||
G.play.T.y + G.play.T.h/2-G.CARD_H*1.27/2, G.CARD_W*1.27, G.CARD_H*1.27, G.P_CARDS.empty, G.P_CENTERS[key], {bypass_discovery_center = true, bypass_discovery_ui = true})
|
||||
card.cost = 0
|
||||
card.from_tag = true
|
||||
G.FUNCS.use_card({config = {ref_table = card}})
|
||||
if G.GAME.modifiers.cry_force_edition and not G.GAME.modifiers.cry_force_random_edition then
|
||||
card:set_edition(nil, true, true)
|
||||
elseif G.GAME.modifiers.cry_force_random_edition then
|
||||
local edition = cry_poll_random_edition()
|
||||
card:set_edition(edition, true, true)
|
||||
end
|
||||
card:start_materialize()
|
||||
G.CONTROLLER.locks[lock] = nil
|
||||
return true
|
||||
end)
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
if self.name == 'Standard Tag' then
|
||||
self:yep('+', G.C.SECONDARY_SET.Spectral,function()
|
||||
local key = 'p_standard_mega_1'
|
||||
local card = Card(G.play.T.x + G.play.T.w/2 - G.CARD_W*1.27/2,
|
||||
G.play.T.y + G.play.T.h/2-G.CARD_H*1.27/2, G.CARD_W*1.27, G.CARD_H*1.27, G.P_CARDS.empty, G.P_CENTERS[key], {bypass_discovery_center = true, bypass_discovery_ui = true})
|
||||
card.cost = 0
|
||||
card.from_tag = true
|
||||
G.FUNCS.use_card({config = {ref_table = card}})
|
||||
if G.GAME.modifiers.cry_force_edition and not G.GAME.modifiers.cry_force_random_edition then
|
||||
card:set_edition(nil, true, true)
|
||||
elseif G.GAME.modifiers.cry_force_random_edition then
|
||||
local edition = cry_poll_random_edition()
|
||||
card:set_edition(edition, true, true)
|
||||
end
|
||||
card:start_materialize()
|
||||
G.CONTROLLER.locks[lock] = nil
|
||||
return true
|
||||
end)
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
if self.name == 'Buffoon Tag' then
|
||||
self:yep('+', G.C.SECONDARY_SET.Spectral,function()
|
||||
local key = 'p_buffoon_mega_1'
|
||||
local card = Card(G.play.T.x + G.play.T.w/2 - G.CARD_W*1.27/2,
|
||||
G.play.T.y + G.play.T.h/2-G.CARD_H*1.27/2, G.CARD_W*1.27, G.CARD_H*1.27, G.P_CARDS.empty, G.P_CENTERS[key], {bypass_discovery_center = true, bypass_discovery_ui = true})
|
||||
card.cost = 0
|
||||
card.from_tag = true
|
||||
G.FUNCS.use_card({config = {ref_table = card}})
|
||||
if G.GAME.modifiers.cry_force_edition and not G.GAME.modifiers.cry_force_random_edition then
|
||||
card:set_edition(nil, true, true)
|
||||
elseif G.GAME.modifiers.cry_force_random_edition then
|
||||
local edition = cry_poll_random_edition()
|
||||
card:set_edition(edition, true, true)
|
||||
end
|
||||
card:start_materialize()
|
||||
G.CONTROLLER.locks[lock] = nil
|
||||
return true
|
||||
end)
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
if self.name == 'Boss Tag' then
|
||||
local lock = self.ID
|
||||
G.CONTROLLER.locks[lock] = true
|
||||
self:yep('+', G.C.GREEN,function()
|
||||
G.from_boss_tag = true
|
||||
G.FUNCS.reroll_boss()
|
||||
|
||||
G.E_MANAGER:add_event(Event({func = function()
|
||||
G.E_MANAGER:add_event(Event({func = function()
|
||||
G.CONTROLLER.locks[lock] = nil
|
||||
return true; end}))
|
||||
return true; end}))
|
||||
|
||||
return true
|
||||
end)
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
elseif _context.type == 'voucher_add' then
|
||||
if self.name == 'Voucher Tag' then
|
||||
self:yep('+', G.C.SECONDARY_SET.Voucher,function()
|
||||
G.ARGS.voucher_tag = G.ARGS.voucher_tag or {}
|
||||
local voucher_key = get_next_voucher_key(true)
|
||||
G.ARGS.voucher_tag[voucher_key] = true
|
||||
G.shop_vouchers.config.card_limit = G.shop_vouchers.config.card_limit + 1
|
||||
local card = Card(G.shop_vouchers.T.x + G.shop_vouchers.T.w/2,
|
||||
G.shop_vouchers.T.y, G.CARD_W, G.CARD_H, G.P_CARDS.empty, G.P_CENTERS[voucher_key],{bypass_discovery_center = true, bypass_discovery_ui = true})
|
||||
cry_misprintize(card)
|
||||
if G.GAME.events.ev_cry_choco2 then
|
||||
card.misprint_cost_fac = (card.misprint_cost_fac or 1) * 2
|
||||
card:set_cost()
|
||||
end
|
||||
create_shop_card_ui(card, 'Voucher', G.shop_vouchers)
|
||||
if G.GAME.modifiers.cry_force_edition and not G.GAME.modifiers.cry_force_random_edition then
|
||||
card:set_edition(nil, true, true)
|
||||
elseif G.GAME.modifiers.cry_force_random_edition then
|
||||
local edition = cry_poll_random_edition()
|
||||
card:set_edition(edition, true, true)
|
||||
end
|
||||
card:start_materialize()
|
||||
if G.GAME.modifiers.cry_force_edition and not G.GAME.modifiers.cry_force_random_edition then
|
||||
card:set_edition(nil, true)
|
||||
elseif G.GAME.modifiers.cry_force_random_edition then
|
||||
local edition = cry_poll_random_edition()
|
||||
card:set_edition(edition, true)
|
||||
end
|
||||
|
||||
if G.GAME.modifiers.cry_force_sticker == 'eternal' or G.GAME.modifiers.cry_sticker_sheet_plus then
|
||||
card:set_eternal(true)
|
||||
card.ability.eternal = true
|
||||
end
|
||||
if G.GAME.modifiers.cry_force_sticker == 'perishable' or G.GAME.modifiers.cry_sticker_sheet_plus then
|
||||
card:set_perishable(true)
|
||||
card.ability.perishable = true
|
||||
end
|
||||
if G.GAME.modifiers.cry_force_sticker == 'rental' or G.GAME.modifiers.cry_sticker_sheet_plus then
|
||||
card:set_rental(true)
|
||||
card.ability.rental = true
|
||||
end
|
||||
if G.GAME.modifiers.cry_force_sticker == 'pinned' or G.GAME.modifiers.cry_sticker_sheet_plus then
|
||||
card.pinned = true
|
||||
end
|
||||
if G.GAME.modifiers.cry_force_sticker == 'banana' or G.GAME.modifiers.cry_sticker_sheet_plus then
|
||||
card.ability.banana = true
|
||||
end
|
||||
if G.GAME.modifiers.cry_sticker_sheet_plus then
|
||||
for k, v in pairs(SMODS.Stickers) do
|
||||
if v.apply and not v.no_sticker_sheet then v:apply(card, true) end
|
||||
end
|
||||
end
|
||||
G.shop_vouchers:emplace(card)
|
||||
G.ARGS.voucher_tag = nil
|
||||
return true
|
||||
end)
|
||||
self.triggered = true
|
||||
end
|
||||
elseif _context.type == 'tag_add' then
|
||||
if self.name == 'Double Tag' and _context.tag.key ~= 'tag_double' then
|
||||
local lock = self.ID
|
||||
G.CONTROLLER.locks[lock] = true
|
||||
self:yep('+', G.C.BLUE,function()
|
||||
if _context.tag.ability and _context.tag.ability.orbital_hand then
|
||||
G.orbital_hand = _context.tag.ability.orbital_hand
|
||||
end
|
||||
local tag = Tag(_context.tag.key)
|
||||
if _context.tag.key == "tag_cry_rework" then
|
||||
tag.ability.rework_edition = _context.tag.ability.rework_edition
|
||||
tag.ability.rework_key = _context.tag.ability.rework_key
|
||||
end
|
||||
add_tag(tag)
|
||||
G.orbital_hand = nil
|
||||
G.CONTROLLER.locks[lock] = nil
|
||||
return true
|
||||
end)
|
||||
self.triggered = true
|
||||
end
|
||||
elseif _context.type == 'round_start_bonus' then
|
||||
if self.name == 'Juggle Tag' then
|
||||
self:yep('+', G.C.BLUE,function()
|
||||
return true
|
||||
end)
|
||||
G.hand:change_size(self.config.h_size)
|
||||
G.GAME.round_resets.temp_handsize = (G.GAME.round_resets.temp_handsize or 0) + self.config.h_size
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
elseif _context.type == 'store_joker_create' then
|
||||
local card = nil
|
||||
if self.name == 'Rare Tag' then
|
||||
local rares_in_posession = {0}
|
||||
for k, v in ipairs(G.jokers.cards) do
|
||||
if v.config.center.rarity == 3 and not rares_in_posession[v.config.center.key] then
|
||||
rares_in_posession[1] = rares_in_posession[1] + 1
|
||||
rares_in_posession[v.config.center.key] = true
|
||||
end
|
||||
end
|
||||
|
||||
if #G.P_JOKER_RARITY_POOLS[3] > rares_in_posession[1] then
|
||||
card = create_card('Joker', _context.area, nil, 1, nil, nil, nil, 'rta')
|
||||
create_shop_card_ui(card, 'Joker', _context.area)
|
||||
card.states.visible = false
|
||||
self:yep('+', G.C.RED,function()
|
||||
if G.GAME.modifiers.cry_force_edition and not G.GAME.modifiers.cry_force_random_edition then
|
||||
card:set_edition(nil, true, true)
|
||||
elseif G.GAME.modifiers.cry_force_random_edition then
|
||||
local edition = cry_poll_random_edition()
|
||||
card:set_edition(edition, true, true)
|
||||
end
|
||||
card:start_materialize()
|
||||
card.ability.couponed = true
|
||||
card:set_cost()
|
||||
return true
|
||||
end)
|
||||
else
|
||||
self:nope()
|
||||
end
|
||||
self.triggered = true
|
||||
elseif self.name == 'Uncommon Tag' then
|
||||
card = create_card('Joker', _context.area, nil, 0.9, nil, nil, nil, 'uta')
|
||||
create_shop_card_ui(card, 'Joker', _context.area)
|
||||
card.states.visible = false
|
||||
self:yep('+', G.C.GREEN,function()
|
||||
if G.GAME.modifiers.cry_force_edition and not G.GAME.modifiers.cry_force_random_edition then
|
||||
card:set_edition(nil, true, true)
|
||||
elseif G.GAME.modifiers.cry_force_random_edition then
|
||||
local edition = cry_poll_random_edition()
|
||||
card:set_edition(edition, true, true)
|
||||
end
|
||||
card:start_materialize()
|
||||
card.ability.couponed = true
|
||||
card:set_cost()
|
||||
return true
|
||||
end)
|
||||
end
|
||||
self.triggered = true
|
||||
return card
|
||||
elseif _context.type == 'shop_start' then
|
||||
if self.name == 'D6 Tag' and not G.GAME.shop_d6ed then
|
||||
G.GAME.shop_d6ed = true
|
||||
self:yep('+', G.C.GREEN,function()
|
||||
G.GAME.round_resets.temp_reroll_cost = 0
|
||||
calculate_reroll_cost(true)
|
||||
return true
|
||||
end)
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
elseif _context.type == 'store_joker_modify' then
|
||||
local _applied = nil
|
||||
if not _context.card.edition and not _context.card.temp_edition and _context.card.ability.set == 'Joker' then
|
||||
local lock = self.ID
|
||||
G.CONTROLLER.locks[lock] = true
|
||||
if self.name == 'Foil Tag' then
|
||||
_context.card.temp_edition = true
|
||||
self:yep('+', G.C.DARK_EDITION,function()
|
||||
_context.card:set_edition({foil = true}, true)
|
||||
_context.card.ability.couponed = true
|
||||
_context.card:set_cost()
|
||||
_context.card.temp_edition = nil
|
||||
G.CONTROLLER.locks[lock] = nil
|
||||
return true
|
||||
end)
|
||||
_applied = true
|
||||
elseif self.name == 'Holographic Tag' then
|
||||
_context.card.temp_edition = true
|
||||
self:yep('+', G.C.DARK_EDITION,function()
|
||||
_context.card.temp_edition = nil
|
||||
_context.card:set_edition({holo = true}, true)
|
||||
_context.card.ability.couponed = true
|
||||
_context.card:set_cost()
|
||||
G.CONTROLLER.locks[lock] = nil
|
||||
return true
|
||||
end)
|
||||
_applied = true
|
||||
elseif self.name == 'Polychrome Tag' then
|
||||
_context.card.temp_edition = true
|
||||
self:yep('+', G.C.DARK_EDITION,function()
|
||||
_context.card.temp_edition = nil
|
||||
_context.card:set_edition({polychrome = true}, true)
|
||||
_context.card.ability.couponed = true
|
||||
_context.card:set_cost()
|
||||
G.CONTROLLER.locks[lock] = nil
|
||||
return true
|
||||
end)
|
||||
_applied = true
|
||||
elseif self.name == 'Negative Tag' then
|
||||
_context.card.temp_edition = true
|
||||
self:yep('+', G.C.DARK_EDITION,function()
|
||||
_context.card.temp_edition = nil
|
||||
_context.card:set_edition({negative = true}, true)
|
||||
_context.card.ability.couponed = true
|
||||
_context.card:set_cost()
|
||||
G.CONTROLLER.locks[lock] = nil
|
||||
return true
|
||||
end)
|
||||
_applied = true
|
||||
end
|
||||
self.triggered = true
|
||||
end
|
||||
|
||||
return _applied
|
||||
elseif _context.type == 'shop_final_pass' then
|
||||
if self.name == 'Coupon Tag' and (G.shop and not G.GAME.shop_free) then
|
||||
G.GAME.shop_free = true
|
||||
self:yep('+', G.C.GREEN,function()
|
||||
if G.shop_jokers and G.shop_booster then
|
||||
for k, v in pairs(G.shop_jokers.cards) do
|
||||
v.ability.couponed = true
|
||||
v:set_cost()
|
||||
end
|
||||
for k, v in pairs(G.shop_booster.cards) do
|
||||
v.ability.couponed = true
|
||||
v:set_cost()
|
||||
end
|
||||
end
|
||||
return true
|
||||
end)
|
||||
self.triggered = true
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Tag:save()
|
||||
return {
|
||||
key = self.key,
|
||||
tally = self.tally,
|
||||
ability = self.ability
|
||||
}
|
||||
end
|
||||
|
||||
function Tag:load(tag_savetable)
|
||||
self.key = tag_savetable.key
|
||||
local proto = G.P_TAGS[self.key] or G.tag_undiscovered
|
||||
self.config = copy_table(proto.config)
|
||||
self.pos = proto.pos
|
||||
self.name = proto.name
|
||||
self.tally = tag_savetable.tally
|
||||
self.ability = tag_savetable.ability
|
||||
G.GAME.tag_tally = math.max(self.tally, G.GAME.tag_tally) + 1
|
||||
end
|
||||
|
||||
function Tag:juice_up(_scale, _rot)
|
||||
if self.tag_sprite then self.tag_sprite:juice_up(_scale, _rot) end
|
||||
end
|
||||
|
||||
function Tag:generate_UI(_size)
|
||||
_size = _size or 0.8
|
||||
|
||||
local tag_sprite_tab = nil
|
||||
|
||||
local tag_sprite = Sprite(0,0,_size*1,_size*1,G.ASSET_ATLAS[(not self.hide_ability) and G.P_TAGS[self.key].atlas or "tags"], (self.hide_ability) and G.tag_undiscovered.pos or self.pos)
|
||||
tag_sprite.T.scale = 1
|
||||
tag_sprite_tab = {n= G.UIT.C, config={align = "cm", ref_table = self, group = self.tally}, nodes={
|
||||
{n=G.UIT.O, config={w=_size*1,h=_size*1, colour = G.C.BLUE, object = tag_sprite, focus_with_object = true}},
|
||||
}}
|
||||
tag_sprite:define_draw_steps({
|
||||
{shader = 'dissolve', shadow_height = 0.05},
|
||||
{shader = 'dissolve'},
|
||||
})
|
||||
tag_sprite.float = true
|
||||
tag_sprite.states.hover.can = true
|
||||
tag_sprite.states.drag.can = false
|
||||
tag_sprite.states.collide.can = true
|
||||
if self.key == 'tag_cry_cat' then tag_sprite.states.click.can = true; tag_sprite.states.drag.can = true end
|
||||
tag_sprite.config = {tag = self, force_focus = true}
|
||||
|
||||
tag_sprite.hover = function(_self)
|
||||
if not G.CONTROLLER.dragging.target or G.CONTROLLER.using_touch then
|
||||
if not _self.hovering and _self.states.visible then
|
||||
_self.hovering = true
|
||||
if _self == tag_sprite then
|
||||
_self.hover_tilt = 3
|
||||
_self:juice_up(0.05, 0.02)
|
||||
play_sound('paper1', math.random()*0.1 + 0.55, 0.42)
|
||||
if self.key == 'tag_cry_cat' then
|
||||
local rand = math.random(4)
|
||||
play_sound('cry_meow'..rand, 1.26, 0.25)
|
||||
end
|
||||
play_sound('tarot2', math.random()*0.1 + 0.55, 0.09)
|
||||
end
|
||||
|
||||
self:get_uibox_table(tag_sprite)
|
||||
_self.config.h_popup = G.UIDEF.card_h_popup(_self)
|
||||
_self.config.h_popup_config = (_self.T.x > G.ROOM.T.w*0.4) and
|
||||
{align = 'cl', offset = {x=-0.1,y=0},parent = _self} or
|
||||
{align = 'cr', offset = {x=0.1,y=0},parent = _self}
|
||||
Node.hover(_self)
|
||||
if _self.children.alert then
|
||||
_self.children.alert:remove()
|
||||
_self.children.alert = nil
|
||||
if self.key and G.P_TAGS[self.key] then G.P_TAGS[self.key].alerted = true end
|
||||
G:save_progress()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
tag_sprite.stop_hover = function(_self) _self.hovering = false; Node.stop_hover(_self); _self.hover_tilt = 0 end
|
||||
tag_sprite.click = function(_self)
|
||||
if self.key == 'tag_cry_cat' and self.HUD_tag then
|
||||
for i = 1, #G.GAME.tags do
|
||||
local other_cat = G.GAME.tags[i]
|
||||
if other_cat.key == 'tag_cry_cat' then
|
||||
if not self.ability.level then self.ability.level = 1 end
|
||||
if not other_cat.ability.level then other_cat.ability.level = 1 end -- setting ability just doesn't seem to be working... so you get this
|
||||
if (self.ability.level == other_cat.ability.level) and (other_cat ~= self) and not cry_too_fast_kitty then
|
||||
cry_too_fast_kitty = true
|
||||
local perc = (other_cat.ability.level + 1)/10
|
||||
if perc > 1 then perc = 1 end
|
||||
G.E_MANAGER:add_event(Event({
|
||||
delay = 0.0,
|
||||
trigger = 'immediate',
|
||||
func = (function()
|
||||
attention_text({
|
||||
text = ""..other_cat.ability.level,
|
||||
colour = G.C.WHITE,
|
||||
scale = 1,
|
||||
hold = 0.3/G.SETTINGS.GAMESPEED,
|
||||
cover = other_cat.HUD_tag,
|
||||
cover_colour = G.C.DARK_EDITION,
|
||||
align = 'cm',
|
||||
})
|
||||
play_sound('generic1', 0.8 + perc/2, 0.6)
|
||||
play_sound('multhit1', 0.9 + perc/2, 0.4)
|
||||
return true
|
||||
end)
|
||||
}))
|
||||
G.E_MANAGER:add_event(Event({
|
||||
delay = 0.0,
|
||||
trigger = 'immediate',
|
||||
func = (function()
|
||||
attention_text({
|
||||
text = "-",
|
||||
colour = G.C.WHITE,
|
||||
scale = 1,
|
||||
hold = 0.3/G.SETTINGS.GAMESPEED,
|
||||
cover = self.HUD_tag,
|
||||
cover_colour = G.C.RED,
|
||||
align = 'cm',
|
||||
})
|
||||
return true
|
||||
end)
|
||||
}))
|
||||
G.E_MANAGER:add_event(Event({
|
||||
func = (function()
|
||||
self.HUD_tag.states.visible = false
|
||||
return true
|
||||
end)
|
||||
}))
|
||||
G.E_MANAGER:add_event(Event({ -- i have no idea what this does but i'm not messing with it
|
||||
func = func
|
||||
}))
|
||||
|
||||
other_cat.ability.level = other_cat.ability.level + 1
|
||||
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = 'after',
|
||||
delay = 0.7,
|
||||
func = (function()
|
||||
self:remove()
|
||||
cry_too_fast_kitty = nil
|
||||
return true
|
||||
end)
|
||||
}))
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
tag_sprite:juice_up()
|
||||
self.tag_sprite = tag_sprite
|
||||
|
||||
return tag_sprite_tab, tag_sprite
|
||||
end
|
||||
|
||||
function Tag:get_uibox_table(tag_sprite)
|
||||
tag_sprite = tag_sprite or self.tag_sprite
|
||||
local name_to_check, loc_vars = self.name, {}
|
||||
if name_to_check == 'Uncommon Tag' then
|
||||
elseif name_to_check == 'Investment Tag' then loc_vars = {self.config.dollars}
|
||||
elseif name_to_check == 'Handy Tag' then loc_vars = {self.config.dollars_per_hand, self.config.dollars_per_hand*(G.GAME.hands_played or 0)}
|
||||
elseif name_to_check == 'Garbage Tag' then loc_vars = {self.config.dollars_per_discard, self.config.dollars_per_discard*(G.GAME.unused_discards or 0)}
|
||||
elseif name_to_check == 'Juggle Tag' then loc_vars = {self.config.h_size}
|
||||
elseif name_to_check == 'Top-up Tag' then loc_vars = {self.config.spawn_jokers}
|
||||
elseif name_to_check == 'Skip Tag' then loc_vars = {self.config.skip_bonus, self.config.skip_bonus*((G.GAME.skips or 0)+1)}
|
||||
elseif name_to_check == 'Orbital Tag' then loc_vars = {
|
||||
(self.ability.orbital_hand == '['..localize('k_poker_hand')..']') and self.ability.orbital_hand or localize(self.ability.orbital_hand, 'poker_hands'), self.config.levels}
|
||||
elseif name_to_check == 'Economy Tag' then loc_vars = {self.config.max}
|
||||
elseif name_to_check == "cry-Rework Tag" then loc_vars = {
|
||||
self.ability and self.ability.rework_edition and localize{type = "name_text", set = "Edition", key = self.ability.rework_edition} or "["..string.lower(localize("k_edition")).."]",
|
||||
self.ability and self.ability.rework_key and localize{type = "name_text", set = "Joker", key = self.ability.rework_key} or "["..string.lower(localize("k_joker")).."]",
|
||||
}
|
||||
elseif name_to_check == "cry-Cat Tag" then loc_vars = {self.ability.level or 1}
|
||||
end
|
||||
tag_sprite.ability_UIBox_table = generate_card_ui(G.P_TAGS[self.key], nil, loc_vars, (self.hide_ability) and 'Undiscovered' or 'Tag', nil, (self.hide_ability), nil, nil, self)
|
||||
return tag_sprite
|
||||
end
|
||||
|
||||
function Tag:remove_from_game()
|
||||
local tag_key = nil
|
||||
for k, v in pairs(G.GAME.tags) do
|
||||
if v == self then tag_key = k end
|
||||
end
|
||||
table.remove(G.GAME.tags, tag_key)
|
||||
end
|
||||
|
||||
function Tag:remove()
|
||||
self:remove_from_game()
|
||||
local HUD_tag_key = nil
|
||||
for k, v in pairs(G.HUD_tags) do
|
||||
if v == self.HUD_tag then HUD_tag_key = k end
|
||||
end
|
||||
|
||||
if HUD_tag_key then
|
||||
if G.HUD_tags and G.HUD_tags[HUD_tag_key+1] then
|
||||
if HUD_tag_key == 1 then
|
||||
G.HUD_tags[HUD_tag_key+1]:set_alignment({type = 'bri',
|
||||
offset = {x=0.7,y=0},
|
||||
xy_bond = 'Weak',
|
||||
major = G.ROOM_ATTACH})
|
||||
else
|
||||
G.HUD_tags[HUD_tag_key+1]:set_role({
|
||||
xy_bond = 'Weak',
|
||||
major = G.HUD_tags[HUD_tag_key-1]})
|
||||
end
|
||||
end
|
||||
table.remove(G.HUD_tags, HUD_tag_key)
|
||||
end
|
||||
|
||||
self.HUD_tag:remove()
|
||||
end
|
Loading…
Reference in a new issue