Skip to main content

nexus\api\event/
arc.rs

1//! [ArcDPS EVTC](https://deltaconnected.com/arcdps/) bridge events.
2
3use super::Event;
4use evtc::agent::realtime::Agent;
5use std::ffi::{CStr, c_char};
6
7pub use evtc;
8
9/// ArcDPS EVTC combat local event.
10pub const COMBAT_LOCAL: Event<CombatData> =
11    unsafe { Event::new("EV_ARCDPS_COMBATEVENT_LOCAL_RAW") };
12
13/// ArcDPS EVTC combat squad event.
14pub const COMBAT_SQUAD: Event<CombatData> =
15    unsafe { Event::new("EV_ARCDPS_COMBATEVENT_SQUAD_RAW") };
16
17/// ArcDPS self join event.
18///
19/// Payload is [`AgentUpdate`] of the self player agent.
20///
21/// Events of this type are triggered upon map load.
22/// The last event can be retriggered on demand by addons sending an [`REPLAY_SELF_JOIN`] event.
23pub const SELF_JOIN: Event<AgentUpdate> = unsafe { Event::new("EV_ARCDPS_SELF_JOIN") };
24
25/// Replays the last [`SELF_JOIN`] event.
26pub const REPLAY_SELF_JOIN: Event<()> = unsafe { Event::new("EV_REPLAY_ARCDPS_SELF_JOIN") };
27
28/// ArcDPS self leave event.
29///
30/// Payload is [`AgentUpdate`] of the self player agent.
31///
32/// Events of this type are triggered when changing instance or leaving a party / squad.
33pub const SELF_LEAVE: Event<AgentUpdate> = unsafe { Event::new("EV_ARCDPS_SELF_LEAVE") };
34
35/// ArcDPS squad join event.
36///
37/// Payload is [`AgentUpdate`] of an allied player agent.
38/// Events of this type are triggered when allied players in your instance join your party/squad or when allied players in your party/squad join your instance.
39/// These events have a 2 second delay.
40///
41/// Nexus tracks all players in your squad and can retrigger these events on demand by addons sending an [`REPLAY_SQUAD_JOIN`] event.
42/// This is intended to be used during addon load, you should be careful to handle duplicates since this can be triggered by other addons.
43pub const SQUAD_JOIN: Event<AgentUpdate> = unsafe { Event::new("EV_ARCDPS_SQUAD_JOIN") };
44
45/// Replays [`SQUAD_JOIN`] events for the current squad.
46pub const REPLAY_SQUAD_JOIN: Event<()> = unsafe { Event::new("EV_REPLAY_ARCDPS_SQUAD_JOIN") };
47
48/// ArcDPS squad leave event.
49///
50/// Payload is [`AgentUpdate`] of an allied player agent.
51///
52/// Events of this type are triggered when allied players in your instance and party/squad either leave your instance or leave your party/squad.
53/// You will not recieve these events if you are the one to change instance or leave the party/squad.
54/// These events have a 2 second delay.
55pub const SQUAD_LEAVE: Event<AgentUpdate> = unsafe { Event::new("EV_ARCDPS_SQUAD_LEAVE") };
56
57/// ArcDPS target changed event.
58///
59/// Events of this type are triggered when you target an agent.
60/// The last event can be retriggered on demand by addons sending an [`REPLAY_TARGET_CHANGED`] event.
61pub const TARGET_CHANGED: Event<AgentUpdate> = unsafe { Event::new("EV_ARCDPS_TARGET_CHANGED") };
62
63/// Replays the [`TARGET_CHANGED`] event for the current target.
64pub const REPLAY_TARGET_CHANGED: Event<()> =
65    unsafe { Event::new("EV_REPLAY_ARCDPS_TARGET_CHANGED") };
66
67/// ArcDPS player account name.
68///
69/// Triggered on first map load.
70/// Can be triggered on demand by sending `"EV_REQUEST_ACCOUNT_NAME"`.
71pub const ACCOUNT_NAME: Event<c_char> = unsafe { Event::new("EV_ACCOUNT_NAME") };
72
73/// ArcDPS agent update.
74#[derive(Debug, Clone)]
75#[repr(C)]
76pub struct AgentUpdate {
77    /// Account name.
78    account: [c_char; 64],
79
80    /// Character name.
81    character: [c_char; 64],
82
83    /// ArcDPS id of the agent.
84    pub id: usize,
85
86    /// Instance id of the agent.
87    pub instance_id: usize,
88
89    /// Whether the agent has been added or removed.
90    added: u32,
91
92    /// Whether the agent is the new target.
93    target: u32,
94
95    /// Whether the agent is self.
96    is_self: u32,
97
98    /// Agent profession.
99    pub prof: u32,
100
101    /// Agent elite specialization.
102    pub elite: u32,
103
104    /// Agent team.
105    pub team: u16,
106
107    /// Agent subgroup.
108    pub subgroup: u16,
109}
110
111impl AgentUpdate {
112    /// Returns the account name as [`CStr`].
113    #[inline]
114    pub fn account_c(&self) -> &CStr {
115        unsafe { CStr::from_ptr(self.account.as_ptr()) }
116    }
117
118    /// Returns the account name as [`str`].
119    #[inline]
120    pub fn account(&self) -> Option<&str> {
121        self.account_c().to_str().ok()
122    }
123
124    /// Returns the character name as [`Cstr`].
125    #[inline]
126    pub fn character_c(&self) -> &CStr {
127        unsafe { CStr::from_ptr(self.character.as_ptr()) }
128    }
129
130    /// Returns the character name as [`str`].
131    #[inline]
132    pub fn character(&self) -> Option<&str> {
133        self.character_c().to_str().ok()
134    }
135
136    /// Whether the agent has been added or removed.
137    #[inline]
138    pub fn is_added(&self) -> bool {
139        self.added != 0
140    }
141
142    /// Whether the agent is the new target.
143    #[inline]
144    pub fn is_target(&self) -> bool {
145        self.target != 0
146    }
147
148    /// Whether the agent is self.
149    #[inline]
150    pub fn is_self(&self) -> bool {
151        self.is_self != 0
152    }
153}
154
155/// ArcDPS EVTC combat event data.
156#[derive(Debug)]
157#[repr(C)]
158pub struct CombatData {
159    event: *const evtc::Event,
160    src: *const Agent,
161    dst: *const Agent,
162    skill_name: *const c_char,
163    pub id: u64,
164    pub rev: u64,
165}
166
167impl CombatData {
168    /// Returns the combat data as tuple.
169    #[inline]
170    pub fn as_tuple(
171        &self,
172    ) -> (
173        Option<&evtc::Event>,
174        Option<&Agent>,
175        Option<&Agent>,
176        u64,
177        u64,
178    ) {
179        (self.event(), self.src(), self.dst(), self.id, self.rev)
180    }
181
182    /// Returns a pointer to the [`Event`].
183    #[inline]
184    pub fn event_ptr(&self) -> *const evtc::Event {
185        self.event
186    }
187
188    /// Returns the [`Event`](evtc::Event).
189    #[inline]
190    pub fn event(&self) -> Option<&evtc::Event> {
191        unsafe { self.event.as_ref() }
192    }
193
194    /// Returns a pointer to the source [`Agent`].
195    #[inline]
196    pub fn src_ptr(&self) -> *const Agent {
197        self.src
198    }
199
200    /// Returns the source [`Agent`].
201    #[inline]
202    pub fn src(&self) -> Option<&Agent> {
203        unsafe { self.src.as_ref() }
204    }
205
206    /// Returns a pointer to the destination [`Agent`].
207    #[inline]
208    pub fn dst_ptr(&self) -> *const Agent {
209        self.dst
210    }
211
212    /// Returns the destination [`Agent`].
213    #[inline]
214    pub fn dst(&self) -> Option<&Agent> {
215        unsafe { self.dst.as_ref() }
216    }
217
218    /// Returns the skill name as [`CStr`].
219    #[inline]
220    pub fn skill_name_c(&self) -> Option<&CStr> {
221        (!self.skill_name.is_null()).then(|| unsafe { CStr::from_ptr(self.skill_name) })
222    }
223
224    /// Returns the skill name as [`str`].
225    #[inline]
226    pub fn skill_name(&self) -> Option<&str> {
227        self.skill_name_c()?.to_str().ok()
228    }
229}