diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index 5f563a3836..66bc18f641 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -33,6 +33,7 @@ pub mod invite; #[cfg(not(target_arch = "wasm32"))] pub mod poise; #[cfg(not(target_arch = "wasm32"))] pub mod projectile; +pub mod quest; #[cfg(not(target_arch = "wasm32"))] pub mod shockwave; #[cfg(not(target_arch = "wasm32"))] diff --git a/common/src/comp/quest.rs b/common/src/comp/quest.rs new file mode 100644 index 0000000000..9cf6cae084 --- /dev/null +++ b/common/src/comp/quest.rs @@ -0,0 +1,130 @@ +//! The following is a proposal for quests in Veloren. A server side quest system would maintain +//! the necessary conditions for the quests. Players would be given a `Quests` component which +//! would store current quests. Each quest consists of a name and a vector of quest conditions. +//! These conditions are popped off the vector until it is empty. At that point the quest is +//! complete. Here is a sample quest: +//! +//! ``` +//! Quest { +//! name: "Escort Bob safely to Thead for Joe", +//! conditions: [ +//! Find(RtSimEntity(3, "Bob"), QuestLocation { +//! kind: Site("Scrin"), +//! location: None, +//! }), +//! Escort(RtSimEntity(3, "Bob"), QuestLocation { +//! kind: Site("Thead"), +//! location: None, +//! }), +//! CollectReward(QuestItem{ +//! item_definition_id: "common.items.utility.coins", +//! quantity: 1000, +//! }), +//! ], +//! } +//! ``` +//! +//! The quest must be completed in order. Failure would be monitored by the server side quest +//! system. (Eg. escort conditions would fail if the escorted entity died.) + +use crate::{comp::Body, rtsim::RtSimId}; +use specs::{Component, DerefFlaggedStorage}; +use specs_idvs::IdvStorage; +use serde::{Deserialize, Serialize}; +use vek::*; + +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct Quests { + pub quests: Vec, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Quest { + name: String, + conditions: Vec, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum QuestCondition { + /// Kill entities. The vector allows multiple target types to be included in the same step of + /// the quest + Kill(Vec), + /// Escort one or multiple targets to a destination + Escort(Vec, QuestLocation), + /// Take an item to a location. Similar to `Escort` but for items, not characters + TakeItemTo(Vec, QuestLocation), + /// Find something(s) from an optional location + Find(FindQuestQuery, Option), + /// Go to a given location + Goto(QuestLocation), + /// A time at which all the previous conditions need to be completed to prevent failure + CompleteBy(f64), + /// Survive without dying or respawning until a given time + SurviveUntil(f64), + /// Collect a reward + CollectReward(Vec, QuestLocation), +} + +/// An item and quantity for use as a reward, an item in or quest, etc +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct QuestItem { + item_definition_id: String, + quantity: u32, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct QuestCharacterTarget { + kind: CharacterTargetKind, + quantity: u32, +} + +/// Something to look for in a find quest +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum CharacterTargetKind { + /// RtSim id and name + RtSimEntity(RtSimId, String), + Creature(Body), +} + +/// Something to look for in a find quest +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum FindQuestQuery { + /// RtSim id and name + RtSimEntity(RtSimId, String), + Site(String), + Creature(Body), + Item(QuestItem), +} + +/// A location for a quest, either as a destination or a place to look for something. +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct QuestLocation { + kind: QuestLocationKind, + location: Option>, +} + +/// Various kinds of locations and destinations for quests. +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum QuestLocationKind { + Site(String), + RtSimEntity(RtSimId, String), + Direction(Direction), + Coordinates, +} + +/// Cardinal directions +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum Direction { + North, + South, + East, + West, + Northeast, + Northwest, + Southeast, + Southwest, +} + +impl Component for Quests { + type Storage = DerefFlaggedStorage>; +} diff --git a/server/src/rtsim/entity.rs b/server/src/rtsim/entity.rs index 500199f822..aa4e592f26 100644 --- a/server/src/rtsim/entity.rs +++ b/server/src/rtsim/entity.rs @@ -21,7 +21,6 @@ pub struct Entity { pub seed: u32, pub last_tick: u64, pub controller: RtSimController, - pub brain: Brain, pub occupation: Option, } diff --git a/server/src/sys/agent.rs b/server/src/sys/agent.rs index 3cd423732f..f5ce0b12a4 100644 --- a/server/src/sys/agent.rs +++ b/server/src/sys/agent.rs @@ -864,7 +864,7 @@ impl<'a> AgentData<'a> { }; if agent.bearing.magnitude_squared() > 0.5f32.powi(2) { - if matches!(Some(Alignment::Owned(_)), data.alignment) { + if matches!(self.alignment, Some(Alignment::Owned(_))) { controller.inputs.move_dir = agent.bearing * 0.30; } else { controller.inputs.move_dir = agent.bearing * 0.65;