use core::ffi::c_void;
use core::time::Duration;
use crate::abi::{Entity, Header, ItemId, KnowledgeId, PlayerKey};
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Event(pub u32);
impl Event {
pub const SETTINGS_CHANGED: Self = Self(1);
pub const LOADER_SETTINGS_CHANGED: Self = Self(2);
pub const TICKED: Self = Self(3);
pub const WORLD_LOADED: Self = Self(4);
pub const WORLD_SAVED: Self = Self(5);
pub const PLAYER_JOINED: Self = Self(6);
pub const PLAYER_LEFT: Self = Self(7);
pub const SHUTDOWN_STARTED: Self = Self(8);
pub const BUILDING_PLACED: Self = Self(9);
pub const BUILDING_REMOVED: Self = Self(10);
pub const JOIN_REFUSED: Self = Self(11);
pub const ALTARS_CHANGED: Self = Self(12);
pub const DAY_STARTED: Self = Self(13);
pub const NIGHT_STARTED: Self = Self(14);
pub const KNOWLEDGE_CHANGED: Self = Self(15);
pub const QUEST_COMPLETED: Self = Self(16);
pub const CHUNK_LOADED: Self = Self(17);
pub const CHUNK_UNLOADED: Self = Self(18);
pub const SETTINGS_REPLACED: Self = Self(19);
pub const PLAYER_DIED: Self = Self(20);
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, bytemuck::Zeroable, crate::Script)]
pub struct PlayerDeathData {
pub header: Header,
pub entity: Entity,
pub cause: u32,
pub key: PlayerKey,
pub position: [f32; 3],
pub cause_guid: [u8; 16],
pub was_deadly_fog: u8,
pub drowned: u8,
pub reserved: u16,
pub killer_entity: Entity,
pub reserved_tail: u32,
}
impl_headed!(PlayerDeathData);
impl PlayerDeathData {
pub const IMPACT: u32 = 0;
pub const FALL_DAMAGE: u32 = 1;
pub const FOG: u32 = 2;
pub const SUFFOCATED: u32 = 3;
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, bytemuck::Zeroable, crate::Script)]
pub struct KnowledgeData {
pub header: Header,
pub entity: Entity,
pub id: KnowledgeId,
pub value: u32,
}
impl_headed!(KnowledgeData);
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, bytemuck::Zeroable, crate::Script)]
pub struct QuestData {
pub header: Header,
pub entity: Entity,
pub quest: KnowledgeId,
}
impl_headed!(QuestData);
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, bytemuck::Zeroable)]
pub struct KnowledgeInput {
pub header: Header,
pub player: Entity,
pub id: KnowledgeId,
pub kind: u8,
pub scope: u8,
pub reserved: u16,
pub value: u32,
pub refusal: u32,
pub allowed: u32,
}
impl_headed!(KnowledgeInput);
impl KnowledgeInput {
pub const NO_SCOPE: u8 = 0xff;
pub const ALLOWED: u32 = 0;
pub const UNKNOWN: u32 = 1;
pub const KIND: u32 = 2;
pub const WORLD: u32 = 3;
pub const COUNTER: u32 = 4;
pub const FLAG_BIT: u32 = 5;
pub const EXPERIENCE: u32 = 6;
pub const SKILL_POINTS: u32 = 7;
pub const QUEST: u32 = 8;
}
pub type KnowledgeInputFn =
unsafe extern "system" fn(call: *const KnowledgeInput, user: *mut c_void) -> u8;
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, bytemuck::Zeroable, crate::Script)]
pub struct ChunkData {
pub header: Header,
pub index: u32,
pub x: u32,
pub z: u32,
pub size: u32,
}
impl_headed!(ChunkData);
#[repr(C)]
#[derive(Clone, Copy, Debug, bytemuck::Zeroable, crate::Script)]
pub struct BuildingData {
pub header: Header,
pub entity: Entity,
pub player: Entity,
pub item: ItemId,
pub kind: u8,
pub replay: u8,
pub template: [u8; 16],
pub position: [f32; 3],
}
impl_headed!(BuildingData);
impl BuildingData {
pub const PLACED: u8 = 0;
pub const PICKED_UP: u8 = 1;
pub const TORN_DOWN: u8 = 2;
}
#[repr(C)]
#[derive(Clone, Copy, Debug, bytemuck::Zeroable)]
pub struct PlayerInfo {
pub header: Header,
pub slot: u32,
pub entity: Entity,
pub key: PlayerKey,
pub permissions: u8,
pub name_len: u8,
pub name: [u8; 64],
}
impl_headed!(PlayerInfo);
impl PlayerInfo {
pub const CAN_KICK_BAN: u8 = 1;
pub const CAN_ACCESS_INVENTORIES: u8 = 1 << 1;
pub const CAN_EDIT_BASE: u8 = 1 << 2;
pub const CAN_EDIT_WORLD: u8 = 1 << 3;
pub const CAN_EXTEND_BASE: u8 = 1 << 4;
pub const CAN_RECEIVE_EXP: u8 = 1 << 5;
}
#[repr(C)]
#[derive(Clone, Copy, Debug, bytemuck::Zeroable, crate::Script)]
pub struct TickData {
pub header: Header,
pub step: u64,
pub elapsed_steps: u64,
pub elapsed_nanos: u64,
pub step_nanos: u64,
pub cost_nanos: u64,
}
impl_headed!(TickData);
impl TickData {
#[must_use]
pub const fn new(step: u64) -> Self {
Self {
header: Header::of::<Self>(),
step,
elapsed_steps: 1,
elapsed_nanos: 0,
step_nanos: 0,
cost_nanos: 0,
}
}
#[must_use]
pub fn with_elapsed(self, steps: u64, elapsed: Duration) -> Self {
let nanos = u64::try_from(elapsed.as_nanos()).unwrap_or(u64::MAX);
Self {
elapsed_steps: steps,
elapsed_nanos: nanos,
step_nanos: nanos / steps.max(1),
..self
}
}
#[must_use]
pub const fn elapsed(&self) -> Duration {
Duration::from_nanos(self.elapsed_nanos)
}
#[must_use]
pub const fn step_interval(&self) -> Option<Duration> {
match self.step_nanos {
0 => None,
nanos => Some(Duration::from_nanos(nanos)),
}
}
#[must_use]
pub const fn cost(&self) -> Option<Duration> {
match self.cost_nanos {
0 => None,
nanos => Some(Duration::from_nanos(nanos)),
}
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, bytemuck::Zeroable)]
pub struct TickHandle(pub u32);
#[repr(C)]
#[derive(Clone, Copy, Debug, bytemuck::Zeroable, crate::Script)]
pub struct PlayerData {
pub header: Header,
pub slot: u32,
pub entity: Entity,
pub key: PlayerKey,
}
impl_headed!(PlayerData);
pub type EventFn = unsafe extern "system" fn(event: Event, data: *const c_void, user: *mut c_void);