mirror of
https://git.ethanthesleepy.one/ethanaobrien/ew
synced 2026-08-26 15:02:18 +08:00
fix bond
This commit is contained in:
@@ -16,6 +16,34 @@ fn index_by(items: &JsonValue, key: &str) -> JsonValue {
|
|||||||
info
|
info
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Missions in an id band grouped by the character they target, as
|
||||||
|
// [requiredBond, missionId] ordered by required bond. Read from masterdata
|
||||||
|
// rather than derived from the character id: the ids do not follow character
|
||||||
|
// order (4010/4011 sit at 1158079/1158080, after the 15000 tier), and
|
||||||
|
// characters added by a card import have none at all.
|
||||||
|
fn missions_by_character(lo: i64, hi: i64) -> JsonValue {
|
||||||
|
let mut acc: std::collections::HashMap<String, Vec<(i64, i64)>> = std::collections::HashMap::new();
|
||||||
|
for data in t("mission").members() {
|
||||||
|
let id = data["id"].as_i64().unwrap_or(0);
|
||||||
|
if id < lo || id >= hi || data["conditionValues"].len() != 1 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
acc.entry(data["conditionValues"][0].to_string())
|
||||||
|
.or_default()
|
||||||
|
.push((data["conditionNumber"].as_i64().unwrap_or(0), id));
|
||||||
|
}
|
||||||
|
let mut info = object! {};
|
||||||
|
for (character, mut list) in acc {
|
||||||
|
list.sort();
|
||||||
|
let mut entries = array![];
|
||||||
|
for (required, id) in list {
|
||||||
|
entries.push(array![required, id]).unwrap();
|
||||||
|
}
|
||||||
|
info[&character] = entries;
|
||||||
|
}
|
||||||
|
info
|
||||||
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref STORY: JsonValue = index_by(&t("story_part"), "id");
|
pub static ref STORY: JsonValue = index_by(&t("story_part"), "id");
|
||||||
|
|
||||||
@@ -203,6 +231,11 @@ lazy_static! {
|
|||||||
|
|
||||||
pub static ref MISSION_LIST: JsonValue = index_by(&t("mission"), "id");
|
pub static ref MISSION_LIST: JsonValue = index_by(&t("mission"), "id");
|
||||||
|
|
||||||
|
pub static ref CHARACTER_BOND_MISSIONS: JsonValue = missions_by_character(1158000, 1159000);
|
||||||
|
|
||||||
|
// 15 per character, aligned with live::CHATS.
|
||||||
|
pub static ref CHARACTER_CHAT_MISSIONS: JsonValue = missions_by_character(1958000, 1960000);
|
||||||
|
|
||||||
pub static ref CHARACTER_CHATS: JsonValue = {
|
pub static ref CHARACTER_CHATS: JsonValue = {
|
||||||
let mut info = object! {};
|
let mut info = object! {};
|
||||||
for data in t("mission").members() {
|
for data in t("mission").members() {
|
||||||
|
|||||||
@@ -460,21 +460,9 @@ fn give_mission_rewards(user: &mut JsonValue, home: &mut JsonValue, missions: &J
|
|||||||
}
|
}
|
||||||
rv
|
rv
|
||||||
}
|
}
|
||||||
pub fn get_master_num(id: i64) -> i64 {
|
// [requiredBond, missionId] pairs for a character's bond missions, lowest first.
|
||||||
let id = id.to_string();
|
pub fn bond_missions(character: i64) -> &'static JsonValue {
|
||||||
let mut masterid = 0;
|
&databases::CHARACTER_BOND_MISSIONS[character.to_string()]
|
||||||
if id.starts_with('2') {
|
|
||||||
masterid += 9;
|
|
||||||
} else if id.starts_with('3') {
|
|
||||||
masterid += 9 + 9;
|
|
||||||
} else if id.starts_with('4') {
|
|
||||||
masterid += 9 + 9 + 12;
|
|
||||||
}
|
|
||||||
masterid
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_master_id(id: i64) -> i64 {
|
|
||||||
get_master_num(id) + id.to_string().char_indices().last().unwrap().1.to_string().parse::<i64>().unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_BOND: i64 = 500000;
|
const MAX_BOND: i64 = 500000;
|
||||||
@@ -550,18 +538,17 @@ fn get_live_character_list(lp_used: i32, deck_id: i32, user: &mut JsonValue, mis
|
|||||||
let after = (before + gains[idx]).min(MAX_BOND);
|
let after = (before + gains[idx]).min(MAX_BOND);
|
||||||
set_character_bond(&mut character_list, character, after);
|
set_character_bond(&mut character_list, character, after);
|
||||||
|
|
||||||
if gains[idx] > 0 {
|
let tiers = bond_missions(character);
|
||||||
let mut mission_id = 1158000 + get_master_id(character);
|
if gains[idx] > 0 && !tiers.is_empty() {
|
||||||
let mut limit = 1500;
|
let mut tier = 0;
|
||||||
let mut status = items::get_mission_status(mission_id, missions);
|
let mut status = items::get_mission_status(tiers[0][1].as_i64().unwrap(), missions);
|
||||||
if status.is_empty() {
|
if status.is_empty() && tiers.len() > 1 {
|
||||||
mission_id += 39;
|
tier = 1;
|
||||||
limit *= 10;
|
status = items::get_mission_status(tiers[1][1].as_i64().unwrap(), missions);
|
||||||
status = items::get_mission_status(mission_id, missions);
|
|
||||||
}
|
}
|
||||||
if status["status"].as_i32().unwrap_or(0) <= 1 {
|
if status["status"].as_i32().unwrap_or(0) <= 1 {
|
||||||
let completed = after >= limit;
|
let completed = after >= tiers[tier][0].as_i64().unwrap();
|
||||||
if let Some(m) = items::update_mission_status(mission_id, 0, completed, false, gains[idx], missions) {
|
if let Some(m) = items::update_mission_status(tiers[tier][1].as_i64().unwrap(), 0, completed, false, gains[idx], missions) {
|
||||||
completed_missions.push(m).unwrap();
|
completed_missions.push(m).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -576,18 +563,21 @@ fn get_live_character_list(lp_used: i32, deck_id: i32, user: &mut JsonValue, mis
|
|||||||
|
|
||||||
if tutorial_step >= 130 {
|
if tutorial_step >= 130 {
|
||||||
for data in rv.members() {
|
for data in rv.members() {
|
||||||
for chat in CHATS.members() {
|
let character = data["master_character_id"].as_i64().unwrap();
|
||||||
|
let chat_missions = &databases::CHARACTER_CHAT_MISSIONS[character.to_string()];
|
||||||
|
for (step, chat) in CHATS.members().enumerate() {
|
||||||
if chat.as_i64().unwrap() > data["exp"].as_i64().unwrap() {
|
if chat.as_i64().unwrap() > data["exp"].as_i64().unwrap() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if crate::router::chat::add_chat(data["master_character_id"].as_i64().unwrap(), 1, chats) {
|
if crate::router::chat::add_chat(character, 1, chats) {
|
||||||
let mission_id = 1958000 + (get_master_id(data["master_character_id"].as_i64().unwrap()) * CHATS.len() as i64);
|
if let Some(mission_id) = chat_missions[step][1].as_i64() {
|
||||||
items::update_mission_status(mission_id, 0, true, true, 1, missions);
|
items::update_mission_status(mission_id, 0, true, true, 1, missions);
|
||||||
completed_missions.push(mission_id).unwrap();
|
completed_missions.push(mission_id).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
user["character_list"] = character_list;
|
user["character_list"] = character_list;
|
||||||
rv
|
rv
|
||||||
@@ -849,4 +839,37 @@ mod tests {
|
|||||||
assert_eq!(asset_gate(stock, "ios", ""), None);
|
assert_eq!(asset_gate(stock, "ios", ""), None);
|
||||||
assert_eq!(asset_gate(stock, "Windows", ""), None);
|
assert_eq!(asset_gate(stock, "Windows", ""), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bond_ids(character: i64) -> Vec<i64> {
|
||||||
|
bond_missions(character).members().map(|m| m[1].as_i64().unwrap()).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bond_missions_match_masterdata() {
|
||||||
|
assert_eq!(bond_ids(1001), vec![1158001, 1158040]);
|
||||||
|
// Not contiguous with character order, and previously derived from the
|
||||||
|
// id's last digit: 3010/3011/3012 and 4010/4011 all resolved to another
|
||||||
|
// character's mission.
|
||||||
|
assert_eq!(bond_ids(3010), vec![1158028, 1158067]);
|
||||||
|
assert_eq!(bond_ids(3012), vec![1158030, 1158069]);
|
||||||
|
assert_eq!(bond_ids(4010), vec![1158079, 1158081]);
|
||||||
|
assert_eq!(bond_ids(4011), vec![1158080, 1158082]);
|
||||||
|
|
||||||
|
// Bands with no bond missions must map to nothing rather than collide
|
||||||
|
// with a mu's character: 6xxx is official, 5xxx is the SIF1 card import.
|
||||||
|
assert!(bond_missions(6001).is_empty());
|
||||||
|
assert!(bond_missions(5001).is_empty());
|
||||||
|
assert!(bond_missions(5172).is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn chat_missions_align_with_bond_steps() {
|
||||||
|
let chats = &databases::CHARACTER_CHAT_MISSIONS["1001"];
|
||||||
|
assert_eq!(chats.len(), CHATS.len());
|
||||||
|
for (step, threshold) in CHATS.members().enumerate() {
|
||||||
|
assert_eq!(chats[step][0].as_i64(), threshold.as_i64());
|
||||||
|
assert_eq!(chats[step][1].as_i64(), Some(1958001 + step as i64));
|
||||||
|
}
|
||||||
|
assert!(databases::CHARACTER_CHAT_MISSIONS["5001"].is_empty());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -434,7 +434,10 @@ async fn initialize(Session { key, body }: Session) -> impl Responder {
|
|||||||
master_character_id: chosen_character,
|
master_character_id: chosen_character,
|
||||||
exp: 1
|
exp: 1
|
||||||
}];
|
}];
|
||||||
items::advance_mission(1158000 + crate::router::live::get_master_id(chosen_character), 1, 1500, &mut missions);
|
let bond = crate::router::live::bond_missions(chosen_character);
|
||||||
|
if !bond.is_empty() {
|
||||||
|
items::advance_mission(bond[0][1].as_i64().unwrap(), 1, bond[0][0].as_i64().unwrap(), &mut missions);
|
||||||
|
}
|
||||||
|
|
||||||
userdata::save_acc(&key, user.clone());
|
userdata::save_acc(&key, user.clone());
|
||||||
userdata::save_acc_chats(&key, chats);
|
userdata::save_acc_chats(&key, chats);
|
||||||
|
|||||||
Reference in New Issue
Block a user