EN UO Topic skills - LIHACHTETAN/ClassicUO-Bad-Newbie-CSharp-Scripts-IDE GitHub Wiki
Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
Home · C# · IDE · UO API · A–Z · Examples · Languages
Applying skills, reading values and managing skill locks. The name of the skill and the availability of the action depend on the data supported by the client/server.
Open full catalog and examples
| Topic | Commands and explanations |
|---|---|
| UseSkill | UO.UseSkill |
| Skill Value | UO.GetSkillValue · UO.SkillVal |
| Skill Current Value | UO.GetSkillCurrentValue |
| Skill Cap | UO.GetSkillCap |
| Skill Locks | UO.GetSkillLockState · UO.SetSkillLockState |
| Tracking | UO.Track |
| Snooping | UO.Snoop |
| Stealth | UO.StealthCnt · UO.UseSkill |
UO.UseSkill · UO.GetSkillCap · UO.GetSkillCurrentValue · UO.GetSkillValue · UO.GetSkillLockState · UO.SetSkillLockState · UO.SkillLockState · UO.SkillVal · UO.Track · UO.Snoop · UO.StealthCnt · UO.TicksSkill
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.
Parameters, result and all scenarios
if (!(Truth(UO.Connected())) || Truth(UO.Dead()) || Truth(UO.Hidden()))
{
return null;
}
if (!(Truth(UO.UseSkill("Hiding"))))
{
UO.Print("Hiding request rejected");
return null;
}
await Delay(1000);
if (Truth(UO.Hidden()))
{
UO.Print("Character is hidden");
}
else
{
UO.Print("Not hidden yet; check the game journal");
}
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;Parameters, result and all scenarios
var selector = "Mining";
var value = UO.GetSkillValue(selector);
UO.Print(Convert.ToString(value));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
double UO.GetSkillCap(object? skillName);Reads the skill limit received from the server.
-
skillName- Required skill: a name from the client data, such as "Mining" or "Animal Lore", or a decimal index from 0 to Skills.Length−1, number or string. The case of the name is not important, trailing spaces are removed, _ is replaced with a space. The index is not the ID of the subject or the index from 1. A number string always means an index.
double (Double) - skill points in increments of 0,1, for example 95,1, not 951. The CapFixed field is divided by 10 directly into the Double. 0 means zero skill or no character/skill. The result is not bool. Legacy SkillVal/BaseVal have a different scale - do not mix these families.
- Reading is performed via Invoke on the game thread based on the data already received; network packets are not sent. The skill is not used or trained. Two requests - two separate snapshots.
- Required skill: a name from the client data, such as "Mining" or "Animal Lore", or a decimal index from 0 to Skills.Length−1, number or string. The case of the name is not important, trailing spaces are removed, _ is replaced with a space. The index is not the ID of the subject or the index from 1. A number string always means an index.
- ExecuteClientApiCompatibility selects the command branch. Text reads the skill selector, Arg reads the numeric numbers and modes. An unconvertible argument may fail the call with a conversion error.
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.
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.GetSkillCap("Mining");
UO.Print("GetSkillCap: " + Convert.ToString(result));Parameters and execution flow:
- In the example, selector and, when recording, mode are explicitly specified. The first line selects a skill by name or a characteristic by number. Print only prints the result.
var selector = "Mining";
var value = UO.GetSkillCap(selector);
UO.Print(Convert.ToString(value));Parameters and execution flow:
- The threshold 95.1 and modes 0/1/2 are given as an example. −1 is checked before changing mode. After writing, only the local copy is read; it's not waiting for the server to respond.
return RunScenario();
object? RunScenario()
{
if (Truth(UO.GetSkillLockState("Mining") >= 0))
{
var value = UO.GetSkillCap("Mining");
if (Truth(value >= 95.1))
{
UO.Print("Value >= 95.1: " + Convert.ToString(value));
}
}
return null;
}
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;Parameters and execution flow:
- All the helper code is given below Main. selector selects a skill/characteristic, mode sets the recording mode. ReadValue/ReadMode return the original number; ApplyMode checks the arguments, performs the action, and does not return a value. UO.Wait(1000) in the reading example separates two pictures.
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 before = ReadValue("Animal_Lore");
await Delay(1000);
var after = ReadValue("Animal Lore");
UO.Print(Convert.ToString(after - before));
return null;
}
dynamic ReadValue(dynamic selector)
{
return UO.GetSkillCap(selector);
}
Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
}C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
Parameters: skillName (Any)
Result: double / Decimal.
During a call:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetSkillValue:bridge.GetSkillValue(Text(0), false, true). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Text:Text(0).
Internal implementation code; this is not a standalone script.
case "getskillcap": return new InjectionValue(bridge.GetSkillValue(Text(0), false, true));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
double UO.GetSkillCurrentValue(object? skillName);Reads the effective value of the skill with modifiers.
-
skillName- Required skill: a name from the client data, such as "Mining" or "Animal Lore", or a decimal index from 0 to Skills.Length−1, number or string. The case of the name is not important, trailing spaces are removed, _ is replaced with a space. The index is not the ID of the subject or the index from 1. A number string always means an index.
double (Double) - skill points in increments of 0,1, for example 95,1, not 951. The ValueFixed field is divided by 10 directly into the Double. 0 means zero skill or no character/skill. The result is not bool. Legacy SkillVal/BaseVal have a different scale - do not mix these families.
- Reading is performed via Invoke on the game thread based on the data already received; network packets are not sent. The skill is not used or trained. Two requests - two separate snapshots.
- Required skill: a name from the client data, such as "Mining" or "Animal Lore", or a decimal index from 0 to Skills.Length−1, number or string. The case of the name is not important, trailing spaces are removed, _ is replaced with a space. The index is not the ID of the subject or the index from 1. A number string always means an index.
- ExecuteClientApiCompatibility selects the command branch. Text reads the skill selector, Arg reads the numeric numbers and modes. An unconvertible argument may fail the call with a conversion error.
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.
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.GetSkillCurrentValue("Mining");
UO.Print("GetSkillCurrentValue: " + Convert.ToString(result));Parameters and execution flow:
- In the example, selector and, when recording, mode are explicitly specified. The first line selects a skill by name or a characteristic by number. Print only prints the result.
var selector = "Mining";
var value = UO.GetSkillCurrentValue(selector);
UO.Print(Convert.ToString(value));Parameters and execution flow:
- The threshold 95.1 and modes 0/1/2 are given as an example. −1 is checked before changing mode. After writing, only the local copy is read; it's not waiting for the server to respond.
return RunScenario();
object? RunScenario()
{
if (Truth(UO.GetSkillLockState("Mining") >= 0))
{
var value = UO.GetSkillCurrentValue("Mining");
if (Truth(value >= 95.1))
{
UO.Print("Value >= 95.1: " + Convert.ToString(value));
}
}
return null;
}
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;Parameters and execution flow:
- All the helper code is given below Main. selector selects a skill/characteristic, mode sets the recording mode. ReadValue/ReadMode return the original number; ApplyMode checks the arguments, performs the action, and does not return a value. UO.Wait(1000) in the reading example separates two pictures.
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 before = ReadValue("Animal_Lore");
await Delay(1000);
var after = ReadValue("Animal Lore");
UO.Print(Convert.ToString(after - before));
return null;
}
dynamic ReadValue(dynamic selector)
{
return UO.GetSkillCurrentValue(selector);
}
Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
}C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
Parameters: skillName (Any)
Result: double / Decimal.
During a call:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetSkillValue:bridge.GetSkillValue(Text(0), true, false). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Text:Text(0).
Internal implementation code; this is not a standalone script.
case "getskillcurrentvalue": return new InjectionValue(bridge.GetSkillValue(Text(0), true, false));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
int UO.GetSkillLockState(object? skillName);Reads the local skill change mode.
-
skillName- Required skill: a name from the client data, such as "Mining" or "Animal Lore", or a decimal index from 0 to Skills.Length−1, number or string. The case of the name is not important, trailing spaces are removed, _ is replaced with a space. The index is not the ID of the subject or the index from 1. A number string always means an index.
int: 0 — increase, 1 — decrease, 2 — blocking. This is a mode code, not true/false. For an unknown skill or missing character, −1 is returned.
- Reading is performed via Invoke on the game thread based on the data already received; network packets are not sent. The skill is not used or trained. Two requests - two separate snapshots.
- Required skill: a name from the client data, such as "Mining" or "Animal Lore", or a decimal index from 0 to Skills.Length−1, number or string. The case of the name is not important, trailing spaces are removed, _ is replaced with a space. The index is not the ID of the subject or the index from 1. A number string always means an index.
- ExecuteClientApiCompatibility selects the command branch. Text reads the skill selector, Arg reads the numeric numbers and modes. An unconvertible argument may fail the call with a conversion error.
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.
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.GetSkillLockState("Mining");
UO.Print("GetSkillLockState: " + Convert.ToString(result));Parameters and execution flow:
- In the example, selector and, when recording, mode are explicitly specified. The first line selects a skill by name or a characteristic by number. Print only prints the result.
var selector = "Mining";
var mode = UO.GetSkillLockState(selector);
UO.Print(Convert.ToString(mode));Parameters and execution flow:
- The threshold 95.1 and modes 0/1/2 are given as an example. −1 is checked before changing mode. After writing, only the local copy is read; it's not waiting for the server to respond.
return RunScenario();
object? RunScenario()
{
var mode = UO.GetSkillLockState("Mining");
if (Truth(mode == 2))
{
UO.Print("Locked");
}
else
{
if (Truth(mode == -1))
{
UO.Print("Unknown selector");
}
else
{
UO.Print("Mode: " + Convert.ToString(mode));
}
}
return null;
}
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;Parameters and execution flow:
- All the helper code is given below Main. selector selects a skill/characteristic, mode sets the recording mode. ReadValue/ReadMode return the original number; ApplyMode checks the arguments, performs the action, and does not return a value. UO.Wait(1000) in the reading example separates two pictures.
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 before = ReadMode("Mining");
await Delay(1000);
var after = ReadMode("Mining");
UO.Print(Convert.ToString(before) + " -> " + Convert.ToString(after));
return null;
}
dynamic ReadMode(dynamic selector)
{
return UO.GetSkillLockState(selector);
}
Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
}C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
Parameters: skillName (Any)
Result: int / Integer.
During a call:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetSkillLockState:bridge.GetSkillLockState(Text(0)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Text:Text(0).
Internal implementation code; this is not a standalone script.
case "getskilllockstate": return new InjectionValue(bridge.GetSkillLockState(Text(0)));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
double UO.GetSkillValue(object? skillName);Reads the base value of the skill without modifiers.
-
skillName- Required skill: a name from the client data, such as "Mining" or "Animal Lore", or a decimal index from 0 to Skills.Length−1, number or string. The case of the name is not important, trailing spaces are removed, _ is replaced with a space. The index is not the ID of the subject or the index from 1. A number string always means an index.
double (Double) - skill points in increments of 0,1, for example 95,1, not 951. The BaseFixed field is divided by 10 directly into the Double. 0 means zero skill or no character/skill. The result is not bool. Legacy SkillVal/BaseVal have a different scale - do not mix these families.
- Reading is performed via Invoke on the game thread based on the data already received; network packets are not sent. The skill is not used or trained. Two requests - two separate snapshots.
- Required skill: a name from the client data, such as "Mining" or "Animal Lore", or a decimal index from 0 to Skills.Length−1, number or string. The case of the name is not important, trailing spaces are removed, _ is replaced with a space. The index is not the ID of the subject or the index from 1. A number string always means an index.
- ExecuteClientApiCompatibility selects the command branch. Text reads the skill selector, Arg reads the numeric numbers and modes. An unconvertible argument may fail the call with a conversion error.
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.
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.GetSkillValue("Mining");
UO.Print("GetSkillValue: " + Convert.ToString(result));Parameters and execution flow:
- In the example, selector and, when recording, mode are explicitly specified. The first line selects a skill by name or a characteristic by number. Print only prints the result.
var selector = "Mining";
var value = UO.GetSkillValue(selector);
UO.Print(Convert.ToString(value));Parameters and execution flow:
- The threshold 95.1 and modes 0/1/2 are given as an example. −1 is checked before changing mode. After writing, only the local copy is read; it's not waiting for the server to respond.
return RunScenario();
object? RunScenario()
{
if (Truth(UO.GetSkillLockState("Mining") >= 0))
{
var value = UO.GetSkillValue("Mining");
if (Truth(value >= 95.1))
{
UO.Print("Value >= 95.1: " + Convert.ToString(value));
}
}
return null;
}
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;Parameters and execution flow:
- All the helper code is given below Main. selector selects a skill/characteristic, mode sets the recording mode. ReadValue/ReadMode return the original number; ApplyMode checks the arguments, performs the action, and does not return a value. UO.Wait(1000) in the reading example separates two pictures.
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 before = ReadValue("Animal_Lore");
await Delay(1000);
var after = ReadValue("Animal Lore");
UO.Print(Convert.ToString(after - before));
return null;
}
dynamic ReadValue(dynamic selector)
{
return UO.GetSkillValue(selector);
}
Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
}C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
Parameters: skillName (Any)
Result: double / Decimal.
During a call:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetSkillValue:bridge.GetSkillValue(Text(0), false, false). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Text:Text(0).
Internal implementation code; this is not a standalone script.
case "getskillvalue": return new InjectionValue(bridge.GetSkillValue(Text(0), false, false));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
void UO.SetSkillLockState(object? skillName, object? skillState);Requests a change to skill mode.
-
skillName- Required skill: a name from the client data, such as "Mining" or "Animal Lore", or a decimal index from 0 to Skills.Length−1, number or string. The case of the name is not important, trailing spaces are removed, _ is replaced with a space. The index is not the ID of the subject or the index from 1. A number string always means an index. -
skillState— Mandatory mode: 0 — increase, 1 — decrease, 2 — blocking. These are three codes, not bool; true/false do not replace the names of all modes.
void - no return value. The result cannot be used as success/error or compared to true. The subsequent reading shows the local model, not the server's confirmation.
- A valid request sends one packet through GameActions and immediately changes local mode. The server can apply its own restrictions; Increases in skill or stats are not guaranteed. Unknown skill, invalid index/mode and missing character are ignored without a package.
- Required skill: a name from the client data, such as "Mining" or "Animal Lore", or a decimal index from 0 to Skills.Length−1, number or string. The case of the name is not important, trailing spaces are removed, _ is replaced with a space. The index is not the ID of the subject or the index from 1. A number string always means an index.
- ExecuteClientApiCompatibility selects the command branch. Text reads the skill selector, Arg reads the numeric numbers and modes. An unconvertible argument may fail the call with a conversion error.
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.
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.SetSkillLockState");
UO.SetSkillLockState("Mining", 2);Parameters and execution flow:
- In the example, selector and, when recording, mode are explicitly specified. The first line selects a skill by name or a characteristic by number. Print only prints the result.
var selector = "Mining";
var mode = 2;
UO.SetSkillLockState(selector, mode);
UO.Print(Convert.ToString(UO.GetSkillLockState(selector)));Parameters and execution flow:
- The threshold 95.1 and modes 0/1/2 are given as an example. −1 is checked before changing mode. After writing, only the local copy is read; it's not waiting for the server to respond.
return RunScenario();
object? RunScenario()
{
var selector = "Mining";
var before = UO.GetSkillLockState(selector);
if (Truth(before >= 0) && Truth(before <= 2))
{
UO.SetSkillLockState(selector, 0);
UO.Print(Convert.ToString(UO.GetSkillLockState(selector)));
}
return null;
}
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;Parameters and execution flow:
- All the helper code is given below Main. selector selects a skill/characteristic, mode sets the recording mode. ReadValue/ReadMode return the original number; ApplyMode checks the arguments, performs the action, and does not return a value. UO.Wait(1000) in the reading example separates two pictures.
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()
{
ApplyMode("Mining", 2);
return null;
}
void ApplyMode(dynamic selector, dynamic mode)
{
if (Truth(mode < 0) || Truth(mode > 2))
{
return;
}
if (Truth(UO.GetSkillLockState(selector) < 0))
{
return;
}
UO.SetSkillLockState(selector, mode);
}
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
Parameters: skillName (Any), skillState (Any)
Result: void / Unit.
During a call:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.SetSkillLockState:bridge.SetSkillLockState(Text(0), Arg(1)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Text:Text(0). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(1).
Internal implementation code; this is not a standalone script.
case "setskilllockstate":
case "skilllockstate": bridge.SetSkillLockState(Text(0), Arg(1)); return InjectionValue.Unit;Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
void UO.SkillLockState(object? skillName, object? skillState);Requests a change to skill mode.
-
skillName- Required skill: a name from the client data, such as "Mining" or "Animal Lore", or a decimal index from 0 to Skills.Length−1, number or string. The case of the name is not important, trailing spaces are removed, _ is replaced with a space. The index is not the ID of the subject or the index from 1. A number string always means an index. -
skillState— Mandatory mode: 0 — increase, 1 — decrease, 2 — blocking. These are three codes, not bool; true/false do not replace the names of all modes.
void - no return value. The result cannot be used as success/error or compared to true. The subsequent reading shows the local model, not the server's confirmation.
- A valid request sends one packet through GameActions and immediately changes local mode. The server can apply its own restrictions; Increases in skill or stats are not guaranteed. Unknown skill, invalid index/mode and missing character are ignored without a package.
- Required skill: a name from the client data, such as "Mining" or "Animal Lore", or a decimal index from 0 to Skills.Length−1, number or string. The case of the name is not important, trailing spaces are removed, _ is replaced with a space. The index is not the ID of the subject or the index from 1. A number string always means an index.
- ExecuteClientApiCompatibility selects the command branch. Text reads the skill selector, Arg reads the numeric numbers and modes. An unconvertible argument may fail the call with a conversion error.
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.
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.SkillLockState");
UO.SkillLockState("Mining", 2);Parameters and execution flow:
- In the example, selector and, when recording, mode are explicitly specified. The first line selects a skill by name or a characteristic by number. Print only prints the result.
var selector = "Mining";
var mode = 2;
UO.SkillLockState(selector, mode);
UO.Print(Convert.ToString(UO.GetSkillLockState(selector)));Parameters and execution flow:
- The threshold 95.1 and modes 0/1/2 are given as an example. −1 is checked before changing mode. After writing, only the local copy is read; it's not waiting for the server to respond.
return RunScenario();
object? RunScenario()
{
var selector = "Mining";
var before = UO.GetSkillLockState(selector);
if (Truth(before >= 0) && Truth(before <= 2))
{
UO.SkillLockState(selector, 0);
UO.Print(Convert.ToString(UO.GetSkillLockState(selector)));
}
return null;
}
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;Parameters and execution flow:
- All the helper code is given below Main. selector selects a skill/characteristic, mode sets the recording mode. ReadValue/ReadMode return the original number; ApplyMode checks the arguments, performs the action, and does not return a value. UO.Wait(1000) in the reading example separates two pictures.
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()
{
ApplyMode("Mining", 2);
return null;
}
void ApplyMode(dynamic selector, dynamic mode)
{
if (Truth(mode < 0) || Truth(mode > 2))
{
return;
}
if (Truth(UO.GetSkillLockState(selector) < 0))
{
return;
}
UO.SkillLockState(selector, mode);
}
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
Parameters: skillName (Any), skillState (Any)
Result: void / Unit.
During a call:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.SetSkillLockState:bridge.SetSkillLockState(Text(0), Arg(1)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Text:Text(0). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(1).
Internal implementation code; this is not a standalone script.
case "setskilllockstate":
case "skilllockstate": bridge.SetSkillLockState(Text(0), Arg(1)); return InjectionValue.Unit;Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
int UO.SkillVal(object? skillName);
int UO.SkillVal(object? skill, object? variant);Reads the legacy value of a skill or its mode/growth.
-
variant- Optional int: 0 - effective value (default), 1 - base value, 2 - increase in the base value from the first reading of this skill in runtime, 3 - blocking mode. -
skillName— Name from the runtime dictionary skillNameToSkillId, for example "Mining". Case is not important, but spaces are not trimmed and _ is not replaced. The numeric text in this legacy function is not an index; unknown name displays a message and gives 0. -
skill— Name from the runtime dictionary skillNameToSkillId, for example "Mining". Case is not important, but spaces are not trimmed and _ is not replaced. The numeric text in this legacy function is not an index; unknown name displays a message and gives 0.
int: options 0/1/2 - tenths of skill points (951 = 95.1); option 3 - mode 0/1/2 or -1 if there is no Player/skill. Unknown name/variant yields 0. Option 2 can be negative if base is lower than the saved baseline runtime, including in the absence of Player and base=0. This is not bool.
- Before choosing variant, SkillBaseVal is taken and, if the skill is being read for the first time, baseline is saved. Therefore, even reading variant=0/1/3 sets the starting point for future growth variant=2.
- An incorrect variant displays a message and gives 0, but the baseline may have already been created. The GetSkillValue/GetSkillCurrentValue values are measured with double glasses and have a different scale.
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.
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.SkillVal("Mining");
UO.Print("SkillVal: " + Convert.ToString(result));Parameters and execution flow:
- Reads the legacy value of a skill or its mode/growth.
UO.Print(UO.SkillVal("Mining"));
UO.Print(UO.SkillVal("Mining", 1));Parameters and execution flow:
- Before choosing variant, SkillBaseVal is taken and, if the skill is being read for the first time, baseline is saved. Therefore, even reading variant=0/1/3 sets the starting point for future growth variant=2.
return RunScenario();
object? RunScenario()
{
var baseline = UO.SkillVal("Mining", 2);
UO.Wait(1000);
UO.Print(UO.SkillVal("Mining", 2) - baseline);
return null;
}Parameters and execution flow:
- An incorrect variant displays a message and gives 0, but the baseline may have already been created. The GetSkillValue/GetSkillCurrentValue values are measured with double glasses and have a different scale.
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 lockMode = UO.SkillVal("Mining", 3);
if (Truth(lockMode == 2))
{
UO.Print("Skill locked");
}
return null;
}
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
Parameters: skillName (String)
Result: int / Integer.
During a call:
-
InjectionScript.Runtime.InjectionApiUO.SkillVal. -
InjectionScript.Runtime.InjectionApiUO.SkillVal:SkillVal(skillName, 0).
Internal implementation code; this is not a standalone script.
public int SkillVal(string skillName) => SkillVal(skillName, 0);Parameters: skill (Any), variant (Any)
Result: int / Integer.
During a call:
-
InjectionScript.Runtime.InjectionApiUO.Register [SkillVal]. -
InjectionScript.Runtime.InjectionApiUO.SkillVal:SkillVal(values[0].ToString(), NumberConversions.ToInt(values[1])). -
InjectionScript.Runtime.InjectionValue.ToString:values[0].ToString(). -
InjectionScript.Runtime.NumberConversions.ToInt:NumberConversions.ToInt(values[1]).
The call executes the stored handler delegate. The registration method creates this delegate while building the API.
Internal implementation code; this is not a standalone script.
values => new InjectionValue(SkillVal(values[0].ToString(), NumberConversions.ToInt(values[1])))Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
void UO.Snoop();
void UO.Snoop(object? container);Uses a container/object, typically requesting that it be opened.
-
container— Optional serial/alias. Default is bridge.LastTarget. The command does not check IsContainer or affiliation.
void - no value. Call on a separate line; completion does not confirm the server's action.
- ExecuteLegacyManualAlias calls bridge.UseObject(Arg(0,bridge.LastTarget)). This is a regular double-click request, and not a separate client algorithm for the Snooping skill.
- Bridge sends the request on the game thread. Server rules apply; There is no built-in waiting for confirmation.
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.
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.Snoop");
UO.Snoop();Parameters and execution flow:
- Uses a container/object, typically requesting that it be opened.
UO.Snoop();Parameters and execution flow:
- ExecuteLegacyManualAlias calls bridge.UseObject(Arg(0,bridge.LastTarget)). This is a regular double-click request, and not a separate client algorithm for the Snooping skill.
return RunScenario();
object? RunScenario()
{
if (Truth(UO.IsContainer("lasttarget")))
{
UO.Snoop("lasttarget");
}
return null;
}
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;Parameters and execution flow:
- Bridge sends the request on the game thread. Server rules apply; There is no built-in waiting for confirmation.
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 id = UO.GetSerial("lasttarget");
if (Truth(UO.Exists(id)))
{
UO.Snoop(id);
UO.Wait(500);
UO.Print(UO.GetContent(id));
}
return null;
}
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
Parameters: No parameters.
Result: void / Unit.
During a call:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteLegacyManualAlias. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.UseObject:bridge.UseObject(Arg(0, bridge.LastTarget)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteLegacyManualAlias::Arg:Arg(0, bridge.LastTarget). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.LastTarget:bridge.LastTarget.
Internal implementation code; this is not a standalone script.
case "snoop": bridge.UseObject(Arg(0, bridge.LastTarget)); break;Parameters: container (Any)
Result: void / Unit.
During a call:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteLegacyManualAlias. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.UseObject:bridge.UseObject(Arg(0, bridge.LastTarget)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteLegacyManualAlias::Arg:Arg(0, bridge.LastTarget). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.LastTarget:bridge.LastTarget.
Internal implementation code; this is not a standalone script.
case "snoop": bridge.UseObject(Arg(0, bridge.LastTarget)); break;Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
int UO.StealthCnt();Reads the character's local stealth offset counter.
There are no parameters.
int is the accumulated sum max(abs(deltaX),abs(deltaY)) between calls at IsHidden. This is not a guaranteed number of server stealth steps or the remaining limit.
- Without Player or when Player is not hidden, resets count=0 and saves current X/Y (or -1). When stealth, compares with previous saved X/Y, adds offset and updates coordinates.
- The counter changes as it is read. Moving back and forth between calls can be skipped; changing Z without X/Y does not increase the counter.
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.
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.StealthCnt();
UO.Print("StealthCnt: " + Convert.ToString(result));Parameters and execution flow:
- Reads the character's local stealth offset counter.
UO.Print(UO.StealthCnt());Parameters and execution flow:
- Without Player or when Player is not hidden, resets count=0 and saves current X/Y (or -1). When stealth, compares with previous saved X/Y, adds offset and updates coordinates.
return RunScenario();
object? RunScenario()
{
var before = UO.StealthCnt();
UO.Wait(500);
UO.Print(UO.StealthCnt() - before);
return null;
}Parameters and execution flow:
- The counter changes as it is read. Moving back and forth between calls can be skipped; changing Z without X/Y does not increase the counter.
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(UO.Hidden()))
{
UO.Print(UO.StealthCnt());
}
else
{
UO.Print(UO.StealthCnt());
}
return null;
}
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
Parameters: No parameters.
Result: int / Integer.
During a call:
-
InjectionScript.Runtime.InjectionApiUO.StealthCnt. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.StealthCnt:bridge.StealthCnt().
Internal implementation code; this is not a standalone script.
public int StealthCnt() => bridge.StealthCnt();Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
int UO.TicksSkill();Reads the saved mark TicksSkill.
There are no parameters.
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.
- Returns the field ticksSkill. It is updated by the successfully accepted UseSkill/UseSkillAtTarget; 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.
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.
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.TicksSkill();
UO.Print("TicksSkill: " + Convert.ToString(result));Parameters and execution flow:
- Reads the saved mark TicksSkill.
var stamp = UO.TicksSkill();
UO.Print(stamp);Parameters and execution flow:
- Returns the field ticksSkill. It is updated by the successfully accepted UseSkill/UseSkillAtTarget; 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.TicksSkill();
var ageTenths = UO.Timer() - stamp;
UO.Print(ageTenths);
return null;
}Parameters and execution flow:
- UO.Timer() - the mark calculates the age in tenths of a second. Marks are not compared between different runtimes.
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.TicksSkill();
UO.Wait(250);
var after = UO.TicksSkill();
UO.Print(before = after);
return null;
}
}C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
Parameters: No parameters.
Result: int / Integer.
During a call:
Internal implementation code; this is not a standalone script.
public int TicksSkill() => ticksSkill;Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
void UO.Track();
void UO.Track(object? flag);
void UO.Track(object? flagRaw, object? x, object? y);Creates or removes a local arrow to coordinates. Helps mark the place of return. Does not trigger the Tracking skill, does not search for creatures, and does not move the character.
-
flag— 0 — remove the local arrow; any other whole - show. UO.Track() and UO.Track(1) place it in the character's current X/Y. UO.Track(1, x, y) places it at the indicated point; UO.Track(0, x, y) ignores coordinates. The two-parameter form is not included in the registered API. -
flagRaw— 0 — remove the local arrow; any other whole - show. UO.Track() and UO.Track(1) place it in the character's current X/Y. UO.Track(1, x, y) places it at the indicated point; UO.Track(0, x, y) ignores coordinates. The two-parameter form is not included in the registered API. -
x— Cell coordinates on the current map, not window pixels. Z and map number are not accepted. Select an existing point on your map; the team does not check terrain, plot a route, or follow a moving target. -
y— Cell coordinates on the current map, not window pixels. Z and map number are not accepted. Select an existing point on your map; the team does not check terrain, plot a route, or follow a moving target.
void - no value; the command does not return move success or bool. Only the local token is changed.
- Server and local arrows are stored separately. Track(0) does not remove the server arrow. Without graphics, the marker is saved and appears when the window is opened. Closing the game window does not remove markers; breaking the connection clears them. The server can move or remove its arrow. Coordinates do not prove that the goal is achievable.
- Cell coordinates on the current map, not window pixels. Z and map number are not accepted. Select an existing point on your map; the team does not check terrain, plot a route, or follow a moving target.
- 0 — remove the local arrow; any other whole - show. UO.Track() and UO.Track(1) place it in the character's current X/Y. UO.Track(1, x, y) places it at the indicated point; UO.Track(0, x, y) ignores coordinates. The two-parameter form is not included in the registered API.
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.
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.Track");
UO.Track();Parameters and execution flow:
- UO.Track() remembers the current point: after leaving, the arrow points back. The point is not updated automatically following the character.
UO.Track();Parameters and execution flow:
- Shows a local arrow to 1450,1690 on the current map. If you are already within one square, Track(0) removes it. Substitute your coordinates.
return RunScenario();
object? RunScenario()
{
var x = 1450;
var y = 1690;
UO.Track(1, x, y);
if (Truth(UO.GetDistance(x, y) <= 1))
{
UO.Track(0);
}
return null;
}
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;Parameters and execution flow:
- The MarkIfDistant function uses the same X/Y and distance: if the target is further than two cells, it puts an arrow, otherwise it removes it. The entire function is shown below; there is no movement or expectation of achievement here.
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()
{
MarkIfDistant(1450, 1690);
return null;
}
void MarkIfDistant(dynamic x, dynamic y)
{
if (Truth(UO.GetDistance(x, y) > 2))
{
UO.Track(1, x, y);
}
else
{
UO.Track(0);
}
}
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
Parameters: No parameters.
Result: void / Unit.
During a call:
-
InjectionScript.Runtime.InjectionApiUO.Track. -
InjectionScript.Runtime.InjectionApiUO.Track:Track(1, GetX(), GetY()). -
InjectionScript.Runtime.InjectionApiUO.GetX:GetX(). -
InjectionScript.Runtime.InjectionApiUO.GetY:GetY().
Internal implementation code; this is not a standalone script.
public void Track() => Track(1, GetX(), GetY());Parameters: flag (Any)
Result: void / Unit.
During a call:
-
InjectionScript.Runtime.InjectionApiUO.Track. -
InjectionScript.Runtime.InjectionApiUO.Track:Track(NumberConversions.ToInt(flag), GetX(), GetY()). -
InjectionScript.Runtime.NumberConversions.ToInt:NumberConversions.ToInt(flag). -
InjectionScript.Runtime.InjectionApiUO.GetX:GetX(). -
InjectionScript.Runtime.InjectionApiUO.GetY:GetY().
Internal implementation code; this is not a standalone script.
public void Track(InjectionValue flag) => Track(NumberConversions.ToInt(flag), GetX(), GetY());Parameters: flagRaw (Any), x (Any), y (Any)
Result: void / Unit.
During a call:
-
InjectionScript.Runtime.InjectionApiUO.Track. -
InjectionScript.Runtime.InjectionApiUO.Track:Track(NumberConversions.ToInt(flagRaw), NumberConversions.ToInt(x), NumberConversions.ToInt(y)). -
InjectionScript.Runtime.NumberConversions.ToInt:NumberConversions.ToInt(flagRaw).
Internal implementation code; this is not a standalone script.
public void Track(InjectionValue flagRaw, InjectionValue x, InjectionValue y)
=> Track(NumberConversions.ToInt(flagRaw), NumberConversions.ToInt(x), NumberConversions.ToInt(y));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
int UO.UseSkill(object? skillName);Asks the server to use the skill by name. Exactly one parameter: skillName. UO.UseSkill("Hiding") tries to hide his own character. If the skill needs a target, select it with the game sight or in advance with a separate command WaitTargetObject.
-
skillName- Required string - the exact English name of the skill, such as "Hiding", "Anatomy" or "Meditation". Case is not important; spaces and underscores are not automatically corrected. Skill number, serial, self, distance, notoriety, maxZ and wait are not transferred here. All names.
int: 1/true—the client accepted the request; 0/false - unknown name or local failure. This is not a skill success, skill growth, or a sign of stealth. For stealth read Hidden(). You can write if UO.UseSkill("Hiding") { ... } or compare with 1/true. A missing or extra argument is a call error.
- Single form: UO.UseSkill(skillName). There are no second or subsequent parameters. Search, target and wait are performed by other commands.
- Hiding and Meditation do not require another object to be selected. Don't prepare WaitTargetObject for them: the remaining burst may respond to the next outsider's sight.
- Anatomy uses a target cursor. Call UseSkill("Anatomy") and select the character with the mouse. To automatically respond, first execute WaitTargetObject, then UseSkill: this way you won’t miss the server’s quick response.
- UseSkill does not create or clear the target queue. If you have prepared a response, clear it CancelWaitTarget on failure/timeout. Do not run other sighting scenarios at the same time.
- Poisoning, Provocation and other multi-step skills require separate processing of additional targets/tools. One pre-selected object does not complete any skill.
- The name in the dictionary does not guarantee use without a tool. Mining requires a tool; spells are cast by Cast. The rules and success are determined by the server.
- An accepted request updates TicksSkill. The team does not expect stealth, effect, skill increase or queue consumption.
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.
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.UseSkill("Hiding");
UO.Print("UseSkill: " + Convert.ToString(result));Parameters and execution flow:
- Hiding is the only argument. UO.Wait(1000) gives time to respond; Hidden reads the received flag. Returning 1 from UseSkill does not mean that you have escaped.
if (!(Truth(UO.Connected())) || Truth(UO.Dead()) || Truth(UO.Hidden()))
{
return null;
}
if (!(Truth(UO.UseSkill("Hiding"))))
{
UO.Print("Hiding request rejected");
return null;
}
await Delay(1000);
if (Truth(UO.Hidden()))
{
UO.Print("Character is hidden");
}
else
{
UO.Print("Not hidden yet; check the game journal");
}
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;Parameters and execution flow:
- Anatomy is the only parameter UseSkill; mobile refers to WaitTargetObject. ASC converts the hex string GetSerial into a number for range checking. 1500 — milliseconds to wait in the example. Finally clears the remaining queue; see the Anatomy result in the game.
return await RunScenarioAsync();
async Task<object?> RunScenarioAsync()
{
var mobile = Asc(UO.GetSerial("lasttarget"), 0);
if (Truth(mobile <= 0) || Truth(mobile >= 0x40000000) || !(Truth(UO.Exists(mobile))))
{
return null;
}
UO.CancelWaitTarget();
try
{
UO.WaitTargetObject(mobile);
if (Truth(UO.UseSkill("Anatomy")))
{
await Delay(1500);
}
}
finally
{
UO.CancelWaitTarget();
}
return null;
}
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;Parameters and execution flow:
- Meditation is invoked without a purpose. before stores the previous mana, 2000 is the observation period. Mana growth may have other reasons; This is not proof of meditation or a promise of a fixed rate of recovery.
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()
{
if (!(Truth(UO.Connected())) || Truth(UO.Dead()))
{
return null;
}
var before = UO.Mana();
if (!(Truth(UO.UseSkill("Meditation"))))
{
UO.Print("Meditation request rejected");
return null;
}
await Delay(2000);
if (Truth(UO.Mana() > before))
{
UO.Print("Mana increased");
}
else
{
UO.Print("No mana increase observed yet");
}
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;
}C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
Parameters: skillName (String)
Result: int / Integer.
During a call:
-
InjectionScript.Runtime.InjectionApiUO.UseSkill. -
InjectionScript.Runtime.InjectionApiUO.UseSkillCore:UseSkillCore(skillName).
Internal implementation code; this is not a standalone script.
public int UseSkill(string skillName)
{
return UseSkillCore(skillName) ? 1 : 0;
}