Teleport Map & Switching Dynamic Wallpaper Support, Gacha optimization #2
3 changed files with 129 additions and 1 deletions
|
@ -150,7 +150,7 @@
|
|||
{
|
||||
"gacha_schedule_id": 5001001,
|
||||
"gacha_parent_schedule_id": 5001,
|
||||
"comment": "1.0, Full, Persistent, Bangboo",
|
||||
"comment": "1.1, Full, Persistent, Bangboo",
|
||||
"gacha_type": 5,
|
||||
"cost_item_id": 112, // 邦布券
|
||||
"start_time": "2024-07-04T06:00:00+08:00",
|
||||
|
@ -184,6 +184,7 @@
|
|||
"item_type": "GACHA_ADDED_ITEM_TYPE_BANGBOO",
|
||||
"item_ids": [
|
||||
54004, // 巴特勒
|
||||
54012, // 阿崔巡查
|
||||
],
|
||||
"is_promotional_items": true,
|
||||
"category_weight": 1
|
||||
|
|
125
nap_gameserver/src/commands/gacha.rs
Normal file
125
nap_gameserver/src/commands/gacha.rs
Normal file
|
@ -0,0 +1,125 @@
|
|||
use data::{gacha::global_gacha_config, tables::ItemID};
|
||||
|
||||
use crate::ServerState;
|
||||
|
||||
use super::ArgSlice;
|
||||
|
||||
pub async fn up(
|
||||
args: ArgSlice<'_>,
|
||||
state: &ServerState,
|
||||
) -> Result<String, Box<dyn std::error::Error>> {
|
||||
const USAGE: &str = "Usage: gacha up [player_uid] (start a gacha UP setting guide (available for Bangboo pool))";
|
||||
|
||||
if args.len() == 0 {
|
||||
return Ok(USAGE.to_string());
|
||||
}
|
||||
|
||||
let uid = args[0].parse::<u32>()?;
|
||||
|
||||
let Some(player_lock) = state.player_mgr.get_player(uid).await else {
|
||||
return Ok(String::from("player not found"));
|
||||
};
|
||||
|
||||
let gachaconf = global_gacha_config();
|
||||
let pool_list: Vec<(u32, &String)> = gachaconf
|
||||
.character_gacha_pool_list
|
||||
.iter()
|
||||
.filter(|pool| {
|
||||
pool.gacha_items.iter().any(|rarity_items| {
|
||||
rarity_items
|
||||
.category_guarantee_policy_tags
|
||||
.iter()
|
||||
.map(|tag| gachaconf.category_guarantee_policy_map.get(tag).unwrap())
|
||||
.any(|policy| policy.chooseable)
|
||||
})
|
||||
})
|
||||
.map(|pool| (pool.gacha_schedule_id, &pool.comment))
|
||||
.collect::<Vec<_>>();
|
||||
if args.len() == 1 {
|
||||
return Ok(format!(
|
||||
"{}\n{}\n{}",
|
||||
"Choose a target gacha pool first:",
|
||||
pool_list
|
||||
.iter()
|
||||
.map(|(id, comment)| format!("- gacha_schedule_id: {id} ({comment})"))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n"),
|
||||
"Use 'gacha up [player_uid] [gacha_schedule_id]' to continue."
|
||||
));
|
||||
}
|
||||
|
||||
let target_pool_id = args[1].parse::<u32>()?;
|
||||
let accepted_pool_id_list = pool_list.into_iter().map(|(id, _)| id).collect::<Vec<_>>();
|
||||
if !accepted_pool_id_list.contains(&target_pool_id) {
|
||||
return Ok(String::from("Gacha Pool not found or not allowed to set UP. Use gacha up [player_uid] to view available pool ids."));
|
||||
}
|
||||
let target_pool = gachaconf
|
||||
.character_gacha_pool_list
|
||||
.iter()
|
||||
.filter(|pool| pool.gacha_schedule_id == target_pool_id)
|
||||
.last()
|
||||
.unwrap();
|
||||
|
||||
let chooseable_items: Vec<(ItemID, &String)> = target_pool
|
||||
.gacha_items
|
||||
.iter()
|
||||
.filter(|rarity_items| {
|
||||
rarity_items
|
||||
.category_guarantee_policy_tags
|
||||
.iter()
|
||||
.map(|tag| gachaconf.category_guarantee_policy_map.get(tag).unwrap())
|
||||
.any(|policy| policy.chooseable)
|
||||
})
|
||||
.map(|items| {
|
||||
items
|
||||
.categories
|
||||
.iter()
|
||||
.map(|(category_tag, category)| {
|
||||
category
|
||||
.item_ids
|
||||
.iter()
|
||||
.map(|id| (ItemID::new_unchecked(id.clone()), category_tag))
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.concat()
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.concat();
|
||||
if args.len() == 2 {
|
||||
return Ok(format!(
|
||||
"{}\n{}\nUse 'gacha up [player_uid] {target_pool_id} [item_id]' to set your UP.",
|
||||
"Choose the UP item you want:",
|
||||
chooseable_items
|
||||
.iter()
|
||||
.map(|(item_id, category_tag)| format!("- ID {item_id} (category: {category_tag})"))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
));
|
||||
}
|
||||
|
||||
let accepted_ids = chooseable_items
|
||||
.iter()
|
||||
.map(|(item_id, _)| item_id.value())
|
||||
.collect::<Vec<_>>();
|
||||
let item_id = args[2].parse::<u32>()?;
|
||||
if !accepted_ids.contains(&item_id) {
|
||||
return Ok(format!("Item ID not found or not included in UP list. Use gacha up [player_uid] {target_pool_id} to view available item ids."));
|
||||
}
|
||||
|
||||
let mut player = player_lock.lock().await;
|
||||
if player
|
||||
.gacha_model
|
||||
.choose_gacha_up(target_pool, &ItemID::new_unchecked(item_id))
|
||||
{
|
||||
Ok(format!(
|
||||
"successfully set your gacha pool: {} (comment: {}) 100% UP to {item_id}. Close & Open Gacha Page to see result.",
|
||||
target_pool.gacha_schedule_id, target_pool.comment
|
||||
))
|
||||
} else {
|
||||
Ok(format!(
|
||||
"failed to set your gacha pool: {} (comment: {}) 100% UP to {item_id} (unexpected maybe bug)",
|
||||
target_pool.gacha_schedule_id, target_pool.comment
|
||||
))
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ use rustyline_async::{Readline, ReadlineEvent, SharedWriter};
|
|||
use crate::ServerState;
|
||||
|
||||
mod avatar;
|
||||
mod gacha;
|
||||
mod item;
|
||||
mod player;
|
||||
|
||||
|
@ -88,5 +89,6 @@ impl CommandManager {
|
|||
avatar::add "[player_uid] [avatar_id]" "gives avatar with specified id to player";
|
||||
item::add_weapon "[player_uid] [weapon_id]" "gives weapon with specified id to player";
|
||||
player::kick "[player_uid] [reason]" "kick the specified player (reason is optional)";
|
||||
gacha::up "[player_uid]" "start a gacha UP setting guide (available for Bangboo pool)";
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue