aoaddons 0.2.0

Simple library for creating addons for albion online game in multiple programing languages.
Documentation
use std::convert::From;

use crate::photon_messages::messages;

use super::events;
use super::id_cache::{DynIdToStaticId, StaticIdToName};
use super::player::DynamicId;

pub struct EventIntermediate<Msg> {
    dyn_id_to_static_id: DynIdToStaticId,
    static_id_to_name: StaticIdToName,
    message: Msg,
}

impl<Msg> EventIntermediate<Msg> {
    pub fn new(
        dyn_id_to_static_id: DynIdToStaticId,
        static_id_to_name: StaticIdToName,
        message: Msg,
    ) -> Self {
        Self {
            dyn_id_to_static_id,
            static_id_to_name,
            message,
        }
    }
}

pub struct EventList {
    value: Vec<events::Event>,
}

impl EventList {
    pub fn new(list: Vec<events::Event>) -> Self {
        Self { value: list }
    }

    pub fn values(self) -> Option<Vec<events::Event>> {
        Some(self.value)
    }
}

macro_rules! try_from_dynamic {
    ($field_name:ident, $intermediate:expr) => {
        if let Some(static_id) = $intermediate
            .dyn_id_to_static_id
            .get(&DynamicId::from($intermediate.message.$field_name as u32))
        {
            *static_id
        } else {
            return Self::new(vec![]);
        }
    };
}

macro_rules! try_from_dynamic_with_name {
    ($field_name:ident, $intermediate:expr) => {
        if let Some(static_id) = $intermediate
            .dyn_id_to_static_id
            .get(&DynamicId::from($intermediate.message.$field_name as u32))
        {
            if let Some(player_name) = $intermediate.static_id_to_name.get(&static_id) {
                (*static_id, player_name.to_string())
            } else {
                return Self::new(vec![]);
            }
        } else {
            return Self::new(vec![]);
        }
    };
}

impl From<EventIntermediate<messages::NewCharacter>> for EventList {
    fn from(intermediate: EventIntermediate<messages::NewCharacter>) -> Self {
        let static_id = try_from_dynamic!(source, intermediate);
        Self::new(vec![
            events::Event::PlayerAppeared(events::Player {
                id: static_id,
                name: intermediate.message.character_name,
            }),
            events::Event::UpdateItems(events::Items {
                source: static_id,
                value: intermediate.message.items,
            }),
        ])
    }
}

impl From<EventIntermediate<messages::Join>> for EventList {
    fn from(intermediate: EventIntermediate<messages::Join>) -> Self {
        let static_id = try_from_dynamic!(source, intermediate);
        Self::new(vec![events::Event::MainPlayerAppeared(events::Player {
            id: static_id,
            name: intermediate.message.character_name,
        })])
    }
}

impl From<EventIntermediate<messages::HealthUpdate>> for EventList {
    fn from(intermediate: EventIntermediate<messages::HealthUpdate>) -> Self {
        let target_static_id = try_from_dynamic!(target, intermediate);

        if intermediate.message.value < 0.0 {
            return Self::new(vec![events::Event::DamageDone(events::Damage {
                source: target_static_id,
                target: intermediate
                    .dyn_id_to_static_id
                    .get(&DynamicId::from(intermediate.message.source as u32))
                    .map(|v| *v),
                value: f32::abs(intermediate.message.value),
            })]);
        }

        Self::new(vec![events::Event::HealthReceived(events::Damage {
            source: target_static_id,
            target: intermediate
                .dyn_id_to_static_id
                .get(&DynamicId::from(intermediate.message.source as u32))
                .map(|v| *v),
            value: intermediate.message.value,
        })])
    }
}

impl From<EventIntermediate<messages::RegenerationHealthChanged>> for EventList {
    fn from(intermediate: EventIntermediate<messages::RegenerationHealthChanged>) -> Self {
        let (static_id, name) = try_from_dynamic_with_name!(source, intermediate);

        match intermediate.message.regeneration_rate {
            Some(_) => Self::new(vec![events::Event::LeaveCombat(events::Player {
                id: static_id,
                name: name,
            })]),
            None => Self::new(vec![events::Event::EnterCombat(events::Player {
                id: static_id,
                name: name,
            })]),
        }
    }
}

impl From<EventIntermediate<messages::KnockedDown>> for EventList {
    fn from(intermediate: EventIntermediate<messages::KnockedDown>) -> Self {
        let (static_id, name) = try_from_dynamic_with_name!(source, intermediate);
        Self::new(vec![events::Event::LeaveCombat(events::Player {
            id: static_id,
            name: name,
        })])
    }
}

impl From<EventIntermediate<messages::UpdateFame>> for EventList {
    fn from(intermediate: EventIntermediate<messages::UpdateFame>) -> Self {
        let source_static_id = try_from_dynamic!(source, intermediate);
        Self::new(vec![events::Event::UpdateFame(events::Fame {
            source: source_static_id,
            value: intermediate.message.fame as f32 / 10000.0,
        })])
    }
}

impl From<EventIntermediate<messages::CharacterEquipmentChanged>> for EventList {
    fn from(intermediate: EventIntermediate<messages::CharacterEquipmentChanged>) -> Self {
        let source_static_id = try_from_dynamic!(source, intermediate);
        Self::new(vec![events::Event::UpdateItems(events::Items {
            source: source_static_id,
            value: intermediate.message.items,
        })])
    }
}

impl From<EventIntermediate<messages::ChatSay>> for EventList {
    fn from(intermediate: EventIntermediate<messages::ChatSay>) -> Self {
        Self::new(vec![events::Event::ChatSay(intermediate.message.text)])
    }
}