tes3mp_plugin/plugin/
mod.rs

1#![allow(unused)]
2
3pub mod generated;
4
5pub use generated::*;
6
7pub const LOG_VERBOSE: u16 = 0;
8pub const LOG_INFO: u16 = 1;
9pub const LOG_WARN: u16 = 2;
10pub const LOG_ERROR: u16 = 3;
11pub const LOG_FATAL: u16 = 4;
12
13pub const REGULAR: u16 = 0;
14pub const IMPERIAL_SHRINE: u16 = 1;
15pub const TRIBUNAL_TEMPLE: u16 = 2;
16
17pub const CLIENT_GAMEPLAY: u8 = 0;
18pub const CLIENT_CONSOLE: u8 = 1;
19pub const CLIENT_DIALOGUE: u8 = 2;
20pub const CLIENT_SCRIPT_LOCAL: u8 = 3;
21pub const CLIENT_SCRIPT_GLOBAL: u8 = 4;
22pub const SERVER_SCRIPT: u8 = 5;
23
24pub const NONE: u8 = 0;
25pub const DRAG: u8 = 1;
26pub const DROP: u8 = 2;
27pub const TAKE_ALL: u8 = 3;
28
29pub const ITEM: u16 = 0;
30pub const ITEM_MAGIC: u16 = 1;
31pub const MAGIC: u16 = 2;
32pub const UNASSIGNED: u16 = 3;
33
34pub const SET: u8 = 0;
35pub const ADD: u8 = 1;
36pub const REMOVE: u8 = 2;
37pub const REQUEST: u8 = 3;
38
39pub const LOAD: u16 = 0;
40pub const UNLOAD: u16 = 1;
41
42pub const RANK: u8 = 0;
43pub const EXPULSION: u8 = 1;
44pub const REPUTATION: u8 = 3;
45
46pub const ENTRY: i16 = 0;
47pub const INDEX: i16 = 1;
48
49pub const SPELL: u16 = 0;
50pub const POTION: u16 = 1;
51pub const ENCHANTMENT: u16 = 2;
52pub const NPC: u16 = 3;
53
54/// Calls a function on `EVENTS_INSTANCE` with given parameters
55#[macro_export]
56macro_rules! call_instance {
57    ($call:tt, $($argument:expr),+) => {
58        let instance = unsafe {
59            EVENTS_INSTANCE
60                .as_ref()
61                .expect(format!("No events instance created: {}\n", stringify!($call)).as_str())
62        };
63        instance.$call($($argument),+);
64        instance.on_any(stringify!($call));
65    };
66
67    ($call:tt) => {
68        let instance = unsafe {
69            EVENTS_INSTANCE
70                .as_ref()
71                .expect(format!("No events instance created: {}\n", stringify!($call)).as_str())
72        };
73        instance.$call();
74        instance.on_any(stringify!($call));
75    };
76}
77
78///
79/// create and bind C symbols to given struct, should implement Events
80///
81#[macro_export]
82macro_rules! use_events {
83    ($events:ident) => {
84        use std::ffi::CStr;
85
86        static mut EVENTS_INSTANCE: Option<$events> = None;
87
88        #[no_mangle]
89        #[allow(non_snake_case)]
90        pub fn OnServerInit() {
91            unsafe {
92                if (EVENTS_INSTANCE.is_none()) {
93                    EVENTS_INSTANCE = Some($events::new());
94                }
95            }
96
97            call_instance!(on_server_init);
98        }
99
100        #[no_mangle]
101        #[allow(non_snake_case)]
102        pub fn OnServerPostInit() {
103            call_instance!(on_server_post_init);
104        }
105
106        #[no_mangle]
107        #[allow(non_snake_case)]
108        pub fn OnServerExit(is_error: bool) {
109            call_instance!(on_server_exit, is_error);
110        }
111
112        #[no_mangle]
113        #[allow(non_snake_case)]
114        pub fn OnActorAI(player_id: u16, description: *const i8) {
115            call_instance!(on_actor_ai, player_id, unsafe {
116                CStr::from_ptr(description).to_str().unwrap_or_default()
117            });
118        }
119
120        #[no_mangle]
121        #[allow(non_snake_case)]
122        pub fn OnActorCellChange(player_id: u16, description: *const i8) {
123            call_instance!(on_actor_cell_change, player_id, unsafe {
124                CStr::from_ptr(description).to_str().unwrap_or_default()
125            });
126        }
127
128        #[no_mangle]
129        #[allow(non_snake_case)]
130        pub fn OnActorDeath(player_id: u16, description: *const i8) {
131            call_instance!(on_actor_death, player_id, unsafe {
132                CStr::from_ptr(description).to_str().unwrap_or_default()
133            });
134        }
135
136        #[no_mangle]
137        #[allow(non_snake_case)]
138        pub fn OnActorEquipment(player_id: u16, description: *const i8) {
139            call_instance!(on_actor_equipment, player_id, unsafe {
140                CStr::from_ptr(description).to_str().unwrap_or_default()
141            });
142        }
143
144        #[no_mangle]
145        #[allow(non_snake_case)]
146        pub fn OnActorList(player_id: u16, description: *const i8) {
147            call_instance!(on_actor_list, player_id, unsafe {
148                CStr::from_ptr(description).to_str().unwrap_or_default()
149            });
150        }
151
152        #[no_mangle]
153        #[allow(non_snake_case)]
154        pub fn OnActorTest(player_id: u16, description: *const i8) {
155            call_instance!(on_actor_test, player_id, unsafe {
156                CStr::from_ptr(description).to_str().unwrap_or_default()
157            });
158        }
159
160        #[no_mangle]
161        #[allow(non_snake_case)]
162        pub fn OnCellDeletion(description: *const i8) {
163            call_instance!(on_cell_deletion, unsafe {
164                CStr::from_ptr(description).to_str().unwrap_or_default()
165            });
166        }
167
168        #[no_mangle]
169        #[allow(non_snake_case)]
170        pub fn OnCellLoad(description: *const i8) {
171            call_instance!(on_cell_load, unsafe {
172                CStr::from_ptr(description).to_str().unwrap_or_default()
173            });
174        }
175
176        #[no_mangle]
177        #[allow(non_snake_case)]
178        pub fn OnCellUnload(description: *const i8) {
179            call_instance!(on_cell_unload, unsafe {
180                CStr::from_ptr(description).to_str().unwrap_or_default()
181            });
182        }
183
184        #[no_mangle]
185        #[allow(non_snake_case)]
186        pub fn OnContainer(player_id: u16, description: *const i8) {
187            call_instance!(on_container, player_id, unsafe {
188                CStr::from_ptr(description).to_str().unwrap_or_default()
189            });
190        }
191
192        #[no_mangle]
193        #[allow(non_snake_case)]
194        pub fn OnDoorState(player_id: u16, description: *const i8) {
195            call_instance!(on_door_state, player_id, unsafe {
196                CStr::from_ptr(description).to_str().unwrap_or_default()
197            });
198        }
199
200        #[no_mangle]
201        #[allow(non_snake_case)]
202        pub fn OnGUIAction(player_id: u16, message_box_id: i16, data: *const i8) {
203            call_instance!(on_gui_action, player_id, message_box_id, unsafe {
204                CStr::from_ptr(data).to_str().unwrap_or_default()
205            });
206        }
207
208        #[no_mangle]
209        #[allow(non_snake_case)]
210        pub fn OnMpNumIncrement(current_mp_num: i16) {
211            call_instance!(on_mp_num_increment, current_mp_num);
212        }
213
214        #[no_mangle]
215        #[allow(non_snake_case)]
216        pub fn OnObjectActivate(player_id: u16, description: *const i8) {
217            call_instance!(on_object_activate, player_id, unsafe {
218                CStr::from_ptr(description).to_str().unwrap_or_default()
219            });
220        }
221
222        #[no_mangle]
223        #[allow(non_snake_case)]
224        pub fn OnObjectDelete(player_id: u16, description: *const i8) {
225            call_instance!(on_object_delete, player_id, unsafe {
226                CStr::from_ptr(description).to_str().unwrap_or_default()
227            });
228        }
229
230        #[no_mangle]
231        #[allow(non_snake_case)]
232        pub fn OnObjectLock(player_id: u16, description: *const i8) {
233            call_instance!(on_object_lock, player_id, unsafe {
234                CStr::from_ptr(description).to_str().unwrap_or_default()
235            });
236        }
237
238        #[no_mangle]
239        #[allow(non_snake_case)]
240        pub fn OnObjectPlace(player_id: u16, description: *const i8) {
241            call_instance!(on_object_place, player_id, unsafe {
242                CStr::from_ptr(description).to_str().unwrap_or_default()
243            });
244        }
245
246        #[no_mangle]
247        #[allow(non_snake_case)]
248        pub fn OnObjectScale(player_id: u16, description: *const i8) {
249            call_instance!(on_object_scale, player_id, unsafe {
250                CStr::from_ptr(description).to_str().unwrap_or_default()
251            });
252        }
253
254        #[no_mangle]
255        #[allow(non_snake_case)]
256        pub fn OnObjectSpawn(player_id: u16, description: *const i8) {
257            call_instance!(on_object_spawn, player_id, unsafe {
258                CStr::from_ptr(description).to_str().unwrap_or_default()
259            });
260        }
261
262        #[no_mangle]
263        #[allow(non_snake_case)]
264        pub fn OnObjectState(player_id: u16, description: *const i8) {
265            call_instance!(on_object_state, player_id, unsafe {
266                CStr::from_ptr(description).to_str().unwrap_or_default()
267            });
268        }
269
270        #[no_mangle]
271        #[allow(non_snake_case)]
272        pub fn OnObjectTrap(player_id: u16, description: *const i8) {
273            call_instance!(on_object_trap, player_id, unsafe {
274                CStr::from_ptr(description).to_str().unwrap_or_default()
275            });
276        }
277
278        #[no_mangle]
279        #[allow(non_snake_case)]
280        pub fn OnPlayerAttribute(player_id: u16) {
281            call_instance!(on_player_attribute, player_id);
282        }
283
284        #[no_mangle]
285        #[allow(non_snake_case)]
286        pub fn OnPlayerBook(player_id: u16) {
287            call_instance!(on_player_book, player_id);
288        }
289
290        #[no_mangle]
291        #[allow(non_snake_case)]
292        pub fn OnPlayerBounty(player_id: u16) {
293            call_instance!(on_player_bounty, player_id);
294        }
295
296        #[no_mangle]
297        #[allow(non_snake_case)]
298        pub fn OnPlayerCellChange(player_id: u16) {
299            call_instance!(on_player_cell_change, player_id);
300        }
301
302        #[no_mangle]
303        #[allow(non_snake_case)]
304        pub fn OnPlayerConnect(player_id: u16) {
305            call_instance!(on_player_connect, player_id);
306        }
307
308        #[no_mangle]
309        #[allow(non_snake_case)]
310        pub fn OnPlayerDeath(player_id: u16) {
311            call_instance!(on_player_death, player_id);
312        }
313
314        #[no_mangle]
315        #[allow(non_snake_case)]
316        pub fn OnPlayerDisconnect(player_id: u16) {
317            call_instance!(on_player_disconnect, player_id);
318        }
319
320        #[no_mangle]
321        #[allow(non_snake_case)]
322        pub fn OnPlayerDisposition(player_id: u16) {
323            call_instance!(on_player_disposition, player_id);
324        }
325
326        #[no_mangle]
327        #[allow(non_snake_case)]
328        pub fn OnPlayerEndCharGen(player_id: u16) {
329            call_instance!(on_player_end_char_gen, player_id);
330        }
331
332        #[no_mangle]
333        #[allow(non_snake_case)]
334        pub fn OnPlayerEquipment(player_id: u16) {
335            call_instance!(on_player_equipment, player_id);
336        }
337
338        #[no_mangle]
339        #[allow(non_snake_case)]
340        pub fn OnPlayerFaction(player_id: u16) {
341            call_instance!(on_player_faction, player_id);
342        }
343
344        #[no_mangle]
345        #[allow(non_snake_case)]
346        pub fn OnPlayerInput(player_id: u16) {
347            call_instance!(on_player_input, player_id);
348        }
349
350        #[no_mangle]
351        #[allow(non_snake_case)]
352        pub fn OnPlayerInventory(player_id: u16) {
353            call_instance!(on_player_inventory, player_id);
354        }
355
356        #[no_mangle]
357        #[allow(non_snake_case)]
358        pub fn OnPlayerItemUse(player_id: u16) {
359            call_instance!(on_player_item_use, player_id);
360        }
361
362        #[no_mangle]
363        #[allow(non_snake_case)]
364        pub fn OnPlayerJournal(player_id: u16) {
365            call_instance!(on_player_journal, player_id);
366        }
367
368        #[no_mangle]
369        #[allow(non_snake_case)]
370        pub fn OnPlayerLevel(player_id: u16) {
371            call_instance!(on_player_level, player_id);
372        }
373
374        #[no_mangle]
375        #[allow(non_snake_case)]
376        pub fn OnPlayerMiscellaneous(player_id: u16) {
377            call_instance!(on_player_miscellaneous, player_id);
378        }
379
380        #[no_mangle]
381        #[allow(non_snake_case)]
382        pub fn OnPlayerQuickKeys(player_id: u16) {
383            call_instance!(on_player_quick_keys, player_id);
384        }
385
386        #[no_mangle]
387        #[allow(non_snake_case)]
388        pub fn OnPlayerReputation(player_id: u16) {
389            call_instance!(on_player_reputation, player_id);
390        }
391
392        #[no_mangle]
393        #[allow(non_snake_case)]
394        pub fn OnPlayerRest(player_id: u16) {
395            call_instance!(on_player_rest, player_id);
396        }
397
398        #[no_mangle]
399        #[allow(non_snake_case)]
400        pub fn OnPlayerResurrect(player_id: u16) {
401            call_instance!(on_player_resurrect, player_id);
402        }
403
404        #[no_mangle]
405        #[allow(non_snake_case)]
406        pub fn OnPlayerSendMessage(player_id: u16, message: *const i8) {
407            call_instance!(on_player_send_message, player_id, unsafe {
408                CStr::from_ptr(message).to_str().unwrap_or_default()
409            });
410        }
411
412        #[no_mangle]
413        #[allow(non_snake_case)]
414        pub fn OnPlayerShapeshift(player_id: u16) {
415            call_instance!(on_player_shapeshift, player_id);
416        }
417
418        #[no_mangle]
419        #[allow(non_snake_case)]
420        pub fn OnPlayerSkill(player_id: u16) {
421            call_instance!(on_player_skill, player_id);
422        }
423
424        #[no_mangle]
425        #[allow(non_snake_case)]
426        pub fn OnPlayerSpellbook(player_id: u16) {
427            call_instance!(on_player_spellbook, player_id);
428        }
429
430        #[no_mangle]
431        #[allow(non_snake_case)]
432        pub fn OnPlayerTopic(player_id: u16) {
433            call_instance!(on_player_topic, player_id);
434        }
435
436        #[no_mangle]
437        #[allow(non_snake_case)]
438        pub fn OnRecordDynamic(player_id: u16) {
439            call_instance!(on_record_dynamic, player_id);
440        }
441
442        #[no_mangle]
443        #[allow(non_snake_case)]
444        pub fn OnRequestDataFileList() {
445            call_instance!(on_request_data_file_list);
446        }
447
448        #[no_mangle]
449        #[allow(non_snake_case)]
450        pub fn OnScriptGlobalShort(player_id: u16) {
451            call_instance!(on_script_global_short, player_id);
452        }
453
454        #[no_mangle]
455        #[allow(non_snake_case)]
456        pub fn OnServerScriptCrash(error: *const i8) {
457            call_instance!(on_server_script_crash, unsafe {
458                CStr::from_ptr(error).to_str().unwrap_or_default()
459            });
460        }
461
462        #[no_mangle]
463        #[allow(non_snake_case)]
464        pub fn OnVideoPlay(player_id: u16, description: *const i8) {
465            call_instance!(on_video_play, player_id, unsafe {
466                CStr::from_ptr(description).to_str().unwrap_or_default()
467            });
468        }
469
470        #[no_mangle]
471        #[allow(non_snake_case)]
472        pub fn OnWorldKillCount(player_id: u16) {
473            call_instance!(on_world_kill_count, player_id);
474        }
475
476        #[no_mangle]
477        #[allow(non_snake_case)]
478        pub fn OnWorldMap(player_id: u16) {
479            call_instance!(on_world_map, player_id);
480        }
481
482        #[no_mangle]
483        #[allow(non_snake_case)]
484        pub fn OnWorldWeather(player_id: u16) {
485            call_instance!(on_world_weather, player_id);
486        }
487    };
488}
489
490/// Trait implementing all known events TES3MP server can trigger
491pub trait Events: Sized {
492    fn new() -> Self;
493    fn on_any(&self, event_name: &str) {}
494
495    fn on_actor_ai(&self, player_id: u16, description: &str) {}
496    fn on_actor_cell_change(&self, player_id: u16, description: &str) {}
497    fn on_actor_death(&self, player_id: u16, description: &str) {}
498    fn on_actor_equipment(&self, player_id: u16, description: &str) {}
499    fn on_actor_list(&self, player_id: u16, description: &str) {}
500    fn on_actor_test(&self, player_id: u16, description: &str) {}
501
502    fn on_cell_deletion(&self, description: &str) {}
503    fn on_cell_load(&self, description: &str) {}
504    fn on_cell_unload(&self, description: &str) {}
505
506    fn on_container(&self, player_id: u16, description: &str) {}
507    fn on_door_state(&self, player_id: u16, description: &str) {}
508
509    fn on_gui_action(&self, player_id: u16, message_box_id: i16, data: &str) {}
510
511    fn on_mp_num_increment(&self, current_mp_num: i16) {}
512
513    fn on_object_activate(&self, player_id: u16, description: &str) {}
514    fn on_object_delete(&self, player_id: u16, description: &str) {}
515    fn on_object_lock(&self, player_id: u16, description: &str) {}
516    fn on_object_place(&self, player_id: u16, description: &str) {}
517    fn on_object_scale(&self, player_id: u16, description: &str) {}
518    fn on_object_spawn(&self, player_id: u16, description: &str) {}
519    fn on_object_state(&self, player_id: u16, description: &str) {}
520    fn on_object_trap(&self, player_id: u16, description: &str) {}
521
522    fn on_player_attribute(&self, player_id: u16) {}
523    fn on_player_book(&self, player_id: u16) {}
524    fn on_player_bounty(&self, player_id: u16) {}
525    fn on_player_cell_change(&self, player_id: u16) {}
526    fn on_player_connect(&self, player_id: u16) {}
527    fn on_player_death(&self, player_id: u16) {}
528    fn on_player_disconnect(&self, player_id: u16) {}
529    fn on_player_disposition(&self, player_id: u16) {}
530    fn on_player_end_char_gen(&self, player_id: u16) {}
531    fn on_player_equipment(&self, player_id: u16) {}
532    fn on_player_faction(&self, player_id: u16) {}
533    fn on_player_input(&self, player_id: u16) {}
534    fn on_player_inventory(&self, player_id: u16) {}
535    fn on_player_item_use(&self, player_id: u16) {}
536    fn on_player_journal(&self, player_id: u16) {}
537    fn on_player_level(&self, player_id: u16) {}
538    fn on_player_miscellaneous(&self, player_id: u16) {}
539    fn on_player_quick_keys(&self, player_id: u16) {}
540    fn on_player_reputation(&self, player_id: u16) {}
541    fn on_player_rest(&self, player_id: u16) {}
542    fn on_player_resurrect(&self, player_id: u16) {}
543    fn on_player_send_message(&self, player_id: u16, message: &str) {}
544    fn on_player_shapeshift(&self, player_id: u16) {}
545    fn on_player_skill(&self, player_id: u16) {}
546    fn on_player_spellbook(&self, player_id: u16) {}
547    fn on_player_topic(&self, player_id: u16) {}
548
549    fn on_record_dynamic(&self, player_id: u16) {}
550
551    fn on_request_data_file_list(&self) {}
552
553    fn on_script_global_short(&self, player_id: u16) {}
554
555    fn on_server_exit(&self, is_error: bool) {}
556    fn on_server_init(&self) {}
557    fn on_server_post_init(&self) {}
558    fn on_server_script_crash(&self, error: &str) {}
559
560    fn on_video_play(&self, player_id: u16, description: &str) {}
561
562    fn on_world_kill_count(&self, player_id: u16) {}
563    fn on_world_map(&self, player_id: u16) {}
564    fn on_world_weather(&self, player_id: u16) {}
565}