Skip to content

EN UO Topic magic

Codex edited this page Oct 12, 2026 · 4 revisions

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

Magic

Home · C# · IDE · UO API · A–Z · Examples · Languages

Spells, abilities and movement with magic. For targeted action, set the target in advance and check the application conditions.

Spells: all names and numbers

Open full catalog and examples

Sections

Topic Commands and explanations
Cast UO.Cast
CastToObject UO.CastToObject
CastAbility UO.CastAbility
Active Spell Ability UO.IsActiveSpellAbility
Spell Timers UO.TicksSpell

All theme commands

Casting

UO.Cast · UO.CastToObject · UO.CastAbility · UO.IsActiveSpellAbility · UO.TicksSpell

Travel

UO.AddRecall · UO.AddGate

Examples on the topic

Each command card has several independent scenarios: direct code, functions and classes. Below are selected short scenarios; restrictions and full analysis are in the cards.

UO.Cast

Parameters, result and all scenarios

UO.CancelWaitTarget();
if (Truth(UO.Cast("Cure")))
{
    UO.Print("Choose the character with the spell cursor");
}
else
{
    UO.Print("Cure request rejected");
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

UO.CastToObject

Parameters, result and all scenarios

var accepted = UO.CastToObject("Heal", "self");
UO.Print(Convert.ToString(accepted));

Complete command reference


UO.AddGate

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

void UO.AddGate(object? bookSerial);

Parameters

  • bookSerial is an identifier value that the compatible script saves as a legacy list entry. At the current runtime, the value is serialized to a string; The command does not check for the existence of an object in the world.

Return value

void. The team does not confirm the availability of the book or the creation of the game portal.

Behavior

  • The value is added to the list AddGate of the current runtime state. In ClassicUO, this compatibility-list does not trigger a game action and does not have a documented public getter to read.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The command is a separate statement. The message before it marks the start of the call; it does not confirm a server action.

UO.Print("Calling UO.AddGate");
UO.AddGate("0x40012345");

1. Save the ID as legacy data without opening the gate. - direct script

Parameters and execution flow:

  • Save the ID as legacy data without opening the gate.
UO.AddGate("0x40012345");

2. Use the value from the string passed to a compatible script. - script function

Parameters and execution flow:

  • Use the value from the string passed to a compatible script.
return  RunScenario();
 object? RunScenario()
{
    var bookSerial = "0x40012345";
    UO.AddGate(bookSerial);
    return null;
}

3. Write the value to the runtime list AddGate. - script class

Parameters and execution flow:

  • Write the value to the runtime list AddGate.
  • The call stores compatibility data; he doesn't use the book in the world.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        RememberGateBook("0x40012345");
        return null;
    }

    void RememberGateBook(dynamic bookSerial)
    {
        UO.AddGate(bookSerial);
    }
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.AddGate(bookSerial) — UO.AddGate(Any)

Parameters: bookSerial (Any)

Result: void / Unit.

During a call:

Internal implementation code; this is not a standalone script.

case "adddir":

                case "addfindlist":

                case "addgate":

                case "addrecall":

                case "addstep":

                    LegacyList(name).Add(string.Join("|", arguments.Select(value => value.ToString())));

                    break;

UO.AddRecall

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

void UO.AddRecall(object? bookSerial);

Parameters

  • bookSerial is an identifier value that the compatible script saves as a legacy list entry. Runtime serializes the passed value into a string.

Return value

void. The call does not return a result and does not confirm the presence of the book.

Behavior

  • The value is added to the list AddRecall of the current runtime state. In ClassicUO, this compatibility-list itself does not send game commands and does not have a documented public getter to read.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The command is a separate statement. The message before it marks the start of the call; it does not confirm a server action.

UO.Print("Calling UO.AddRecall");
UO.AddRecall("0x40012345");

1. Save the value as compatibility data, do not run Recall. - direct script

Parameters and execution flow:

  • Save the value as compatibility data, do not run Recall.
UO.AddRecall("0x40012345");

2. Pass the identifier via a string variable. - script function

