Macro eos_rs::patches

patches!() { /* proc-macro */ }
Expand description

This generates the entrypoints for item & move effects and special processes. This macro needs to be called exactly once and only in the main module.

Arguments

  • All but the last argument can be one of these:
    • Raw Patch
    • Item Effect
    • Move Effect
    • Special Process
  • The last argument is optional and can be ASM glue code.

Raw Patch

A raw patch that can be used any way you want. You will need to add ASM glue code that will actually branch to this patch for it to actually do anything.

The patch function MUST be extern "C", pub and be annotated with #[no_mangle]. The arguments it receives depend on the glue code / where it is inserted in the machine code of the ROM.

Raw patches must call register_logger for log macros to work.

Syntax of argument

<Function Name; Rust Identifier>

Signature of raw patch functions registered this way:

#[no_mangle] pub extern "C" fn function(/* ? */) /* -> ? */ { /* ... */ }

Can be optionally marked unsafe.

Note

At the present time, defining raw patches in this macro doesn’t actually do anything. Your patch will work just fine without it, however this could change in the future, so please add your patches.

Item Effect

Registers a function that will be called for the defined item when it is used in a dungeon.

Syntax of argument

<Function Name; Rust Identifier>: item_effect <Item ID; Literal number or Path>

Item ID is the ID of the item itself, not an internal item effect ID.

Signature of raw patch functions registered this way:

pub fn function<'a>(
    global_dungeon: &'a mut eos_rs::api::dungeon_mode::GlobalDungeonData<'a>,
    user: &mut eos_rs::api::objects::DungeonEntity,
    target: &mut eos_rs::api::objects::DungeonEntity,
    used_item: &mut eos_rs::api::objects::DungeonItem,
    is_thrown: bool
) { /* ... */ }

Move Effect

Registers a function that will be called for the defined move when it is used in a dungeon.

Syntax of argument

<Function Name; Rust Identifier>: move_effect <Move ID; Literal number or Path>

Move ID is the ID of the move itself, not an internal move effect ID.

Signature of raw patch functions registered this way:

pub fn function<'a>(
    global_dungeon: &'a mut eos_rs::api::dungeon_mode::GlobalDungeonData<'a>,
    user: &mut eos_rs::api::objects::DungeonEntity,
    target: &mut eos_rs::api::objects::DungeonEntity,
    used_move: &mut eos_rs::api::objects::Move
) { /* ... */ }

Special Process

Registers a function that can be called from the script engine using the “special process” mechanism.

Syntax of argument

<Function Name; Rust Identifier>: special_process <Process ID; Literal number>

Process ID is the ID as used in the script engine (first parameter to the ProcessSpecial opcode).

Signature of raw patch functions registered this way:

pub fn function(arg1: i16, arg2: i16, ov11: &eos_rs::api::overlay::OverlayLoadLease<11>) -> i32 { /* ... */ 0 }

ASM glue code

This is a literal string. It will later during the build process be converted into a cotpatch file that is placed in the patches/ directory of c-of-time.

See the documentation in the README.md of the c-of-time repository for more information (section Usage; on Github).

What this will generate

This will generate three functions at the place it’s called:

/// This function is called from C code of `c-of-time` (see `src/item_effects.c` in the
/// `c-of-time` repository).
/// It will select all item effects defined in this macro for the related item and call it.
/// This function will also set up the logger.
/// It will log a warning if it can't find any item effects.
///
/// NOTE: By default `src/item_effects.c` is written in a way that will only call
/// the Rust codebase, if there is no item effect already defined in C code.
#[no_mangle]
pub unsafe extern "C" fn eos_rs_apply_item_effect(
    user: *mut eos_rs::ffi::entity,
    target: *mut eos_rs::ffi::entity,
    used_item: *mut eos_rs::ffi::item,
    is_thrown: eos_rs::ffi::bool_
) -> eos_rs::ffi::bool_ { /* ... */ }

/// See `eos_rs_apply_item_effect`, this is exactly the same, but for move effects.
#[no_mangle]
pub unsafe extern "C" fn eos_rs_apply_move_effect(
    data: *mut eos_rs::ffi::move_effect_input,
    user: *mut eos_rs::ffi::entity,
    target: *mut eos_rs::ffi::entity,
    used_move: *mut eos_rs::ffi::move_
) -> eos_rs::ffi::bool_ { /* ... */ }

/// See `eos_rs_apply_item_effect`, this is exactly the same, but for special processes.
#[no_mangle]
pub unsafe extern "C" fn eos_rs_call_special_process(
    unknown: *mut eos_rs::ffi::undefined4,
    special_process_id: eos_rs::ctypes::c_uint,
    arg1: eos_rs::ctypes::c_short,
    arg2: eos_rs::ctypes::c_short,
    return_val: *mut i32
) { /* ... */ }

Example

use eos_rs_proc::patches;  // use `eos_rs::patches` from public code. The proc crate is private.

// `has_high_health`, `print_args` etc. are functions.
// See `rust/src/main.rs` in the default `c-of-time` repository for more details.
patches! {
    has_high_health,
    print_args: special_process 101,
    just_panic: special_process 102,
    oran_berry_burn: item_effect eos_rs::api::items::ItemId::ITEM_ORAN_BERRY,
    cut_badly_poisoned: eos_rs::api::moves:: MoveId::MOVE_CUT,
    "
HasLowHealth+0:
  B has_high_health
    "
}

Notes

The ASM glue code is not processed at runtime, this is done by the eos-rs-build crate during build. It will extract the ASM glue code to the patches/ directory in the c-of-time base directory (in the default configuration of the c-of-time repository.