This document describes the custom AngelScript API for Master Sword Rebirth.
- Server: Available only in server-side scripts
- Client: Available only in client-side scripts
- Shared: Available in both server and client scripts
Scope: Shared
// Constructors
Vector3()
Vector3(float x, float y, float z)
// Properties
float x
float y
float z
// Methods
float Length() const
float Length2D() const
Vector3 Normalize() const
float DotProduct(const Vector3 &in) const
Vector3 CrossProduct(const Vector3 &in) const
float Distance(const Vector3 &in) const
// Operators
Vector3 opAdd(const Vector3 &in) const
Vector3 opSub(const Vector3 &in) const
Vector3 opMul(float) const
Vector3 opDiv(float) const
bool opEquals(const Vector3 &in) constScope: Shared
// Constructor
Color(int r, int g, int b, int a = 255)
// Properties
int r
int g
int b
int aScope: Shared
const int kRenderNormal = 0 // Normal rendering
const int kRenderTransColor = 1 // Transparent color
const int kRenderTransTexture = 2 // Transparent texture
const int kRenderGlow = 3 // Glow effect
const int kRenderTransAlpha = 4 // Transparent alpha
const int kRenderTransAdd = 5 // Additive transparencyconst int DAMAGE_NO = 0 // Entity takes no damage
const int DAMAGE_YES = 1 // Entity takes normal damage
const int DAMAGE_AIM = 2 // Entity takes aim-based damageScope: Server
// Methods
Vector3 GetOrigin()
string GetClassName()
void SetOrigin(const Vector3 &in)
float GetHealth()
void SetHealth(float)
bool IsAlive()
string DisplayName()
Vector3 Center()
float Volume()
float Weight()
bool IsPlayer()
// Entity configuration methods
void SetNetName(const string &in)
string GetNetName()
void SetRenderMode(int)
void SetRenderAmount(int)
void SetTakeDamage(int)
void SetGodMode(bool)Scope: Server Inherits from CBaseEntity
// Methods
string DisplayName() const
string GetName() const // Alias for DisplayName
string GetSteamID() const // Returns Steam ID
int GetEntIndex() const // Entity index
bool IsConnected() const
bool IsAlive() const
bool IsAdmin() const
Vector3 GetOrigin() const
float GetHealth() const
string GetTitle() const // Player's in-game title
float MaxHP() const
float MaxMP() const
bool IsElite() const
string GetPartyName() const
bool IsLocalHost() const
string GetClassName() const
void SetOrigin(const Vector3 &in)
void SetHealth(float)
Vector3 Center() const
float Volume() const
float Weight() const
bool IsPlayer() const
void PlaySound(const string &in)
void SendInfoMsg(const string &in)
void SendEventMsg(const string &in)
// Enhanced messaging methods with color support
void SendColoredMessage(MessageColor color, const string &in message)
void SendHUDInfoMessage(const string &in title, const string &in message)
// Map transition methods
void SetTransitionFields(const string &in localSpawn, const string &in destMap, const string &in destSpawn)
string GetOldTransition() const
string GetNextMap() const
string GetNextTransition() const
int GetJoinType() const
void SetJoinType(int joinType)
// Spawn management methods
bool MoveToSpawnSpot()
void SetSpawnTransition(const string &in transName)
string GetSpawnTransition() const
// Inventory/Item management methods
CBasePlayerItem@ GetItemBySlot(int slot) const
CBasePlayerWeapon@ GetActiveWeapon() const
array<CBasePlayerItem@>@ GetInventory()
bool HasItem(const string &in itemName) const
// Comparison
bool opEquals(const CBasePlayer@+ other) constSetTransitionFields sets the player's C++ transition fields which control where they spawn after map changes:
localSpawn: Current spawn point name on the current map (setsm_OldTransitionandm_SpawnTransition)destMap: Destination map name (setsm_NextMap)destSpawn: Spawn point name on the destination map (setsm_NextTransition)- Automatically calls
SaveChar()to persist the changes
GetOldTransition, GetNextMap, GetNextTransition: Retrieve the current transition state
GetJoinType / SetJoinType: Get or set how the player joined the server
- JoinType constants:
JN_NOTALLOWED(0),JN_TRAVEL(1),JN_STARTMAP(2),JN_VISITED(3),JN_ELITE(4) - Changing JoinType affects spawn point selection logic
- Useful for ensuring transitions take priority over start map status
MoveToSpawnSpot moves the player to their designated spawn point:
- Returns
trueif successful,falseotherwise - Uses the player's current spawn transition to find the appropriate spawn point
- Automatically sets player position and angles to match the spawn point
SetSpawnTransition / GetSpawnTransition: Set or retrieve the player's current spawn transition name:
- The spawn transition determines which
ms_player_spawnentity the player will spawn at - Maximum length: 32 characters
- Used by map transition system and respawn logic
GetItemBySlot / GetActiveWeapon / GetInventory / HasItem: Inventory management methods:
- See the "Item/Weapon Management Methods" section below for detailed documentation
- These methods provide access to player's items, weapons, and inventory state
Example:
CBasePlayer@ player = PlayerBySteamID("STEAM_0:1:12345");
if (player !is null) {
player.SetTransitionFields("start", "thornlands", "entrance");
// Adjust JoinType to ensure transition spawn is used
if (player.GetJoinType() == 2) { // JN_STARTMAP
player.SetJoinType(1); // JN_TRAVEL
}
}SendColoredMessage sends a colored text message to the player's HUD event console:
color: MessageColor enum value determining the message colormessage: Message text to display (max 140 characters, auto-truncated with*suffix)- Automatically adds newline if not present
- Replaces legacy script commands:
playermessage,rplayermessage,gplayermessage,bplayermessage,yplayermessage,dplayermessage
SendHUDInfoMessage sends an info box message to the player's top-left HUD:
title: Title text for the info box (max 120 characters, auto-truncated with*\nsuffix)message: Body text for the info box (max 120 characters, auto-truncated with*\nsuffix)- Replaces legacy script command:
infomsg <player> <title> <message>
Example - Messaging:
CBasePlayer@ player = PlayerByIndex(1);
if (player !is null) {
// Send colored messages
player.SendColoredMessage(MessageColor::Green, "You found a rare item!");
player.SendColoredMessage(MessageColor::Red, "You took damage!");
player.SendColoredMessage(MessageColor::Yellow, "Attack dealt 50 damage");
player.SendColoredMessage(MessageColor::Blue, "Mana restored");
player.SendColoredMessage(MessageColor::Gray, "Cannot equip this item");
player.SendColoredMessage(MessageColor::White, "Normal information message");
// Send HUD info box
player.SendHUDInfoMessage("Quest Complete", "You completed the tutorial quest!");
}Scope: Server
enum MessageColor {
White = 0, // Normal color (off-white) - HUDEVENT_NORMAL
Gray = 1, // Dark gray - unable/disabled actions - HUDEVENT_UNABLE
Yellow = 2, // Yellowish - attack results - HUDEVENT_ATTACK
Red = 3, // Red - damage received - HUDEVENT_ATTACKED
Green = 4, // Green - positive events - HUDEVENT_GREEN
Blue = 5 // Blue - info/mana events - HUDEVENT_BLUE
}The MessageColor enum is used with SendColoredMessage() to specify HUD message colors:
- White: Standard informational messages, general notifications
- Gray: Disabled actions (can't pickup, can't equip, etc.)
- Yellow: Combat feedback (your attack damage)
- Red: Taking damage, negative combat events
- Green: Positive events (item pickup, quest complete, healing)
- Blue: Special information, mana-related events
Scope: Server Base class for animated entities
// Animation methods
int LookupSequence(const string &in label)
void ResetSequenceInfo()
void SetBodygroup(int group, int value)
int GetBodygroup(int group)
// Properties (read-only from script)
float GetFrameRate() const
bool IsSequenceFinished() const
bool IsSequenceLooping() constLookupSequence finds a sequence by name:
- Returns sequence index or -1 if not found
- Used for setting specific animations on models
ResetSequenceInfo resets the current sequence information:
- Call when switching sequences or models
- Resets timing and frame information
SetBodygroup / GetBodygroup manage model body groups:
- Body groups allow switching between model variations
- Common for armor, weapons, or character customization
Scope: Server Base class for inventory items
// Properties
string GetItemName() const
string GetWorldModel() const
string GetHandSpriteName() const
string GetTradeSpriteName() const
CBasePlayer@ GetOwnerPlayer() const
int GetItemID() const
uint GetValue() const
bool IsWielded() const
bool IsUseable() const
// Methods
bool IsMSItem() const
bool CanDrop() const
bool Deploy()
void Holster()
void Materialize()GetItemName returns the internal item name (e.g., "dagger", "broadsword"):
- This is the script name used to identify the item type
GetWorldModel returns the world model path:
- Used when the item is dropped or placed in the world
GetOwnerPlayer returns the player who owns this item:
- Returns
nullif not owned by a player - Use to check item ownership
GetValue returns the item's gold value:
- Used for trading, selling, and economy systems
IsWielded checks if the item is currently being held/used:
- Returns
trueif the item is actively equipped
Deploy / Holster control item equipping:
Deploy()equips the item (makes it active)Holster()puts the item away
Example:
CBasePlayer@ pPlayer = PlayerByIndex(1);
if (pPlayer !is null) {
CBasePlayerItem@ pItem = pPlayer.GetItemBySlot(0);
if (pItem !is null) {
MS_ANGEL_INFO("Item: " + pItem.GetItemName());
MS_ANGEL_INFO("Value: " + pItem.GetValue() + " gold");
MS_ANGEL_INFO("Wielded: " + (pItem.IsWielded() ? "Yes" : "No"));
}
}Scope: Server Weapons (extends CBasePlayerItem)
// Ammo properties
int GetClip() const
void SetClip(int amount)
int GetPrimaryAmmoType() const
int GetSecondaryAmmoType() const
// Attack timing
float GetNextPrimaryAttack() const
void SetNextPrimaryAttack(float time)
float GetNextSecondaryAttack() const
void SetNextSecondaryAttack(float time)
float GetTimeWeaponIdle() const
// State properties
bool IsInReload() const
// Methods
bool CanDeploy()
bool IsUseable()
void SendWeaponAnim(int anim, int skiplocal)
int PrimaryAmmoIndex()
int SecondaryAmmoIndex()
string pszAmmo1()
string pszAmmo2()GetClip / SetClip manage weapon ammunition:
GetClip()returns current ammunition in the weapon's clipSetClip(amount)sets the clip ammunition count- Use for reloading or ammo manipulation
GetNextPrimaryAttack / SetNextPrimaryAttack control attack timing:
- Time value when the weapon can fire again
- Based on
gpGlobals->timefor server timing
IsInReload checks if the weapon is currently reloading:
- Returns
trueduring reload animation - Use to prevent actions during reload
SendWeaponAnim plays a weapon animation:
animis the animation sequence indexskiplocalskips animation for local player (client prediction)
Example:
CBasePlayer@ pPlayer = PlayerByIndex(1);
if (pPlayer !is null) {
CBasePlayerWeapon@ pWeapon = pPlayer.GetActiveWeapon();
if (pWeapon !is null) {
MS_ANGEL_INFO("Clip: " + pWeapon.GetClip());
MS_ANGEL_INFO("In Reload: " + (pWeapon.IsInReload() ? "Yes" : "No"));
// Refill clip
pWeapon.SetClip(30);
}
}Scope: Server
The following inventory management methods are available on CBasePlayer:
// Get item from specific inventory slot
CBasePlayerItem@ GetItemBySlot(int slot) const
// Get player's currently active weapon
CBasePlayerWeapon@ GetActiveWeapon() const
// Get all items in player's inventory
array<CBasePlayerItem@>@ GetInventory()
// Check if player has specific item by name
bool HasItem(const string &in itemName) constGetItemBySlot retrieves an item from a specific inventory slot:
slot: Inventory slot index (0 to MAX_ITEM_TYPES-1)- Returns
nullif slot is empty - Use to access specific inventory positions
GetActiveWeapon gets the player's currently equipped weapon:
- Returns
nullif no weapon is active or item is not a weapon - Casts to CBasePlayerWeapon for weapon-specific access
GetInventory returns all items the player owns:
- Returns an array of all CBasePlayerItem@ references
- Includes items from all inventory slots
- Empty slots are not included in the array
HasItem checks if player owns a specific item by name:
itemName: The item's script name (e.g., "dagger")- Returns
trueif found in any inventory slot - Case-sensitive comparison
Example:
CBasePlayer@ pPlayer = PlayerByIndex(1);
if (pPlayer !is null) {
// Check if player has a specific item
if (pPlayer.HasItem("health_potion")) {
pPlayer.SendInfoMsg("You have a health potion!");
}
// Iterate through all player items
array<CBasePlayerItem@>@ items = pPlayer.GetInventory();
for (uint i = 0; i < items.length(); i++) {
CBasePlayerItem@ pItem = items[i];
MS_ANGEL_INFO("Item " + i + ": " + pItem.GetItemName());
}
// Get active weapon and check ammo
CBasePlayerWeapon@ pWeapon = pPlayer.GetActiveWeapon();
if (pWeapon !is null && pWeapon.GetClip() < 5) {
pPlayer.SendColoredMessage(MessageColor::Red, "Low ammo!");
}
// Get item from specific slot
CBasePlayerItem@ pSlotItem = pPlayer.GetItemBySlot(0);
if (pSlotItem !is null) {
MS_ANGEL_INFO("Slot 0 item: " + pSlotItem.GetItemName());
}
}Scope: Shared
string Left(const string &in str, int count)
string Right(const string &in str, int count)
string Mid(const string &in str, int start, int count)
int Length(const string &in str)
string ToUpper(const string &in str)
string ToLower(const string &in str)
string Replace(const string &in str, const string &in find, const string &in replace)
// String utilities (requires array support)
array<string>@ split(const string &in) const // Method on string type
string join(const array<string> &in arr, const string &in delimiter)Scope: Shared
float sin(float)
float cos(float)
float sqrt(float)
float abs(float)
float min(float, float)
float max(float, float)Scope: Varies
// Time and game state
float GetGameTime() // Shared
string GetTimestamp() // Shared
string GetMapName() // Shared
string GetPlayerCurrentMap() // Shared
// Console variables
string GetCvar(const string &in) // Shared
// Random number generation
float Random(float min, float max) // Shared
// Logging
void LogMessage(const string &in) // Shared
void ChatLog(const string &in) // Server
void MS_ANGEL_INFO(const string &in) // Shared
void MS_ANGEL_DEBUG(const string &in) // Shared
void MS_ANGEL_ERROR(const string &in) // SharedScope: Server
// Player queries
array<CBasePlayer@>@ GetAllPlayers()
int GetPlayerCount()
CBasePlayer@ PlayerByIndex(int index)
CBasePlayer@ PlayerBySteamID(const string &in steamID)
int GetCurrentPlayerID()
// Player information
bool IsConnected(CBasePlayer@)
string GetDisplayName(CBasePlayer@)
string GetSteamID(CBasePlayer@)
string GetPlayerSteamID(CBasePlayer@) // Alias for GetSteamID
bool IsAdmin(CBasePlayer@)
string GetClientAddress(CBasePlayer@)
// Player communication
void SendPlayerMessage(const string &in playerName, const string &in title, const string &in message)
// Menu system
void OpenVoteMenu(CBasePlayer@ player, const string &in title, const array<string> &in options)
// Spawn management
bool MovePlayerToRandomSpawn(CBasePlayer@ player, float maxDistance)MovePlayerToRandomSpawn moves a player to a random spawn point within a specified distance:
player: The player to movemaxDistance: Maximum distance in units to search for spawn points (e.g., 256.0)- Returns
trueif a spawn point was found and the player was moved - Returns
falseif no spawn points were found within the distance - Searches for
ms_player_spawnentities near the player's current position - Useful for
/stuckcommands or respawn systems - Converted from legacy
torandomspawnscript command
Example:
// Move player to a random nearby spawn (within 256 units)
if (MovePlayerToRandomSpawn(pPlayer, 256.0f)) {
pPlayer.SendInfoMsg("Teleported to nearby spawn point");
} else {
pPlayer.SendInfoMsg("No spawn points found nearby");
}Scope: Server
// Execute server console commands
void ExecuteServerCommand(const string &in command)ExecuteServerCommand allows scripts to execute server console commands such as:
changelevel <mapname>- Change to a different mapkick #<userid>- Kick a player by user IDbanid <minutes> <steamid> kick- Ban a player by Steam IDsv_password <password>- Set server passwordms_pklevel <level>- Set PvP level (0=disabled, 1+=enabled)
Security Notes:
- Commands like
quit,exit, andrcon_passwordare blocked for security - Only use trusted input when building command strings
- This function is SERVER_ONLY and cannot be called from client scripts
Implementation Details:
- Exposed via
AS_ExecuteServerCommandinASBuiltinFunctions.cpp - Uses
SERVER_COMMAND()andSERVER_EXECUTE()internally - Security validation performed before execution
Scope: Server
// External function calls
void CallPlayerExternal(const string &in playerID, const string &in function, const array<string>@ &in args)
void CallGameMasterExternal(const string &in function, const array<string>@ &in args)
// Player messaging
void SendMessageToAllPlayers(const string &in color, const string &in message)
void SendInfoMessageToAll(const string &in title, const string &in message)
void SendPlayerMessage(const string &in playerName, const string &in title, const string &in message)
void SendConsoleMessage(const string &in playerID, const string &in message)CallPlayerExternal calls external functions on player scripts:
playerID: Player's Steam IDfunction: Name of the function to call (e.g., "ext_set_map", "ext_setspawn", "ext_changelevel_prep")args: Array of string arguments to pass to the function
CallGameMasterExternal calls external functions on GameMaster scripts:
function: Name of the GameMaster function to call (e.g., "gm_create_vote", "gm_set_global_var")args: Array of string arguments to pass to the function
SendMessageToAllPlayers sends colored chat messages to all players:
color: Color name (red, green, blue, yellow, etc.)message: Message text to display
SendInfoMessageToAll sends info box messages to all players:
title: Title text for the info boxmessage: Body text for the info box
Scope: Server
// Check if a map exists on the server
bool EngineMapExists(const string &in mapName)EngineMapExists checks if a map file exists on the server:
mapName: Map name without .bsp extension (e.g., "crossroads", "thornlands")- Returns
trueif the map file exists in the maps/ directory - Returns
falseif the map doesn't exist or the name is invalid - Uses engine file system to validate actual map file presence
- Server-only function for map transition validation
Example Usage:
if (EngineMapExists("crossroads")) {
ExecuteServerCommand("changelevel crossroads");
} else {
SendMessageToAllPlayers("red", "Map 'crossroads' not found on server");
}Scope: Server
// Entity creation and manipulation
CBaseEntity@ CreateEntity(const string &in scriptName)
void SetEntityName(CBaseEntity@, const string &in)
void SetEntityTargetName(CBaseEntity@, const string &in)
void SetEntityHealth(CBaseEntity@, float)
bool IsEntityDead(CBaseEntity@)
// Type casting
CBaseEntity@ ToEntity(CBasePlayer@)
CBasePlayer@ ToPlayer(CBaseEntity@)
// Entity string conversion
CBaseEntity@ StringToEntity(const string &in)
CBasePlayer@ StringToPlayer(const string &in)
// Entity spawning functions
CMSMonster@ SpawnNPC(const string &in scriptName, const Vector3 &in position, const array<string>@ params = null)
CBasePlayerItem@ SpawnItem(const string &in scriptName, const Vector3 &in position, const array<string>@ params = null)SpawnNPC creates an NPC entity at the specified position:
scriptName: Script name of the NPC to spawn (e.g., "game_master", "skeleton")position: 3D coordinates where the NPC should spawnparams: Optional array of additional parameters (reserved for future use)- Returns: Pointer to the spawned CMSMonster, or null if creation failed
- Server-only function
SpawnItem creates an item entity at the specified position:
scriptName: Script name of the item to spawn (e.g., "potion_health", "sword_short")position: 3D coordinates where the item should spawnparams: Optional array of additional parameters (reserved for future use)- Returns: Pointer to the spawned CBasePlayerItem, or null if creation failed
- Server-only function
Example:
// Spawn a skeleton at coordinates (100, 200, 0)
CMSMonster@ pSkeleton = SpawnNPC("skeleton", Vector3(100, 200, 0));
if (pSkeleton !is null) {
LogMessage("Skeleton spawned at index " + pSkeleton.entindex());
// Now you have direct access to CMSMonster properties
pSkeleton.m_HP = 100.0f;
pSkeleton.Title = "Elite Skeleton";
}
// Spawn a health potion (returns CBasePlayerItem)
CBasePlayerItem@ pPotion = SpawnItem("potion_health", Vector3(150, 250, 10));
if (pPotion !is null) {
LogMessage("Item spawned: " + pPotion.GetItemName());
// Access item-specific properties
uint value = pPotion.GetValue();
LogMessage("Item value: " + value + " gold");
}StringToEntity converts an entity string to a CBaseEntity pointer:
- Entity strings are in the format
"PentP(index,address)"(e.g.,"PentP(1,12345678)") - Returns
nullif the string is invalid or the entity no longer exists - Validates both the entity index and memory address for safety
- Used when C++ passes entity references as strings to scripts
StringToPlayer converts an entity string to a CBasePlayer pointer:
- Uses
StringToEntityinternally and casts to player - Returns
nullif the entity is not a valid player - Convenient for converting player entity strings from C++ events
Example:
// Event handler receiving entity string from C++
void GamePlayerPutInWorld(const string &in entityString) {
CBasePlayer@ pPlayer = StringToPlayer(entityString);
if (pPlayer !is null) {
LogMessage("Player spawned: " + pPlayer.GetName());
}
}Scope: Server
string GetPlayerQuestData(const string &in playerID, const string &in key)
void SetPlayerQuestData(const string &in playerID, const string &in key, const string &in value)Scope: Shared
Base class for script objects with variable storage system.
// Variable management methods
void SetVar(const string &in key, const string &in value)
string GetVar(const string &in key)
// Additional methods depend on implementationScope: Shared
int StartCoroutine(const string &in functionName)
void DelaySeconds(float seconds)
// Additional coroutine functions depend on implementationScope: Shared
The module system provides comprehensive module management with dependency resolution, import/export functionality, and automatic discovery.
// Core module operations
bool LoadModule(const string &in filename) // Load a module from file
bool UnloadModule(const string &in name) // Unload a module by name
bool ReloadModule(const string &in name) // Reload an existing module
bool HasModule(const string &in name) // Check if module is loaded
// Import functionality
bool ImportModule(const string &in moduleName) // Import module into current namespace
bool ImportModule(const string &in moduleName, const string &in asNamespace) // Import with namespaceModules are declared in .as files using the module keyword. The module itself becomes a class, and its constructor is automatically called upon loading:
module MyModule {
// Module properties
private int m_counter;
private string m_name;
// Constructor - automatically called when module loads
MyModule() {
m_counter = 0;
m_name = "MyModule";
// Initialization code here
}
// Module methods
void myFunction() {
// Function implementation
}
int getCounter() {
return m_counter;
}
}-
Automatic Discovery: The system can automatically discover modules in PAK files by scanning for
module ModuleName {declarations -
Dependency Management: Modules can declare dependencies that are automatically resolved during loading
-
Import/Export System: Modules can export functions and types for use by other modules
-
Module Preprocessing: The
modulekeyword is transformed toclasssyntax internally. The module becomes a class instance. -
Lifecycle Management: The system automatically generates initialization code:
ModuleName_Initialize()- Creates a global instanceg_ModuleNameand calls the module's constructorModuleName_Shutdown()- Cleans up the global instance- The module constructor is executed automatically when the module loads
When loading modules programmatically, the following options are available:
- compileOnly: Only compile without building
- allowOverwrite: Allow replacing existing modules
- resolveDependencies: Automatically load required dependencies
- validateExports: Check that declared exports exist
The module system searches for modules in configured paths, typically:
- PAK file locations
- Script directories
- Custom paths added via configuration
Scope: Shared
The engine event system allows scripts to respond to game events by implementing global functions with specific names. The C++ engine will call these functions at appropriate times.
Scope: Server
// Called when player spawns in world (after character selection)
void GamePlayerPutInWorld()
void GamePlayerPutInWorld(CBasePlayer@ pPlayer)
void GamePlayerPutInWorld(const string &in playerIdentifier)
// Called when player respawns after death
void GameRespawn(CBasePlayer@ pPlayer)
// Called when the server activates (map load complete)
void ServerActivate()ServerActivate is called after all map entities have been spawned and activated:
- Called once per map load, after entity activation completes
- Ideal for initializing game systems, spawning dynamic entities
- GameMaster scripts should implement this to spawn the game_master NPC
- Called from C++
client.cpp:ServerActivate()viaCallGlobalFunctionWithParams - Replaces the legacy C++ game_master spawning code
Example - GameMaster Implementation:
void ServerActivate() {
LogMessage("Server activated, spawning game_master...");
// Spawn game_master NPC at far coordinates (returns CMSMonster@)
CMSMonster@ pGameMaster = SpawnNPC("game_master", Vector3(20000, -10000, -20000), null, Angel);
if (pGameMaster !is null) {
// Configure game_master properties
pGameMaster.SetNetName("-game_master"); // Required for C++ lookup
pGameMaster.SetHealth(1.0f);
pGameMaster.SetRenderMode(kRenderTransTexture);
pGameMaster.SetRenderAmount(0); // Invisible
pGameMaster.SetGodMode(true);
pGameMaster.SetTakeDamage(DAMAGE_NO);
// Set MS-specific properties
pGameMaster.Title = "Game Master";
pGameMaster.m_Menu_Autoopen = false;
LogMessage("Game master spawned and configured successfully");
} else {
LogMessage("ERROR: Failed to spawn game_master");
}
}GamePlayerPutInWorld is called when a player enters the world after character selection (not during respawn):
- Called from C++
player.cpp:2730viaCallScriptEvent - The entity string version receives
"PentP(index,address)"format fromEntToString(this) - The version with
CBasePlayer@can be called directly with a player object - The version with string identifier can look up players by Steam ID or index
- Implement this function globally in your AngelScript module to handle player spawn events
- See
PlayerEvents.asfor the reference implementation
GameRespawn is called when a player respawns after death:
- Implement this function globally to handle post-death respawn logic
- Different from
GamePlayerPutInWorldwhich is for initial world entry
Reference Implementation (PlayerEvents.as):
The official implementation handles:
- Christmas Mode: Seasonal events on specific maps (edana, deralia, helena)
- Random Spawn: Moves player to random nearby spawn point for anti-stuck
- Transition Data: Restores spawn points from quest data (key: "d")
- Home Position: Saves player's home coordinates to quest data
- First Join: Initializes new players (sets
PLR_IN_WORLDquest flag) - Dark Level: Restores dark level from quest data (key: "dl")
- Meta Perks: Donator/dev halos and trollcano checks
Example:
void GamePlayerPutInWorld(const string &in entityString) {
// Convert entity string to player
CBasePlayer@ pPlayer = StringToPlayer(entityString);
if (pPlayer is null) return;
string steamID = pPlayer.GetSteamID();
// Handle player spawn logic
LogMessage("Player " + pPlayer.GetName() + " entered the world");
// Set transition data from quest data
string trans = GetPlayerQuestData(steamID, "d");
if (trans.length() > 0) {
pPlayer.SetTransitionFields(trans, GetMapName(), trans);
}
// Set home position
Vector3 pos = pPlayer.GetOrigin();
string posStr = pos.x + "," + pos.y + "," + pos.z;
SetPlayerQuestData(steamID, "MY_HOME", posStr);
}Scope: Shared
Memory optimization functions are available but typically managed automatically by the engine.
Inheritance Chain: CBaseEntity → CBaseMonster → CMSMonster → CBasePlayer
All monster classes inherit methods and properties from their parent classes. For example, CMSMonster has access to all CBaseEntity methods like SetNetName(), SetHealth(), GetClassName(), etc.
Scope: Server Base class for all monsters (inherits from CBaseEntity)
// Properties (direct member access)
float m_flFieldOfView // Monster's view cone width (dot product, e.g. 0.5)
float m_flWaitFinished // Time when current wait expires
float m_flMoveWaitFinished // Time when movement wait expires
int m_LastHitGroup // Last body region that took damage
float m_flNextAttack // Time when can attack again
int m_bloodColor // Blood particle color value
float m_flDistTooFar // Enemy too far distance threshold
float m_flDistLook // Monster sight distance (default 2048)
int m_iMaxHealth // Maximum health value
int m_afCapability // Capability flags (bits_CAP_*)
CBaseEntity@ Enemy // Current enemy entity (virtual property)
CBaseEntity@ TargetEnt // Current target entity (virtual property)
Vector3 EnemyLKP // Enemy last known position (virtual property)
// Core AI Methods
int BloodColor() // Get blood color value
void Look(int distance) // Look for targets within distance
void RunAI() // Execute AI tick
bool IsAlive() // Check if monster is alive
void MonsterThink() // AI think function
int IRelationship(CBaseEntity@ target) // Get relationship to target
void MonsterInit() // Initialize monster
void StartMonster() // Activate monster
CBaseEntity@ BestVisibleEnemy() // Find best visible enemy
bool FInViewCone(CBaseEntity@ entity) // Check if entity in view cone
bool FInViewCone(const Vector3 &in) // Check if position in view cone
void SetState(int state) // Set monster state
void ReportAIState() // Debug AI state to console
int CheckEnemy(CBaseEntity@ enemy) // Validate enemy
void PushEnemy(CBaseEntity@ enemy, const Vector3 &in lastPos) // Save enemy
bool PopEnemy() // Restore previous enemy
void ClearSchedule() // Clear current schedule
float ChangeYaw(int speed) // Rotate yaw toward target
bool FacingIdeal() // Check if facing ideal direction
Vector3 BodyTarget(const Vector3 &in) // Get aim point on body
// Condition Management
void SetConditions(int conditions) // Set condition flags
void ClearConditions(int conditions) // Clear condition flags
bool HasConditions(int conditions) // Check condition flags
bool HasAllConditions(int conditions) // Check all condition flags
// Memory Management
void Remember(int memory) // Set memory flag
void Forget(int memory) // Clear memory flag
bool HasMemory(int memory) // Check memory flag
bool HasAllMemories(int memory) // Check all memory flags
// Task Management
void TaskComplete() // Mark current task complete
void TaskFail() // Mark current task failed
void TaskBegin() // Begin current task
// Movement
bool IsMoving() // Check if monster is moving
void Stop() // Stop movementMonsterState Enum Values:
MONSTERSTATE_NONE(0) - No stateMONSTERSTATE_IDLE(1) - Idle/passiveMONSTERSTATE_COMBAT(2) - In combatMONSTERSTATE_ALERT(3) - Alert/investigatingMONSTERSTATE_HUNT(4) - Hunting enemyMONSTERSTATE_PRONE(5) - Prone/knocked downMONSTERSTATE_SCRIPT(6) - Scripted sequenceMONSTERSTATE_PLAYDEAD(7) - Playing deadMONSTERSTATE_DEAD(8) - Dead
Example - Basic Monster AI Control:
void ControlMonsterAI() {
// Get a monster entity (example assumes you have one)
CBaseEntity@ entity = /* get monster entity */;
CBaseMonster@ monster = ToMonster(entity);
if (monster !is null) {
// Configure monster AI
monster.m_flFieldOfView = 0.7f; // Narrower view cone
monster.m_flDistLook = 1024.0f; // Shorter sight range
// Set monster to combat state
monster.SetState(MONSTERSTATE_COMBAT);
// Find and engage enemy
CBaseEntity@ enemy = monster.BestVisibleEnemy();
if (enemy !is null) {
monster.Enemy = enemy;
MS_ANGEL_INFO("Monster engaged enemy");
}
// Check conditions
if (monster.HasConditions(bits_COND_SEE_ENEMY)) {
MS_ANGEL_INFO("Monster sees enemy");
}
// Remember something
monster.Remember(bits_MEMORY_PROVOKED);
}
}Scope: Server Master Sword monster class (inherits from CBaseMonster, which inherits from CBaseEntity)
Note: CMSMonster has full access to all CBaseEntity methods (e.g., SetNetName(), GetClassName(), SetHealth(), SetRenderMode()) and all CBaseMonster methods (e.g., Look(), SetState(), BestVisibleEnemy()).
// Properties (direct member access)
float m_HP // Current health points
float m_MP // Current mana points
int m_Gold // Gold amount carried
float m_StepSize // Maximum step height
float m_SpeedMultiplier // Speed modifier (1.0 = normal)
float m_TurnRate // Turn speed ratio (0.0-1.0)
float m_Width // Monster width for collision
float m_Height // Monster height for collision
uint8 m_Gender // Monster gender (Gender enum as uint8)
string Title // Display title/name (virtual property, msstring wrapper)
string ScriptName // Script file name (virtual property, msstring wrapper)
int m_Lives // Remaining lives (respawns)
float m_SkillLevel // Experience worth
bool m_Menu_Autoopen // Auto-open menu on +use
float m_HITMulti // Hit chance multiplier
float m_HPMulti // HP multiplier
float m_DMGMulti // Damage output multiplier
float m_HearingSensitivity // Sound hearing sensitivity
// Lifecycle Methods
bool IsMSMonster() // Check if this is an MSMonster
float MaxHP() // Get effective maximum HP
float MaxMP() // Get effective maximum MP
bool IsAlive() // Check if alive
// Economy Methods
int GiveGold(int amount) // Give/take gold (returns new amount)
int GiveGold(int amount, bool verbose) // With verbose messages
float GiveHP(float amount) // Give/take HP (returns new HP)
float GiveMP(float amount) // Give/take MP (returns new MP)
// Stats System
int GetNatStat(int stat) // Get natural stat value
int GetSkillStat(int stat) // Get skill stat value
int GetSkillStatCount() // Get number of skill stats
// Movement
float WalkSpeed() // Get walk speed
float RunSpeed() // Get run speed
bool IsFlying() // Check if flying/swimming
// Combat
bool IsActing() // Check if attacking/acting
bool IsShielding() // Check if blocking with shield
void CancelAttack() // Cancel current attack
// Miscellaneous
float Weight() // Get total weight (gear + items)
void SetSpeed() // Recalculate speedGender Enum Values:
GENDER_MALE(0) - MaleGENDER_FEMALE(1) - FemaleGENDER_UNKNOWN(2) - Unknown/neutral
SpeechType Enum Values:
SPEECH_GLOBAL(0) - Global chatSPEECH_LOCAL(1) - Local range (300 units)SPEECH_PARTY(2) - Party only
Example - Monster Management:
void ManageMSMonster() {
// Get an MS monster entity
CBaseEntity@ entity = /* get monster entity */;
CMSMonster@ monster = ToMSMonster(entity);
if (monster !is null) {
// Set properties
monster.Title = "Elite Guardian";
monster.m_SpeedMultiplier = 1.5f;
monster.m_HPMulti = 2.0f;
monster.m_DMGMulti = 1.3f;
// Give rewards
monster.GiveHP(50.0f); // Heal 50 HP
monster.GiveMP(25.0f); // Restore 25 MP
monster.GiveGold(100); // Add 100 gold
// Check stats
float currentHP = monster.m_HP;
float maxHP = monster.MaxHP();
float hpPercent = (currentHP / maxHP) * 100.0f;
MS_ANGEL_INFO("Monster HP: " + currentHP + "/" + maxHP + " (" + hpPercent + "%)");
MS_ANGEL_INFO("Gold: " + monster.m_Gold);
// Check combat state
if (monster.IsActing()) {
MS_ANGEL_INFO("Monster is attacking");
}
if (monster.IsShielding()) {
MS_ANGEL_INFO("Monster is blocking");
}
// Get stats
int strength = monster.GetNatStat(STAT_STRENGTH);
MS_ANGEL_INFO("Strength: " + strength);
}
}Example - Monster Casting:
void CastMonsterTypes() {
CBaseEntity@ entity = /* get entity */;
// Cast to CBaseMonster
CBaseMonster@ monster = ToMonster(entity);
if (monster !is null) {
MS_ANGEL_INFO("Entity is a monster");
monster.Look(1024);
}
// Cast to CMSMonster
CMSMonster@ msMonster = ToMSMonster(entity);
if (msMonster !is null) {
MS_ANGEL_INFO("Entity is an MS monster");
MS_ANGEL_INFO("HP: " + msMonster.m_HP + "/" + msMonster.MaxHP());
}
// Cast monster to entity
CBaseEntity@ backToEntity = ToEntity(monster);
}NOTE: All classes and functions in this section are available ONLY in client-side scripts (marked with #scope client in legacy scripts or loaded as client modules in AngelScript).
Client classes follow three main categories:
Entity Hierarchy:
CClientEntity (base)
└── CLocalPlayer
Effect Hierarchy:
CClientEffect (base)
├── CTempEntity
├── CDynamicLight
└── CBeam
Item Classes:
CGenericItem (standalone, read-only item data)
- CLocalPlayer inherits all entity query methods from CClientEntity (GetOrigin, GetAngles, GetVelocity, etc.)
- All effect classes inherit the
IsValid()method from CClientEffect - CGenericItem provides read-only access to item data for UI/display purposes
Scope: Client
Base class for all client-side visual effects.
class CClientEffect {
bool IsValid() const; // Check if effect is valid
}This class is inherited by CTempEntity, CDynamicLight, and CBeam.
Scope: Client
Read-only wrapper for client-side entity queries. This is the base class for CLocalPlayer.
class CClientEntity {
bool Exists() const; // Check if entity exists
int GetIndex() const; // Get entity index
Vector3 GetOrigin() const; // Get position
Vector3 GetAngles() const; // Get angles
Vector3 GetVelocity() const; // Get velocity
string GetModelName() const; // Get model path
int GetModelIndex() const; // Get model index
int GetRenderMode() const; // Get render mode
int GetRenderAmount() const; // Get render amount
Color GetRenderColor() const; // Get render color
bool IsPlayer() const; // Check if player entity
bool IsVisible() const; // Check if visible
Vector3 GetBonePosition(int) const; // Get bone position
int GetBoneCount() const; // Get bone count
Vector3 GetAttachment(int) const; // Get attachment position
int GetSequence() const; // Get animation sequence
float GetFrame() const; // Get animation frame
int GetBody() const; // Get body group
int GetSkin() const; // Get skin
}
// Global accessor
CClientEntity@ GetClientEntity(int index)Example:
void QueryEntity(int index) {
CClientEntity@ ent = GetClientEntity(index);
if (ent.Exists()) {
MS_ANGEL_INFO("Entity: " + ent.GetModelName());
MS_ANGEL_INFO("Position: " + ent.GetOrigin().x);
MS_ANGEL_INFO("Is Player: " + ent.IsPlayer());
}
}Scope: Client
The local player represents the player running the client. Inherits from CClientEntity.
class CLocalPlayer : CClientEntity {
// Inherited from CClientEntity:
// int GetIndex() const;
// Vector3 GetOrigin() const;
// Vector3 GetAngles() const;
// Vector3 GetVelocity() const;
// string GetModelName() const;
// ... and all other CClientEntity methods
// Local player specific methods:
Vector3 GetViewAngles() const; // Get view angles (camera)
bool IsThirdPerson() const; // Check if in third-person mode
bool IsUnderwater() const; // Check if underwater
Vector3 GetWaterOrigin() const; // Get water surface position
bool CanAttack() const; // Check if can attack
bool CanJump() const; // Check if can jump
bool CanDuck() const; // Check if can duck
bool CanRun() const; // Check if can run
bool CanMove() const; // Check if can move
int GetWaterLevel() const; // Get water level (0-3)
}
// Global accessor
CLocalPlayer@ GetLocalPlayer()Example:
void CheckLocalPlayer() {
CLocalPlayer@ player = GetLocalPlayer();
// Can use inherited CClientEntity methods
Vector3 pos = player.GetOrigin();
Vector3 angles = player.GetAngles();
string model = player.GetModelName();
MS_ANGEL_INFO("Player at: " + pos.x + "," + pos.y + "," + pos.z);
MS_ANGEL_INFO("Player model: " + model);
// Can use local player specific methods
if (player.IsUnderwater()) {
MS_ANGEL_INFO("Player is underwater!");
}
Vector3 viewAngles = player.GetViewAngles();
MS_ANGEL_INFO("Looking at: " + viewAngles.y + " degrees");
}Scope: Client
Temporary entity for client-side visual effects. Inherits from CClientEffect.
class CTempEntity : CClientEffect {
// Inherited from CClientEffect:
// bool IsValid() const;
// Transform
void SetOrigin(const Vector3 &in);
Vector3 GetOrigin() const;
void SetAngles(const Vector3 &in);
Vector3 GetAngles() const;
void SetVelocity(const Vector3 &in);
Vector3 GetVelocity() const;
// Appearance
void SetModel(const string &in);
void SetSprite(const string &in);
void SetScale(float);
float GetScale() const;
void SetFrame(int);
int GetFrame() const;
void SetFrameRate(float);
void SetBody(int);
void SetSkin(int);
// Rendering
void SetRenderMode(int);
void SetRenderAmount(int);
void SetRenderColor(const Color &in);
void SetRenderFx(int);
// Physics
void SetGravity(float);
void SetCollisionMode(CollisionMode);
void SetBounceFactor(float);
void SetMins(const Vector3 &in);
void SetMaxs(const Vector3 &in);
// Lifetime
void SetDeathDelay(float);
void SetFadeout(bool, float);
void Kill();
// Following
void FollowEntity(int entityIndex, int attachment = -1);
void StopFollowing();
// Custom data
void SetUserInt(int slot, int value);
int GetUserInt(int slot) const;
void SetUserFloat(int slot, float value);
float GetUserFloat(int slot) const;
// Callbacks (TODO)
void SetUpdateCallback(const string &in);
void SetCollisionCallback(const string &in);
void SetWaterCallback(const string &in);
void SetTimerCallback(float, const string &in);
}
enum CollisionMode {
None,
World,
All,
AllAndDie
}
// Factory functions
CTempEntity@ CreateTempSprite(const string &in spriteName, const Vector3 &in origin);
CTempEntity@ CreateTempModel(const string &in modelName, const Vector3 &in origin);
CTempEntity@ CreateFrameSprite(const string &in spriteName, const Vector3 &in origin);
CTempEntity@ CreateFrameModel(const string &in modelName, const Vector3 &in origin);Example:
void CreateExplosionEffect() {
Vector3 pos = Vector3(100, 200, 50);
CTempEntity@ sprite = CreateTempSprite("sprites/fire.spr", pos);
if (sprite.IsValid()) {
sprite.SetScale(2.0);
sprite.SetFrameRate(15.0);
sprite.SetRenderMode(kRenderTransAdd);
sprite.SetRenderAmount(200);
sprite.SetDeathDelay(1.0);
sprite.SetFadeout(true, 0.5);
}
}Scope: Client
Client-side dynamic lighting. Inherits from CClientEffect.
class CDynamicLight : CClientEffect {
// Inherited from CClientEffect:
// bool IsValid() const;
void SetOrigin(const Vector3 &in);
Vector3 GetOrigin() const;
void SetRadius(float);
void SetColor(const Color &in);
void SetDuration(float);
void SetDark(bool); // Dark light (removes light)
void FollowEntity(int entityIndex);
void Kill();
}
// Factory function
CDynamicLight@ CreateDynamicLight(const Vector3 &in origin, float radius,
const Color &in color, float duration = 0.0f);Example:
void CreateTorchLight() {
Vector3 pos = Vector3(100, 200, 50);
Color orange = Color(255, 128, 0, 255);
CDynamicLight@ light = CreateDynamicLight(pos, 256.0, orange, 5.0);
if (light.IsValid()) {
// Light will last 5 seconds
light.SetRadius(300.0); // Make it brighter
}
}Scope: Client
Client-side beam effects. Inherits from CClientEffect.
class CBeam : CClientEffect {
// Inherited from CClientEffect:
// bool IsValid() const;
void SetStartPos(const Vector3 &in);
void SetEndPos(const Vector3 &in);
void SetStartEntity(int entityIndex, int attachment);
void SetEndEntity(int entityIndex, int attachment);
void SetSprite(const string &in);
void SetWidth(float);
void SetAmplitude(float);
void SetBrightness(float);
void SetSpeed(float);
void SetFrameRate(float);
void SetColor(const Color &in);
void SetLife(float);
void Kill();
}
// Factory functions
CBeam@ CreateBeamPoints(const Vector3 &in start, const Vector3 &in end, const string &in sprite);
CBeam@ CreateBeamEntities(int startIdx, int startAttach, int endIdx, int endAttach, const string &in sprite);
CBeam@ CreateBeamEntPoint(int startIdx, int attachment, const Vector3 &in endPos, const string &in sprite);
// Effect utilities
void CreateSpark(const Vector3 &in origin);
void CreateSparkOnModel(int entityIndex, int attachment = 0);
void CreateDecal(int decalIndex, const Vector3 &in traceStart, const Vector3 &in traceEnd);Example:
void CreateLightningBeam() {
Vector3 start = Vector3(0, 0, 100);
Vector3 end = Vector3(100, 100, 0);
CBeam@ beam = CreateBeamPoints(start, end, "sprites/laserbeam.spr");
if (beam.IsValid()) {
beam.SetWidth(20.0);
beam.SetColor(Color(100, 100, 255, 255));
beam.SetBrightness(200.0);
beam.SetLife(2.0);
}
}Scope: Client
Client-side environment control (fog, screen tint, sky).
class CClientEnvironment {
// Fog control
void SetFogEnabled(bool);
bool GetFogEnabled() const;
void SetFogColor(const Color &in);
Color GetFogColor() const;
void SetFogDensity(float);
void SetFogStart(float);
void SetFogEnd(float);
void SetFogType(int);
// Screen effects
void SetScreenTint(const Color &in);
Color GetScreenTint() const;
void ClearScreenTint();
// Sky
void SetSkyTexture(const string &in);
string GetSkyName() const;
void SetLightGamma(float);
void SetMaxViewDistance(float);
}
// Global accessor
CClientEnvironment@ GetEnvironment()Example:
void SetDarkAtmosphere() {
CClientEnvironment@ env = GetEnvironment();
// Dark red screen tint
env.SetScreenTint(Color(50, 0, 0, 100));
// Enable fog
env.SetFogEnabled(true);
env.SetFogColor(Color(20, 0, 0, 255));
env.SetFogDensity(0.002);
}Scope: Client
Client-side audio playback.
class CClientSound {
void PlaySound(int channel, const string &in soundPath, float volume = 1.0f);
void SetVolume(int channel, const string &in soundPath, float volume);
void StopSound(int channel, const string &in soundPath);
void PlaySoundAtPosition(const Vector3 &in pos, const string &in soundPath, float volume = 1.0f);
}
// Global accessor
CClientSound@ GetClientSound()
// Sound channel constants
const int SOUND_CHANNEL_WEAPON = 0;
const int SOUND_CHANNEL_VOICE = 1;
const int SOUND_CHANNEL_STREAM = 5;Example:
void PlayAmbientSound() {
CClientSound@ sound = GetClientSound();
sound.PlaySound(SOUND_CHANNEL_STREAM, "ambient/wind.wav", 0.5);
}Scope: Client
// Trace/query functions
Vector3 GetGroundHeight(const Vector3 &in origin);
Vector3 GetSkyHeight(const Vector3 &in origin);
bool IsUnderSky(const Vector3 &in origin);
Vector3 TraceLine(const Vector3 &in start, const Vector3 &in end, bool worldOnly = false);
int TraceLineEntity(const Vector3 &in start, const Vector3 &in end);
int GetContents(const Vector3 &in origin);
// Client-specific accessors
float GetClientTime();
string GetCurrentMap();
bool IsClientSide(); // Always returns true on client
array<int>@ GetNearbyEntities(const Vector3 &in origin, float radius, bool playersOnly = false);Example:
void CheckGround() {
CLocalPlayer@ player = GetLocalPlayer();
Vector3 playerPos = player.GetOrigin();
Vector3 ground = GetGroundHeight(playerPos);
float distToGround = playerPos.z - ground.z;
MS_ANGEL_INFO("Distance to ground: " + distToGround);
if (IsUnderSky(playerPos)) {
MS_ANGEL_INFO("Player is under open sky");
}
}Scope: Client
Read-only access to item properties for client-side UI, display, and visualization. This class provides safe access to item data without exposing game logic.
Note: CGenericItem provides read-only methods only. All game logic (use, drop, equip, etc.) must be handled server-side.
class CGenericItem {
// Basic Properties
string GetItemName() const; // Internal item name (e.g., "dagger")
int GetItemID() const; // Unique item instance ID
int GetQuality() const; // Current item quality/durability
int GetMaxQuality() const; // Maximum quality value
int GetQuantity() const; // Stack quantity (for groupable items)
int GetMaxQuantity() const; // Maximum stack size
float GetWeight() const; // Item weight
uint GetValue() const; // Gold value
int GetLocation() const; // Item location (ITEMPOS_* constants)
int GetHand() const; // Which hand (LEFT_HAND/RIGHT_HAND)
// Visual/Rendering Properties
string GetViewModel() const; // View model path (1st person)
string GetPlayerHoldModel() const; // Player hold model (3rd person)
string GetAnimExtension() const; // Animation extension
string GetAnimExtensionLegs() const; // Leg animation extension
int GetRenderMode() const; // Render mode (kRender*)
int GetRenderAmount() const; // Render amount (0-255)
int GetRenderFx() const; // Render effects
int GetSkin() const; // Model skin index
int GetViewModelAnim() const; // Current view model animation
float GetViewModelAnimSpeed() const; // View model animation speed
// Item Type Checks
bool IsWorn() const; // Is currently worn/equipped
bool IsArmor() const; // Is armor piece
bool IsWearable() const; // Can be worn
bool IsShield() const; // Is a shield
bool IsGroupable() const; // Can stack with others
bool IsContainer() const; // Can hold other items
bool IsProjectile() const; // Is a projectile/ammo
bool IsDrinkable() const; // Can be consumed as drink
bool IsPerishable() const; // Has expiration/decay
bool IsSpell() const; // Is a spell scroll/tome
// Container Methods (for container items)
int Container_ItemCount() const; // Number of items in container
float Container_Weight() const; // Total weight of contents
bool Container_IsOpen() const; // Is container open
float Volume() const; // Item volume
// Attack Information
int GetAttackCount() const; // Number of attack modes
}Location Constants:
const int ITEMPOS_NONE = 0;
const int ITEMPOS_HANDS = 1;
const int ITEMPOS_BODY = 2;Hand Constants:
const int LEFT_HAND = 0;
const int RIGHT_HAND = 1;Example - Displaying Item Info in UI:
void DisplayItemTooltip(CGenericItem@ pItem) {
if (pItem is null) return;
string tooltip = "=== " + pItem.GetItemName() + " ===\n";
tooltip += "Value: " + pItem.GetValue() + " gold\n";
tooltip += "Weight: " + pItem.GetWeight() + " kg\n";
tooltip += "Quality: " + pItem.GetQuality() + "/" + pItem.GetMaxQuality() + "\n";
// Check item type
if (pItem.IsWearable()) {
tooltip += "Type: Wearable\n";
tooltip += "Equipped: " + (pItem.IsWorn() ? "Yes" : "No") + "\n";
}
if (pItem.IsContainer()) {
tooltip += "Container: " + pItem.Container_ItemCount() + " items\n";
tooltip += "Total Weight: " + pItem.Container_Weight() + " kg\n";
}
if (pItem.IsGroupable()) {
tooltip += "Quantity: " + pItem.GetQuantity() + "/" + pItem.GetMaxQuantity() + "\n";
}
MS_ANGEL_INFO(tooltip);
}Example - Filtering Items by Type:
void ShowWeapons(array<CGenericItem@>@ items) {
for (uint i = 0; i < items.length(); i++) {
CGenericItem@ pItem = items[i];
// Check if item has attack capability
if (pItem.GetAttackCount() > 0) {
MS_ANGEL_INFO("Weapon: " + pItem.GetItemName());
MS_ANGEL_INFO(" Attacks: " + pItem.GetAttackCount());
MS_ANGEL_INFO(" Hand: " + (pItem.GetHand() == LEFT_HAND ? "Left" : "Right"));
}
}
}Example - Rendering Information:
void CheckItemVisuals(CGenericItem@ pItem) {
if (pItem is null) return;
MS_ANGEL_INFO("View Model: " + pItem.GetViewModel());
MS_ANGEL_INFO("World Model: " + pItem.GetPlayerHoldModel());
MS_ANGEL_INFO("Render Mode: " + pItem.GetRenderMode());
MS_ANGEL_INFO("Skin: " + pItem.GetSkin());
// Check transparency
if (pItem.GetRenderMode() == kRenderTransAlpha) {
int alpha = pItem.GetRenderAmount();
MS_ANGEL_INFO("Item is " + (alpha < 128 ? "mostly transparent" : "mostly opaque"));
}
}Scope: Client
The VGUI (Valve GUI) system allows client-side scripts to create custom user interfaces with interactive elements like buttons, labels, text fields, and frames.
VGUIPanel (base class)
├── VGUIFrame (windowed panels with title bars)
├── VGUIButton (clickable buttons)
├── VGUILabel (text display)
├── VGUITextEntry (text input fields)
└── VGUIImagePanel (image display)
Scope: Client
Base class for all VGUI panels. Provides core functionality for positioning, sizing, visibility, and hierarchy.
class VGUIPanel {
// Validity
bool IsValid();
// Position and sizing
void SetPos(int x, int y);
void SetSize(int wide, int tall);
void SetBounds(int x, int y, int wide, int tall);
// Visibility
void SetVisible(bool state);
bool IsVisible();
// Hierarchy
void SetParent(VGUIPanel@ parent);
void AddChild(VGUIPanel@ child);
void RemoveChild(VGUIPanel@ child);
// Appearance
void SetFgColor(int r, int g, int b, int a);
void SetBgColor(int r, int g, int b, int a);
// Rendering
void Repaint();
void SetPaintEnabled(bool enabled);
// Input
bool IsMouseOver();
// Cleanup
void Remove(); // Remove from parent
}SetPos / SetSize / SetBounds: Position and size the panel
- Coordinates are in screen space (pixels)
- Position (0,0) is top-left corner of screen
SetVisible: Show or hide the panel and all its children
SetParent / AddChild / RemoveChild: Manage panel hierarchy
- Child panels move with their parent
- Child visibility is affected by parent visibility
SetFgColor / SetBgColor: Set foreground and background colors
- Parameters: red (0-255), green (0-255), blue (0-255), alpha (0-255)
- Alpha 0 = fully transparent, 255 = fully opaque
IsMouseOver: Check if mouse cursor is over this panel
Remove: Remove panel from its parent (panel remains valid until released)
Scope: Client
Windowed panels with title bars, dragging support, and optional close/minimize buttons.
class VGUIFrame : VGUIPanel {
// All VGUIPanel methods, plus:
void SetTitle(const string& in);
void SetMoveable(bool);
void SetSizeable(bool);
void SetCloseButton(bool);
void SetMinimizeButton(bool);
void Center(); // Center on screen
}SetTitle: Set the title bar text
SetMoveable: Allow/disallow dragging the frame by its title bar
SetSizeable: Allow/disallow resizing the frame by dragging edges
SetCloseButton / SetMinimizeButton: Show/hide window control buttons
Center: Position the frame at the center of the screen
Example:
VGUIFrame@ frame = CreateFrame(100, 100, 400, 300, "My Window");
frame.SetMoveable(true);
frame.SetSizeable(false);
frame.SetCloseButton(true);
frame.Center();
frame.SetVisible(true);Scope: Client
Clickable buttons with callback support.
class VGUIButton : VGUIPanel {
// All VGUIPanel methods, plus:
void SetText(const string& in);
void SetCallback(const string& in); // Function name to call when clicked
void SetEnabled(bool);
void SetArmedColor(int r, int g, int b, int a); // Color when mouse over
void SetDepressedColor(int r, int g, int b, int a); // Color when clicked
}SetText: Set the button's label text
SetCallback: Set the AngelScript function to call when button is clicked
- Function must exist in the global scope
- Function takes no parameters and returns void
SetEnabled: Enable/disable the button (disabled buttons can't be clicked)
SetArmedColor: Color when mouse hovers over button
SetDepressedColor: Color when button is being clicked
Example:
void OnMyButtonClick() {
MS_ANGEL_INFO("Button was clicked!");
}
VGUIButton@ btn = CreateButton("Click Me", 50, 50, 120, 30);
btn.SetCallback("OnMyButtonClick");
btn.SetArmedColor(255, 200, 100, 255); // Orange when hovering
btn.SetVisible(true);Scope: Client
Static text display with formatting options.
class VGUILabel : VGUIPanel {
// All VGUIPanel methods, plus:
void SetText(const string& in);
void SetTextColor(int r, int g, int b, int a);
void SetContentAlignment(int alignment); // 0=left, 1=center, 2=right
}SetText: Set the label text
SetTextColor: Set the color of the text
SetContentAlignment: Align text within the label
- 0 = left-aligned
- 1 = center-aligned
- 2 = right-aligned
Example:
VGUILabel@ label = CreateLabel("Player Health: 100", 10, 10, 200, 30);
label.SetTextColor(0, 255, 0, 255); // Green text
label.SetContentAlignment(0); // Left-aligned
label.SetVisible(true);Scope: Client
Text input fields for user text entry.
class VGUITextEntry : VGUIPanel {
// All VGUIPanel methods, plus:
void SetText(const string& in);
string GetText();
void SetEditable(bool);
void SetMaxLength(int); // Note: Not fully supported in base VGUI
void SetMultiline(bool); // Note: Use TextPanel for multiline
}SetText / GetText: Set or retrieve the current text
SetEditable: Allow/disallow editing
Example:
VGUITextEntry@ entry = CreateTextEntry(10, 50, 200, 30);
entry.SetText("Enter your name");
entry.SetEditable(true);
entry.SetVisible(true);
// Later, retrieve the text:
string playerName = entry.GetText();Scope: Client
Display images (sprites or textures).
class VGUIImagePanel : VGUIPanel {
// All VGUIPanel methods, plus:
void SetImage(const string& in); // Set image path
void SetScaleImage(bool); // Scale image to fit panel size
}SetImage: Set the image to display
- Path relative to game directory
- Supports TGA format
SetScaleImage: Whether to scale the image to fit the panel bounds
Example:
VGUIImagePanel@ img = CreateImagePanel("gfx/vgui/logo.tga", 100, 100, 256, 256);
img.SetScaleImage(true);
img.SetVisible(true);Scope: Client
Factory functions for creating VGUI panels.
// Create windowed frame
VGUIFrame@ CreateFrame(int x, int y, int wide, int tall, const string& in title);
// Create button
VGUIButton@ CreateButton(const string& in text, int x, int y, int wide, int tall);
// Create label
VGUILabel@ CreateLabel(const string& in text, int x, int y, int wide, int tall);
// Create text entry field
VGUITextEntry@ CreateTextEntry(int x, int y, int wide, int tall);
// Create image panel
VGUIImagePanel@ CreateImagePanel(const string& in imagePath, int x, int y, int wide, int tall);
// Create generic panel (container)
VGUIPanel@ CreatePanel(int x, int y, int wide, int tall);Scope: Client
// Get screen dimensions
void GetScreenSize(int& out wide, int& out tall);
// Check if panel is valid
bool IsPanelValid(VGUIPanel@ panel);GetScreenSize: Retrieve the current screen resolution
- Use for positioning panels relative to screen size
IsPanelValid: Check if a panel pointer is valid and not null
Scope: Client
Here's a complete example showing how to create a custom dialog:
// Global variables to keep panels alive
VGUIFrame@ g_CustomDialog;
VGUILabel@ g_MessageLabel;
VGUIButton@ g_OkButton;
VGUIButton@ g_CancelButton;
void ShowCustomDialog(const string& in message) {
// Create frame
g_CustomDialog = CreateFrame(0, 0, 400, 200, "Notification");
g_CustomDialog.Center();
g_CustomDialog.SetMoveable(true);
g_CustomDialog.SetCloseButton(true);
// Create message label
g_MessageLabel = CreateLabel(message, 20, 50, 360, 60);
g_MessageLabel.SetTextColor(255, 255, 255, 255);
g_MessageLabel.SetContentAlignment(1); // Center
g_CustomDialog.AddChild(g_MessageLabel);
// Create OK button
g_OkButton = CreateButton("OK", 100, 140, 80, 30);
g_OkButton.SetCallback("OnDialogOK");
g_OkButton.SetArmedColor(100, 200, 100, 255);
g_CustomDialog.AddChild(g_OkButton);
// Create Cancel button
g_CancelButton = CreateButton("Cancel", 220, 140, 80, 30);
g_CancelButton.SetCallback("OnDialogCancel");
g_CancelButton.SetArmedColor(200, 100, 100, 255);
g_CustomDialog.AddChild(g_CancelButton);
// Show dialog
g_CustomDialog.SetVisible(true);
}
void OnDialogOK() {
MS_ANGEL_INFO("User clicked OK");
HideCustomDialog();
}
void OnDialogCancel() {
MS_ANGEL_INFO("User clicked Cancel");
HideCustomDialog();
}
void HideCustomDialog() {
if (g_CustomDialog !is null && g_CustomDialog.IsValid()) {
g_CustomDialog.SetVisible(false);
@g_CustomDialog = null; // Release references
@g_MessageLabel = null;
@g_OkButton = null;
@g_CancelButton = null;
}
}-
Entity Lifetime: Entity references (CBaseEntity@, CBasePlayer@, CBaseMonster@, CMSMonster@) are managed by the game engine. Scripts should not attempt to delete entities directly.
-
Array Types: The
array<T>template type is available for creating dynamic arrays of any registered type. -
Dictionary Type: A dictionary type is available for key-value storage.
-
String Type: Strings in AngelScript use the
stringtype with full UTF-8 support. -
Reference Counting: Reference types (marked with @) use automatic reference counting. The engine manages the lifetime of game objects.
-
Null Checking: Always check entity references for null before use:
CBasePlayer@ player = PlayerByIndex(1); if (player !is null) { // Safe to use player }
-
Type Safety: AngelScript is strongly typed. Use appropriate casting functions when converting between types.
- 1.0: Initial documentation based on ASBindings.cpp and ASEntityBindings.cpp analysis
- 1.1: Added comprehensive module system documentation from ASModuleSystem.h and scriptmodule.h
- 1.2: Added comprehensive CBaseMonster and CMSMonster bindings with full property access and AI control methods
- 1.3: Added complete client-side AngelScript API documentation including CLocalPlayer, CClientEntity, CTempEntity, CDynamicLight, CBeam, CClientEnvironment, CClientSound, and client utility functions
- 1.4: Refactored client-side classes to use inheritance hierarchies using asbind20's
.base<>()feature:- CClientEffect base class for effects (CTempEntity, CDynamicLight, CBeam)
- CLocalPlayer now inherits from CClientEntity, gaining all entity query methods
- 1.5: Added comprehensive VGUI (Valve GUI) system for client-side custom UI creation:
- VGUIPanel base class for all UI elements
- VGUIFrame for windowed interfaces
- VGUIButton with callback support
- VGUILabel for text display
- VGUITextEntry for user input
- VGUIImagePanel for image display
- Factory functions and complete usage examples