Parameters and execution flow:

  • Pass the identifier via a string variable.
return  RunScenario();
 object? RunScenario()
{
    var bookSerial = "0x40012345";
    UO.AddRecall(bookSerial);
    return null;
}

3. Each call adds a separate entry to AddRecall of the current runtime. - script class

Parameters and execution flow:

  • Each call adds a separate entry to AddRecall of the current runtime.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        UO.AddRecall("0x40012345");
        UO.AddRecall("0x40012346");
        return null;
    }
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.AddRecall(bookSerial) — UO.AddRecall(Any)

Parameters: bookSerial (Any)

Result: void / Unit.

During a call:

Internal implementation code; this is not a standalone script.

case "adddir":

                case "addfindlist":

                case "addgate":

                case "addrecall":

                case "addstep":

                    LegacyList(name).Add(string.Join("|", arguments.Select(value => value.ToString())));

                    break;

UO.Cast

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

int UO.Cast(object? spellName);

Requests the use of a spell by name. Exactly one parameter: spellName, for example UO.Cast("Heal"). The target is selected separately: with the mouse using the appeared crosshair or via WaitTargetObject before Cast. Accepting a request does not confirm a successful effect.

Parameters

  • spellName - Required line - the English name of the spell in quotes: "Heal", "Cure", "Greater Heal". Names are not translated along with the interface. The dictionary also recognizes built-in aliases and spell words. The numeric ID, including the string "29", target, distance, notoriety, maxZ and wait are not Cast parameters. All names and schools.

Return value

int: 1/true—the client accepted the request; 0/false - the name is not recognized or the request is locally rejected. You can write if UO.Cast("Heal") { ... } or compare with 1/true. These are not ID spells or proof of healing/damage. A missing or extra argument causes an error. The command does not expect aiming and completion of the spell.

Behavior

  • Single form: UO.Cast(spellName). There are no second or subsequent arguments. Searching for a target, preparing a response, waiting, and clearing are performed by separate commands.
  • To manually select, clear your previous queue CancelWaitTarget, call Cast and click the desired object with your crosshair. The Cast itself does not clear the queue: the script could have prepared it in advance.
  • For an automatic target, first call WaitTargetObject(serial/alias), then Cast(name). This order allows you to respond to the server's quick aim. For spells without a target cursor, do not prepare an answer.
  • The server determines the spell's availability, resources, valid target, range, and effect. A positive result only confirms local acceptance of the request.
  • The prepared queue may remain unattended if the server fails. Remove it CancelWaitTarget after limited wait or local failure. Do not run other scripts in parallel with target.
  • An accepted request updates TicksSpell. Cast does not wait for animation, healing or change HP. The catalog ID explains the internal protocol, but does not replace the name in the argument.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

var result = UO.Cast("Cure");
UO.Print("Cast: " + Convert.ToString(result));

1. Cure: select target with mouse - direct script

Parameters and execution flow:

  • Cure is the only argument to Cast. After launch, select the character with the game sight. Check the server failure and the result in the game.
