sevenx_engine 0.2.11

Engine de jogos 2D/3D completa com suporte Android, física, áudio, partículas, tilemap, UI, eventos e sistema 3D avançado com PBR.
Documentation
// Sistema de Quests/Missões
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QuestSystem {
    pub quests: HashMap<String, Quest>,
    pub active_quests: Vec<String>,
    pub completed_quests: Vec<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Quest {
    pub id: String,
    pub title: String,
    pub description: String,
    pub objectives: Vec<QuestObjective>,
    pub rewards: QuestRewards,
    pub status: QuestStatus,
    pub required_level: u32,
    pub prerequisites: Vec<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QuestObjective {
    pub id: String,
    pub description: String,
    pub objective_type: ObjectiveType,
    pub current: u32,
    pub target: u32,
    pub completed: bool,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ObjectiveType {
    Kill { enemy_id: String },
    Collect { item_id: String },
    Talk { npc_id: String },
    Reach { location: String },
    Escort { npc_id: String },
    Defend { duration: f32 },
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QuestRewards {
    pub exp: u32,
    pub gold: u32,
    pub items: Vec<(String, u32)>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum QuestStatus {
    Available,
    Active,
    Completed,
    Failed,
}

impl QuestSystem {
    pub fn new() -> Self {
        Self {
            quests: HashMap::new(),
            active_quests: Vec::new(),
            completed_quests: Vec::new(),
        }
    }

    pub fn add_quest(&mut self, quest: Quest) {
        self.quests.insert(quest.id.clone(), quest);
    }

    pub fn start_quest(&mut self, quest_id: &str) -> bool {
        if let Some(quest) = self.quests.get_mut(quest_id) {
            if quest.status == QuestStatus::Available {
                quest.status = QuestStatus::Active;
                self.active_quests.push(quest_id.to_string());
                return true;
            }
        }
        false
    }

    pub fn complete_quest(&mut self, quest_id: &str) -> Option<QuestRewards> {
        if let Some(quest) = self.quests.get_mut(quest_id) {
            if quest.status == QuestStatus::Active && quest.all_objectives_complete() {
                quest.status = QuestStatus::Completed;
                self.active_quests.retain(|id| id != quest_id);
                self.completed_quests.push(quest_id.to_string());
                return Some(quest.rewards.clone());
            }
        }
        None
    }

    pub fn update_objective(&mut self, quest_id: &str, objective_id: &str, progress: u32) {
        if let Some(quest) = self.quests.get_mut(quest_id) {
            if quest.status == QuestStatus::Active {
                for obj in &mut quest.objectives {
                    if obj.id == objective_id {
                        obj.current = obj.current.max(progress).min(obj.target);
                        obj.completed = obj.current >= obj.target;
                    }
                }
            }
        }
    }

    pub fn get_active_quests(&self) -> Vec<&Quest> {
        self.active_quests
            .iter()
            .filter_map(|id| self.quests.get(id))
            .collect()
    }

    pub fn get_available_quests(&self, player_level: u32) -> Vec<&Quest> {
        self.quests
            .values()
            .filter(|q| {
                q.status == QuestStatus::Available
                    && q.required_level <= player_level
                    && q.prerequisites.iter().all(|p| self.completed_quests.contains(p))
            })
            .collect()
    }
}

impl Quest {
    pub fn new(id: &str, title: &str, description: &str) -> Self {
        Self {
            id: id.to_string(),
            title: title.to_string(),
            description: description.to_string(),
            objectives: Vec::new(),
            rewards: QuestRewards::default(),
            status: QuestStatus::Available,
            required_level: 1,
            prerequisites: Vec::new(),
        }
    }

    pub fn add_objective(&mut self, objective: QuestObjective) {
        self.objectives.push(objective);
    }

    pub fn all_objectives_complete(&self) -> bool {
        !self.objectives.is_empty() && self.objectives.iter().all(|obj| obj.completed)
    }

    pub fn progress_percentage(&self) -> f32 {
        if self.objectives.is_empty() {
            return 0.0;
        }
        let completed = self.objectives.iter().filter(|obj| obj.completed).count();
        (completed as f32 / self.objectives.len() as f32) * 100.0
    }
}

impl QuestObjective {
    pub fn kill(id: &str, description: &str, enemy_id: &str, count: u32) -> Self {
        Self {
            id: id.to_string(),
            description: description.to_string(),
            objective_type: ObjectiveType::Kill {
                enemy_id: enemy_id.to_string(),
            },
            current: 0,
            target: count,
            completed: false,
        }
    }

    pub fn collect(id: &str, description: &str, item_id: &str, count: u32) -> Self {
        Self {
            id: id.to_string(),
            description: description.to_string(),
            objective_type: ObjectiveType::Collect {
                item_id: item_id.to_string(),
            },
            current: 0,
            target: count,
            completed: false,
        }
    }
}

impl Default for QuestRewards {
    fn default() -> Self {
        Self {
            exp: 0,
            gold: 0,
            items: Vec::new(),
        }
    }
}

impl Default for QuestSystem {
    fn default() -> Self {
        Self::new()
    }
}