aboutsummaryrefslogtreecommitdiff
path: root/azalea-entity/src/attributes.rs
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2023-07-14 22:20:40 -0500
committerGitHub <noreply@github.com>2023-07-14 22:20:40 -0500
commit7405427199e5a994d4a6a706f84434a69cb7a7d9 (patch)
treeca537e5d761bc053187d952fced0915c850b92aa /azalea-entity/src/attributes.rs
parentd1afd02aa84e7b4450c1607277f078eb2a0f1bf3 (diff)
downloadazalea-drasl-7405427199e5a994d4a6a706f84434a69cb7a7d9.tar.xz
Mining (#95)
* more mining stuff * initialize azalea-tags crate * more mining stuff 2 * mining in ecs * well technically mining works but no codegen for how long it takes to mine each block yet * rename downloads to __cache__ it was bothering me since it's not *just* downloads * codegen block behavior * fix not sending packet to finish breaking block * mining animation 🎉 * clippy * cleanup, move Client::mine into a client extension * add azalea/src/mining.rs --------- Co-authored-by: mat <git@matdoes.dev>
Diffstat (limited to 'azalea-entity/src/attributes.rs')
-rw-r--r--azalea-entity/src/attributes.rs116
1 files changed, 116 insertions, 0 deletions
diff --git a/azalea-entity/src/attributes.rs b/azalea-entity/src/attributes.rs
new file mode 100644
index 00000000..97b890dc
--- /dev/null
+++ b/azalea-entity/src/attributes.rs
@@ -0,0 +1,116 @@
+//! See <https://minecraft.fandom.com/wiki/Attribute>.
+
+use std::{
+ collections::HashMap,
+ io::{Cursor, Write},
+};
+
+use azalea_buf::{BufReadError, McBuf, McBufReadable, McBufWritable};
+use bevy_ecs::component::Component;
+use thiserror::Error;
+use uuid::{uuid, Uuid};
+
+#[derive(Clone, Debug, Component)]
+pub struct Attributes {
+ pub speed: AttributeInstance,
+}
+
+#[derive(Clone, Debug)]
+pub struct AttributeInstance {
+ pub base: f64,
+ modifiers_by_uuid: HashMap<Uuid, AttributeModifier>,
+}
+
+#[derive(Clone, Debug, Error)]
+#[error("A modifier with this UUID is already present.")]
+pub struct AlreadyPresentError;
+
+impl AttributeInstance {
+ pub fn new(base: f64) -> Self {
+ Self {
+ base,
+ modifiers_by_uuid: HashMap::new(),
+ }
+ }
+
+ pub fn calculate(&self) -> f64 {
+ let mut total = self.base;
+ for modifier in self.modifiers_by_uuid.values() {
+ match modifier.operation {
+ AttributeModifierOperation::Addition => total += modifier.amount,
+ AttributeModifierOperation::MultiplyBase => total += self.base * modifier.amount,
+ _ => {}
+ }
+ if let AttributeModifierOperation::MultiplyTotal = modifier.operation {
+ total *= 1.0 + modifier.amount;
+ }
+ }
+ total
+ }
+
+ /// Add a new modifier to this attribute.
+ pub fn insert(&mut self, modifier: AttributeModifier) -> Result<(), AlreadyPresentError> {
+ if self
+ .modifiers_by_uuid
+ .insert(modifier.uuid, modifier)
+ .is_some()
+ {
+ Err(AlreadyPresentError)
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Remove the modifier with the given UUID from this attribute, returning
+ /// the previous modifier is present.
+ pub fn remove(&mut self, uuid: &Uuid) -> Option<AttributeModifier> {
+ self.modifiers_by_uuid.remove(uuid)
+ }
+}
+
+#[derive(Clone, Debug)]
+pub struct AttributeModifier {
+ pub uuid: Uuid,
+ pub name: String,
+ pub amount: f64,
+ pub operation: AttributeModifierOperation,
+}
+
+#[derive(Clone, Debug, Copy, McBuf)]
+pub enum AttributeModifierOperation {
+ Addition,
+ MultiplyBase,
+ MultiplyTotal,
+}
+
+pub fn sprinting_modifier() -> AttributeModifier {
+ AttributeModifier {
+ uuid: uuid!("662A6B8D-DA3E-4C1C-8813-96EA6097278D"),
+ name: "Sprinting speed boost".to_string(),
+ amount: 0.30000001192092896,
+ operation: AttributeModifierOperation::MultiplyTotal,
+ }
+}
+
+impl McBufReadable for AttributeModifier {
+ fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
+ let uuid = Uuid::read_from(buf)?;
+ let amount = f64::read_from(buf)?;
+ let operation = AttributeModifierOperation::read_from(buf)?;
+ Ok(Self {
+ uuid,
+ name: "Unknown synced attribute modifier".to_string(),
+ amount,
+ operation,
+ })
+ }
+}
+
+impl McBufWritable for AttributeModifier {
+ fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ self.uuid.write_into(buf)?;
+ self.amount.write_into(buf)?;
+ self.operation.write_into(buf)?;
+ Ok(())
+ }
+}