UO.CancelWaitTarget();
if (Truth(UO.Cast("Cure")))
{
    UO.Print("Choose the character with the spell cursor");
}
else
{
    UO.Print("Cure request rejected");
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Heal: separate target for yourself - script function

Parameters and execution flow:

  • self — argument WaitTargetObject; Heal is the only argument to Cast. 3000 - three seconds to aim in this example, not a guarantee of healing completion. Finally deletes the remaining response and on failure.
return await RunScenarioAsync();
async Task<object?> RunScenarioAsync()
{
    UO.CancelWaitTarget();
    try
    {
        UO.WaitTargetObject("self");
        if (Truth(UO.Cast("Heal")))
        {
            await Delay(3000);
        }
    }
    finally
    {
        UO.CancelWaitTarget();
    }

    return null;
}

Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Full function for selected ally - scenario class

Parameters and execution flow:

  • spellName, target, cleanupDelayMs - parameters of your function CastAtObject, not overload UO.Cast. Internally, Cast only accepts spellName. ASC converts string ID to a number; 4000 — queue clearing delay. true means acceptance of the request, not success of the treatment.

Spells / Spells

Spells/Spells

return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        var target = Asc(UO.GetSerial("lasttarget"), 0);
        if (Truth(await CastAtObject("Greater Heal", target, 4000)))
        {
            UO.Print("Request sent; verify healing in the game");
        }

        return null;
    }

    async Task<dynamic> CastAtObject(dynamic spellName, dynamic target, dynamic cleanupDelayMs)
    {
        if (!(Truth(UO.Connected())) || Truth(UO.Dead()) || Truth(target <= 0) || !(Truth(UO.Exists(target))))
        {
            return false;
        }

        dynamic accepted = false;
        UO.CancelWaitTarget();
        try
        {
            UO.WaitTargetObject(target);
            accepted = UO.Cast(spellName);
            if (Truth(accepted))
            {
                await Delay(cleanupDelayMs);
            }
        }
        finally
        {
            UO.CancelWaitTarget();
        }

        return accepted;
    }

    int Asc(object? value, int fallback = 0)
    {
        string text = Convert.ToString(value) ?? "";
        if (text.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
            return int.TryParse(text[2..], System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out int hex) ? hex : fallback;
        return int.TryParse(text, out int number) ? number : fallback;
    }

    Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.Cast(spellName) — UO.Cast(String)

Parameters: spellName (String)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

public int Cast(string spellName)

        {

            if (NumberConversions.TryStr2Int((spellName ?? string.Empty).Trim(), out _))

            {

                SystemMessage("UO.Cast: use one spell name, for example UO.Cast(\"Heal\").");

                return 0;

            }

            return CastCore(spellName) ? 1 : 0;

        }

UO.CastAbility

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

int UO.CastAbility(object? abilityId);

Toggles the currently selected ability of the current weapon via UseAbility: Calling an already selected ability again deselects it.

Parameters

  • abilityId — Ability name or number string resolved by ResolveClassicUOAbilityId; the unknown value gives 0.

Return value

int 1 — the client called the current primary/secondary ability; 0 - no character, unknown ID or the ability does not match the current weapon.

Behavior

  • 1 describes the acceptance of a client request, rather than a successful hit or write-off of resources by the server. ID, which is not the current primary/secondary ability, returns 0 even if it is in the directory.
  • GameActions.UsePrimaryAbility/UseSecondaryAbility check the 0x80 bit. When the bit is off, deselect the other option and send the selected ability; when already enabled, send ID 0 to disable. Then the bit is switched. Returning 1 confirms the call to this client branch, including shutdown.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

var result = UO.CastAbility(UO.GetAbilityID("Armor Ignore"));
UO.Print("CastAbility: " + Convert.ToString(result));

1. Resolve Ability Name - Direct Script

Parameters and execution flow:

  • Availability in the catalog is separate from weapon matching.
var id = UO.GetAbilityID("Armor Ignore");
if (Truth(id > 0))
{
    var accepted = UO.CastAbility(id);
    UO.Print(Convert.ToString(accepted));
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Call by name - script function

Parameters and execution flow:

  • The name resolves to ID and is checked against the current weapon.
return  RunScenario();
 object? RunScenario()
{
    var accepted = UO.CastAbility("Armor Ignore");
    UO.Print(Convert.ToString(accepted));
    return null;
}

3. Invalid ID - script class

Parameters and execution flow:

  • Zero is outside the directory and returns 0 without activation.

Spells / Spells

Spells/Spells

return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var accepted = UO.CastAbility(0);
        UO.Print(Convert.ToString(accepted));
        return null;
    }
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.CastAbility(abilityId) — UO.CastAbility(Integer)

Parameters: abilityId (Integer/String)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

public int UseAbility(int abilityId) => bridge.UseAbility(abilityId);

UO.CastAbility(abilityId) — UO.CastAbility(String)

Parameters: abilityId (Integer/String)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

public int UseAbility(string abilityName)

        {

            int abilityId = bridge.ResolveAbility(abilityName);

            return abilityId > 0 ? bridge.UseAbility(abilityId) : 0;

        }

UO.CastToObject

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

dynamic UO.CastToObject(object? spellName, object? objID);

Places a waiting object target and sends a spell by name or numeric ID.

Parameters

  • spellName - string with the name of the spell, including underscore instead of a space, or numeric ID for bridge.Cast.
  • objID — Serial of the object or supported name of self/backpack/lasttarget/saved object; numeric strings and 0x strings are resolved by runtime.

Return value

int/boolean result 1 — the client accepted the Cast request; 0 — request rejected. The success of the spell is not confirmed by the server.

Behavior

  • The string form goes through CastAtTarget; the numeric form puts WaitTargetObject, then bridge.Cast. If Cast fails, the pending target is canceled. Upon acceptance, ticksSpell is updated.
  • Bridge rejects non-positive spellId, no connection and dead character. The timer marks the sending, not the end of the cast; the result of the impact on the object depends on the server.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

object? result = UO.CastToObject("Heal", "self");
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Treat yourself - direct script

Parameters and execution flow:

  • Heal makes self the target of the next server cursor.
var accepted = UO.CastToObject("Heal", "self");
UO.Print(Convert.ToString(accepted));

2. Numeric ID - script function

Parameters and execution flow:

  • The numeric form passes ID 4 to the client; 1 means sending a request.
return  RunScenario();
 object? RunScenario()
{
    var accepted = UO.CastToObject(4, UO.Self());
    UO.Print(Convert.ToString(accepted));
    return null;
}

3. Check Selected Object - Script Class

Parameters and execution flow:

  • Local existence check helps avoid using a missing lasttarget.

Spells / Spells

Spells/Spells

return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var target = UO.LastTarget();
        if (Truth(UO.Exists(target)))
        {
            var accepted = UO.CastToObject("Greater Heal", target);
            UO.Print(Convert.ToString(accepted));
        }

        return null;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.CastToObject(spellName, objID) — UO.CastToObject(Any,Any)

Parameters: spellName (Any), objID (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "casttoobject":

                    if (arguments[0].Kind == InjectionValueKind.String)

                        return CastAtTarget(arguments[0], arguments[1]) != 0 ? InjectionValue.True : InjectionValue.False;



                    WaitTargetObject(Arg(1));

                    int castAccepted = bridge.Cast(Arg(0));

                    if (castAccepted != 0)

                    {

                        ticksSpell = Timer();

                        return InjectionValue.True;

                    }



                    bridge.CancelTarget();

                    return InjectionValue.False;

UO.IsActiveSpellAbility

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

dynamic UO.IsActiveSpellAbility(object? spellName);

Checks whether the server has reported the active state of the selected ability/spell. Useful before reactivating a channeled ability. It does not turn on anything, does not cast or select a target.

Parameters

  • spellName - The only required parameter: an English name from the spell catalog or the whole ID. For example, "Confidence" and 402 stand for the same Bushido spell. Case is not important; underscores in the name are replaced with spaces. The number line is also recognized. Do not pass ID character, item type or skill number.

Return value

int: 1 - the server reported the active state of this ID; 0 - there is no such active state now. In C# check the numerical result: if (UO.IsActiveSpellAbility(402) != 0) { ... }. This is a logical sign, not the number, time or result of the last cast. Unknown name, ID outside 1…65535 and no resulting state also give 0.

Behavior

  • The list updates the server package 0xBF/0x25: enabling adds ID, disabling removes it. Works without a graphics window and without a spell button on the screen. Closing a window saves the state; breaking the connection clears it. Answering 0 does not prove that the character is unable to cast the spell. The server should send this status; This is not a universal check for all buffs. For instant Heal/Recall, such an example does not confirm a successful cast. The spell's duration, remaining mana, availability, and success are not determined by this command.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

object? result = UO.IsActiveSpellAbility(402);
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Checking status using ID - direct script

Parameters and execution flow:

  • 402 - ID Confidence. The active variable contains either 1 or 0; true here is equivalent to 1. The message describes the received status, not the result of the cast attempt.
var active = UO.IsActiveSpellAbility(402);
if (Truth(Truth(active) == true))
{
    UO.Print("Confidence is active");
}
else
{
    UO.Print("No active Confidence state received");
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Don't Repeat Active Ability - Script Function

Parameters and execution flow:

  • "Confidence" - the same ID 402. Cast only accepts the name. The request is sent once if there is no active status; it does not guarantee success on the server. Do not run this snippet in a fast loop; the server response may be delayed.
return  RunScenario();
 object? RunScenario()
{
    if (Truth(UO.IsActiveSpellAbility("Confidence") == 0))
    {
        UO.Cast("Confidence");
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Waiting for Acknowledgment with Limit - Script Class

Parameters and execution flow:

  • spell - name or ID; expected - true to enable, false to disable; timeoutMs — wait limit in milliseconds. Main waits until 500 ms with checks every 25 ms and does not cast anything. The function returns true if there is a match, false otherwise. This is a limited expectation of a local state, not a proof of the reason for its change; actual time may increase if the script is paused or under load.

Spells / Spells

Spells/Spells

return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        if (Truth(WaitAbilityState("Confidence", true, 500)))
        {
            UO.Print("Active state received");
        }
        else
        {
            UO.Print("No active state before timeout");
        }

        return null;
    }

    dynamic WaitAbilityState(dynamic spell, dynamic expected, dynamic timeoutMs)
    {
        var elapsed = 0;
        while (Truth(elapsed < timeoutMs))
        {
            if (Truth((UO.IsActiveSpellAbility(spell) == 1) == expected))
            {
                return true;
            }

            UO.Wait(25);
            elapsed = elapsed + 25;
        }

        return Truth((UO.IsActiveSpellAbility(spell) == 1) == expected);
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.IsActiveSpellAbility(spellName) — UO.IsActiveSpellAbility(Any)

Parameters: spellName (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "isactivespellability":

                {

                    int? spellId = arguments[0].Kind == InjectionValueKind.String

                        ? ConvertSpellName(Text(0).Replace('_', ' '))

                        : (int?)Arg(0);

                    return new InjectionValue(spellId.HasValue ? bridge.IsActiveSpell(spellId.Value) : 0);

                }

UO.TicksSpell

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

int UO.TicksSpell();

Reads the saved mark TicksSpell.

Parameters

There are no parameters.

Return value

int — mark UO.Timer in tenths of a second from the start of runtime. 0 - the mark has not yet been set or the event occurred in the first tenth of a second; it is not milliseconds or calendar time.

Behavior

  • Returns the field ticksSpell. It is updated by the successfully accepted Cast/CastAtTarget; it is not automatic observation of all manual/server activities. The command itself does not change the mark.
  • UO.Timer() - the mark calculates the age in tenths of a second. Marks are not compared between different runtimes.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

var result = UO.TicksSpell();
UO.Print("TicksSpell: " + Convert.ToString(result));

1. Direct call - direct script

Parameters and execution flow:

  • Reads the saved mark TicksSpell.
var stamp = UO.TicksSpell();
UO.Print(stamp);

2. Explicit option - script function

Parameters and execution flow:

  • Returns the field ticksSpell. It is updated by the successfully accepted Cast/CastAtTarget; it is not automatic observation of all manual/server activities. The command itself does not change the mark.
return  RunScenario();
 object? RunScenario()
{
    var stamp = UO.TicksSpell();
    var ageTenths = UO.Timer() - stamp;
    UO.Print(ageTenths);
    return null;
}

3. Full Helper Function - Script Class

Parameters and execution flow:

  • UO.Timer() - the mark calculates the age in tenths of a second. Marks are not compared between different runtimes.

Spells / Spells

Spells/Spells

return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var before = UO.TicksSpell();
        UO.Wait(250);
        var after = UO.TicksSpell();
        UO.Print(before = after);
        return null;
    }
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.TicksSpell() — UO.TicksSpell()

Parameters: No parameters.

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

public int TicksSpell() => ticksSpell;

Clone this wiki locally