Skip to main content

tengu_api/tasks/
collection.rs

1//! Collection task (task 8): 3 ninjas same element + same rarity.
2//! Uses cached collection_counts (updated on recruit, merge, prestige).
3
4use solana_program::program_error::ProgramError;
5
6use crate::consts::{
7    ELEMENT_RARITY_REWARD_N, ELEMENT_RARITY_REWARD_R,
8    ELEMENT_RARITY_REWARD_SR, ELEMENT_RARITY_REWARD_SSR, ELEMENT_RARITY_REWARD_UR,
9};
10use crate::state::Tasks;
11
12const RARITY_REWARDS: [u64; 5] = [
13    ELEMENT_RARITY_REWARD_N,
14    ELEMENT_RARITY_REWARD_R,
15    ELEMENT_RARITY_REWARD_SR,
16    ELEMENT_RARITY_REWARD_SSR,
17    ELEMENT_RARITY_REWARD_UR,
18];
19
20/// collection_index = element×5+rarity (0–24).
21pub fn collection_index(element: u64, rarity: u64) -> usize {
22    (element * 5 + rarity) as usize
23}
24
25/// Check collection task using cached counts. Mutates tasks.collection_claimed.
26/// Returns (completed, reward). collection_index = element×5+rarity (0–24).
27pub fn check(
28    tasks: &mut Tasks,
29    collection_index: u8,
30) -> Result<(bool, u64), ProgramError> {
31    if collection_index > 24 {
32        return Err(ProgramError::InvalidAccountData);
33    }
34    let rarity = (collection_index % 5) as usize;
35
36    let count = tasks.collection_counts[collection_index as usize];
37    if count < 3 {
38        return Err(crate::error::DojosError::TaskNotCompleted.into());
39    }
40
41    let idx = collection_index as usize;
42    if tasks.collection_claimed[idx] != 0 {
43        return Err(crate::error::DojosError::TaskAlreadyClaimed.into());
44    }
45    tasks.collection_claimed[idx] = 1;
46
47    let reward = RARITY_REWARDS[rarity];
48    Ok((true, reward))
49}