json stores are gone, they nulled out every data ref on load and wrote the null straight back on save. shop json and the purchase commands ended up in here too.
142 lines
5.1 KiB
Rust
142 lines
5.1 KiB
Rust
use logic::model::{
|
|
LogicChest, LogicClientAvatar, LogicClientHome, LogicCommodityStore, LogicDataSlot, LogicSpell,
|
|
LogicSpellCollection, LogicSpellDeck, LogicTimer,
|
|
};
|
|
use titan::LogicLong;
|
|
use logic::data::RESOURCE_GOLD;
|
|
use logic::{table, LogicDataRef};
|
|
use crate::catalog::GOLD_RESOURCE_FALLBACK_INSTANCE;
|
|
use crate::store::{OwnedCard, PlayerProfile, StoredChest};
|
|
pub const COMMODITY_RESOURCES: usize = 0;
|
|
fn spell_of(owned: &OwnedCard) -> LogicSpell {
|
|
LogicSpell {
|
|
data: owned.card.clone(),
|
|
level_index: owned.level_index,
|
|
create_time: 0,
|
|
count: owned.count,
|
|
new_count: 0,
|
|
recent_use_count: 0,
|
|
new_upgrade_available: false,
|
|
show_new_icon: false,
|
|
}
|
|
}
|
|
fn chest_of(stored: &StoredChest) -> LogicChest {
|
|
LogicChest {
|
|
data: stored.chest.clone(),
|
|
unlocked: stored.unlocked,
|
|
claimed: stored.claimed,
|
|
is_new: false,
|
|
unlock_timer: (stored.remaining_ticks > 0).then_some(LogicTimer {
|
|
remaining_ticks: stored.remaining_ticks,
|
|
total_ticks: stored.total_ticks,
|
|
end_timestamp: stored.end_timestamp,
|
|
}),
|
|
chest_id: stored.chest_id,
|
|
source: stored.source,
|
|
slot_index: stored.slot_index,
|
|
}
|
|
}
|
|
fn chest_slots(profile: &PlayerProfile) -> Vec<Option<LogicChest>> {
|
|
let mut slots = vec![None; profile.chest_slot_count];
|
|
for stored in &profile.chests {
|
|
let Ok(index) = usize::try_from(stored.slot_index) else {
|
|
continue;
|
|
};
|
|
if index < slots.len() {
|
|
slots[index] = Some(chest_of(stored));
|
|
}
|
|
}
|
|
slots
|
|
}
|
|
pub fn build_home(profile: &PlayerProfile) -> LogicClientHome {
|
|
let deck = LogicSpellDeck::from_cards(profile.deck.iter().map(spell_of));
|
|
let collection =
|
|
LogicSpellCollection::from_spells(profile.collection.iter().map(spell_of).collect());
|
|
let mut home = LogicClientHome {
|
|
home_id: LogicLong::new(profile.account.high, profile.account.low),
|
|
chest_id_counter: profile.chest_id_counter,
|
|
free_chest_collect_count: profile.free_chest_collect_count,
|
|
donation_capacity_limit_timer: LogicTimer::idle(),
|
|
donated_capacity: 0,
|
|
decks: vec![deck],
|
|
spell_collection: collection,
|
|
selected_deck_index: 0,
|
|
chest_slots: chest_slots(profile),
|
|
free_chest_timer: LogicTimer::idle(),
|
|
donation_cooldown_timer: LogicTimer::idle(),
|
|
free_chest: None,
|
|
purchased_chest: None,
|
|
crowns_towards_crown_chest: profile.crowns_towards_crown_chest,
|
|
star_chest_timer_pending: false,
|
|
star_chest_timer: LogicTimer::idle(),
|
|
crown_chest: None,
|
|
request_spells_cooldown_timer: LogicTimer::idle(),
|
|
finished_tutorials: [0; 8],
|
|
opened_pages: 0,
|
|
last_shown_level_up: profile.exp_level,
|
|
arena: profile.arena.clone(),
|
|
shop_seed: -1,
|
|
shop_weekday_index: -1,
|
|
shop_weekday_index_seen: -1,
|
|
shop_timer: LogicTimer::idle(),
|
|
shop_spells: Vec::new(),
|
|
share_replay_cooldown_timer: LogicTimer::idle(),
|
|
send_team_mail_cooldown_timer: LogicTimer::idle(),
|
|
free_chest_diamond_index: 0,
|
|
crown_chest_diamond_index: 0,
|
|
card_usage_stats_battle_count: profile.battle_count,
|
|
royal_tv_replay_version_major: 0,
|
|
royal_tv_replay_version_build: 0,
|
|
royal_tv_replay_version_content: 0,
|
|
seen_replay_ids: Vec::new(),
|
|
card_request_message: None,
|
|
requested_cards: Vec::new(),
|
|
};
|
|
if profile.tutorials_finished {
|
|
home.finish_all_tutorials();
|
|
}
|
|
home
|
|
}
|
|
fn gold_resource(profile: &PlayerProfile) -> LogicDataRef {
|
|
if !profile.gold_resource.is_none() {
|
|
return profile.gold_resource.clone();
|
|
}
|
|
let by_name = LogicDataRef::by_name(table::RESOURCES, RESOURCE_GOLD);
|
|
if !by_name.is_none() {
|
|
return by_name;
|
|
}
|
|
LogicDataRef::of(table::RESOURCES, GOLD_RESOURCE_FALLBACK_INSTANCE)
|
|
}
|
|
pub fn build_avatar(profile: &PlayerProfile) -> LogicClientAvatar {
|
|
let account = LogicLong::new(profile.account.high, profile.account.low);
|
|
let mut commodities = LogicCommodityStore::default();
|
|
commodities.set(
|
|
COMMODITY_RESOURCES,
|
|
vec![LogicDataSlot::new(gold_resource(profile), profile.gold)],
|
|
);
|
|
LogicClientAvatar {
|
|
avatar_id: account,
|
|
account_id: account,
|
|
home_id: account,
|
|
name: profile.name.clone(),
|
|
name_set_by_user: profile.name_set_by_user,
|
|
name_change_state: -1,
|
|
arena: profile.arena.clone(),
|
|
score: profile.trophies,
|
|
legacy_flag: false,
|
|
commodities,
|
|
diamonds: profile.diamonds,
|
|
free_diamonds: profile.free_diamonds,
|
|
exp_points: profile.exp_points,
|
|
exp_level: profile.exp_level,
|
|
cumulative_purchased_diamonds: 0,
|
|
alliance: None,
|
|
battle_count: profile.battle_count,
|
|
win_count: profile.win_count,
|
|
lose_count: profile.lose_count,
|
|
win_loose_streak: 0,
|
|
npc_win_count: profile.npc_win_count,
|
|
npc_lose_count: profile.npc_lose_count,
|
|
arena_before_last_npc_match: profile.arena.instance_id().unwrap_or(0) != 0,
|
|
}
|
|
}
|