diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 9b5b076..8a100a4 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -7,8 +7,11 @@ - [BattleGround](./classes/BattleGround.md) - [Corpse](./classes/Corpse.md) - [Creature](./classes/Creature.md) + - [Map](./classes/EMap.md) - [GameObject](./classes/GameObject.md) - [Group](./classes/Group.md) + - [Item](./classes/Item.md) + - [Object](./classes/EObject.md) - [Player](./classes/Player.md) - [Unit](./classes/Unit.md) - [WorldObject](./classes/WorldObject.md) diff --git a/docs/classes/EMap.md b/docs/classes/EMap.md new file mode 100644 index 0000000..676cc44 --- /dev/null +++ b/docs/classes/EMap.md @@ -0,0 +1,354 @@ +## GetAreaId +This method returns the area ID of the [Map] based on the specified X, Y, and Z coordinates. The `phasemask` parameter allows specifying the phase for phased content, providing flexibility for scripting events or actions that depend on the game's current state. + +### Parameters +- `x`: number - The X coordinate on the map +- `y`: number - The Y coordinate on the map +- `z`: number - The Z coordinate on the map +- `phasemask`: number (optional) - The phasemask for phased areas + +### Returns +areaId: number - The area ID of the specified location on the map. + +### Example Usage: +Scripting a scenario to check players' locations to trigger a custom event. +```typescript +const AREA_ID_ELVEN_FOREST = 123; // Example area ID for Elven Forest +const EVENT_PHASEMASK = 1; // Default phase + +const onPlayerMove: player_event_on_update_zone = (event: number, player: Player, newZone: number, newArea: number): void => { + const playerX = player.GetX(); + const playerY = player.GetY(); + const playerZ = player.GetZ(); + + const playerAreaId = player.GetMap().GetAreaId(playerX, playerY, playerZ, EVENT_PHASEMASK); + + if(playerAreaId === AREA_ID_ELVEN_FOREST) { + // Trigger a custom event or action for the player + TriggerCustomEventForPlayer(player); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_UPDATE_ZONE, (...args) => onPlayerMove(...args)); + +function TriggerCustomEventForPlayer(player: Player) { + // Logic to trigger the event for the player + player.SendAreaTriggerMessage("Welcome to the Elven Forest! Custom Events await you."); +} +``` +This snippet demonstrates how to use `GetAreaId` to trigger a custom event when a player enters a specific area. By checking the area ID where the player moves, developers can script immersive experiences tailored to different locations in the game. + +# GetDifficulty +This method retrieves the difficulty level of the current map where the EMap instance is located. It's important to note that if the game expansion is before The Burning Crusade (pre-TBC), this method will always return `0`, implying that difficulty levels introduced in later expansions are not applicable. + +### Returns +difficulty: `number` - The difficulty of the map. This is an integer where `0` usually signifies a normal difficulty setting. Higher numbers indicate increased difficulty levels such as heroic or mythic, depending on the context and game expansion. + +### Example Usage: +```typescript +const onPlayerEnterMap: map_event_on_create = (event: number, map: EMap): void => { + let mapDifficulty = map.GetDifficulty(); + + // Log the difficulty level. If the game is pre-TBC, it will log '0'. + console.log(`Entered map with difficulty level: ${mapDifficulty}`); + + // You can use the difficulty information to customize player experience + if (mapDifficulty > 0) { + console.log("This map has increased difficulty."); + // Implement difficulty-based enhancements or challenges here. + } else { + console.log("Standard difficulty or pre-TBC map. Setting normal challenges."); + // Implement standard gameplay features here. + } +} + +RegisterMapEvent(MapEvents.MAP_EVENT_ON_CREATE, (...args) => onPlayerEnterMap(...args)); +``` + +In this example, whenever a player enters a map, it checks the difficulty of the map using `GetDifficulty()`. The script then logs the difficulty level, demonstrating how to use the method to adjust game logic based on map difficulty. This can be particularly useful for custom scripts or mods that aim to enhance player experience or provide challenges based on the difficulty level of the map they are in. The example also highlights the backward compatibility with pre-TBC expansions by handling cases where the difficulty level is always `0`. + +## GetHeight + +This method returns the elevation (height) of the terrain/map at a specific X and Y coordinate. It’s particularly useful for scripts that need to spawn objects or characters at precise locations above the ground. If the method cannot find a height (for example, if the coordinates are out of bounds), it returns `nil`. + +### Parameters + +* `x`: number - The X coordinate on the map. +* `y`: number - The Y coordinate on the map. + +### Returns + +* `height`: number | `nil` - The height at the given coordinates, or `nil` if no height data is available. + +### Example Usage: + +Let’s say you're creating a custom event where a treasure chest appears at random locations within a defined area, but you need to ensure it spawns on the ground. The `GetHeight` method can be used to dynamically adjust the Z (height) coordinate for the spawn location. + +```typescript +function SpawnTreasureChest(map: EMap, minX: number, maxX: number, minY: number, maxY: number): void { + // Generate random X and Y within the specified bounds + const x = Math.random() * (maxX - minX) + minX; + const y = Math.random() * (maxY - minY) + minY; + + // Get the ground height at the generated X and Y coordinates + const z = map.GetHeight(x, y); + + // Check if a height was found + if (z !== null) { + // Assuming SpawnChest is a function you've defined to spawn a chest at given coordinates + SpawnChest(x, y, z); + console.log(`Spawned a chest at coordinates: ${x}, ${y}, ${z}`); + } else { + console.log("Failed to find a suitable spawn height. Trying again..."); + SpawnTreasureChest(map, minX, maxX, minY, maxY); // Recursive call to try again + } +} + +// Example call to our function +const myMap = new EMap(); +SpawnTreasureChest(myMap, 5000, 5500, 5000, 5500); +``` + +This script randomly selects X and Y coordinates within specified boundaries and uses the `GetHeight` method to find an appropriate Z coordinate so the chest spawns on the ground. If `GetHeight` returns `nil` (indicating no valid ground was found at those coordinates), the script tries again with new coordinates. + +## GetInstanceData +Retrieves a data table for the map's instance if the instance has been scripted using Eluna. This method serves as a bridge for Lua scripted encounters to store and manage their data. Should the instance be managed through C++, this method will return `nil`, indicating the absence of a Lua-scripted data table. + +### Returns +dataTable: `Record[]` - A JavaScript object array with string keys, representative of the instance's data. If no data or if not scripted in Eluna, returns `nil`. + +### Example Usage: +Below is an example of how to retrieve instance data for a custom scripted boss encounter, checking for the existence of data before attempting to use it, and initializing the data if it does not exist. + +```typescript +const initializeBossData = (map: EMap) => { + // Attempt to retrieve existing instance data + let instanceData = map.GetInstanceData(); + + // If no data exists, initialize it + if (instanceData == null) { + instanceData = [{ bossDefeated: false, playersParticipated: [] }]; + console.log("Instance data initialized for scripted boss event."); + } else { + console.log("Instance data retrieved for ongoing boss event."); + } + + // Check if the boss has already been defeated in this instance + if (instanceData[0].bossDefeated) { + console.log("The boss has already been defeated in this instance."); + } else { + console.log("The boss is still alive. Good luck adventurers!"); + } +}; + +const OnMapLoad: map_event_on_load = (event: number, map: EMap) => { + // Initialize or retrieve boss data when a map loads + initializeBossData(map); +}; + +RegisterMapEvent(MapEvents.MAP_EVENT_ON_LOAD, (...args) => OnMapLoad(...args)); +``` +This script demonstrates initializing or retrieving custom data for a given map instance. It can be particularly useful for server-side mods that enhance gameplay through scripted events, tracking player progress, or managing complex encounter states in AzerothCore via mod-eluna. + +## GetInstanceId +This method retrieves the instance ID of the current [Map] where the player or unit resides. Instance IDs +are unique identifiers for instances (dungeons, raids, etc.) which are used to separate different instance runs +from each other. This can be useful for scripts that need to apply logic specific to a particular instance run. + +### Returns +instanceId: number - The unique identifier for the instance of the current [Map]. + +### Example Usage: +In this example, we create a simple script that announces the instance ID to the player upon entering an instance. This can be particularly useful for custom dungeon or raid scripts where actions might depend on the specific instance run. + +```typescript +const onPlayerEnterInstance: player_event_on_enter_instance = (event: number, player: Player, map: EMap): void => { + const instanceId = map.GetInstanceId(); + player.SendBroadcastMessage(`Welcome! The Instance ID for this run is: ${instanceId}`); +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_ENTER_INSTANCE, (...args) => onPlayerEnterInstance(...args)); +``` +In this script, we listen for the `PLAYER_EVENT_ON_ENTER_INSTANCE` event, which is triggered whenever a player enters an instance. Upon triggering, our `onPlayerEnterInstance` function is called, which fetches the instance ID of the [Map] the player has just entered using `GetInstanceId()`. Finally, it sends a broadcast message to the player, welcoming them and informing them about the current instance ID. This is a basic example to illustrate how `GetInstanceId()` can be used in modding efforts on AzerothCore with mod-eluna. + +## GetMapId +This method retrieves the unique identifier of the current map in which the entity is present. This ID corresponds to the 'id' column in the 'maps' table of the AzerothCore database. Knowing the map ID can help with various scripting tasks, such as conditional events based on the player's location. + +### Returns +* **mapId**: number - The unique identifier of the current map. + +### Example Usage: +Let's create a script that announces the current map ID to the player upon entering a new map. This could be useful for debug purposes or specialized events that only occur in certain areas. + +```typescript +const onMapChange: player_event_on_map_change = (event: number, player: Player): void => { + // Retrieve the map ID where the player currently is + const mapId = player.GetMapId(); + + // Inform the player of their current map ID + player.SendBroadcastMessage(`Welcome! You are currently in map ID: ${mapId}`); +} + +// Register the event to trigger upon map change +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_MAP_CHANGE, (...args) => onMapChange(...args)); +``` + +In this example, we've used the `GetMapId` method to fetch the current map ID where the player is located. This information is then communicated to the player through a broadcast message. This script can be particularly useful for developers or administrators when testing map-specific features or simply to inform players about their current location in a more detailed manner. + +## GetName + +This method retrieves the name of the current [Map] the character is in. Map names can be used to check player locations against specific criteria in your scripts. + +### Returns +- **string** - The name of the map. + +### Example Usage: + +Imagine you want to create a welcome message for players when they enter a specific zone, such as Stormwind City. You can use the `GetName` method to check the player's current map and then trigger the welcome message. + +```typescript +const welcomeMessage = { + "Stormwind": "Welcome to Stormwind City, the pride of the Alliance!", + "Orgrimmar": "Welcome to Orgrimmar, the heart of the Horde." +}; + +const onPlayerMapChange: player_event_on_map_change = (event: number, player: Player): void => { + const currentMap = player.GetMap(); + const mapName = currentMap.GetName(); + + // Check if welcome message exists for the current map + const message = welcomeMessage[mapName]; + if(message) { + player.SendAreaTriggerMessage(message); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_MAP_CHANGE, (...args) => onPlayerMapChange(...args)); +``` +In this script, when the `PLAYER_EVENT_ON_MAP_CHANGE` event is triggered, indicating the player has changed maps, it retrieves the map object the player is currently in using `GetMap()`. Then, it retrieves the name of the map with `GetName()`. Based on the map name, it looks up a predefined message in the `welcomeMessage` object. If a message exists for that map, it sends the message to the player using `SendAreaTriggerMessage()`. + +This example demonstrates a practical application of the `GetName` method, where it's important to know the map's identifier to execute conditional logic. + +## GetPlayerCount +This method retrieves the total number of players present on a specific [Map], excluding Game Masters (GMs). This can be useful for dynamically adjusting game mechanics based on player population or for collecting statistics. + +### Returns +- **number**: The count of players currently on the map (excluding GMs). + +### Example Usage: +Used in a scenario where an event is triggered based on the current player population on a map. The event starts only if there are at least 10 players on the map, excluding GMs. This ensures active participation and competition among players. + +```typescript +const MIN_PLAYERS_FOR_EVENT = 10; + +const StartEventIfEnoughPlayers: map_event_on_update = (event: number, map: EMap) => { + const playerCount = map.GetPlayerCount(); + + if (playerCount >= MIN_PLAYERS_FOR_EVENT) { + console.log(`Starting event, player count: ${playerCount}`); + // StartEvent(); // Placeholder for event start function + } else { + console.log(`Not enough players to start event. Current count: ${playerCount}`); + // Wait or schedule to try again later + } +} + +// Example registration for a map update event, adjusting based on actual mod-eluna event system +RegisterMapEvent(MapEvents.MAP_EVENT_ON_UPDATE, (...args) => StartEventIfEnoughPlayers(...args)); +``` +This script checks the player count on a map at certain update intervals. It logs a message and starts an event when the player count meets or exceeds the minimum requirement. Conversely, it logs a different message when the condition isn't met, possibly waiting or scheduling a check for a later time. + +## GetPlayers +Retrieves the players that are currently present in a specified map and belong to a particular team. This can be used to perform operations on a group of players based on their team affiliation within a map. Teams are identified by the `TeamId` enum, which includes `TEAM_ALLIANCE`, `TEAM_HORDE`, and `TEAM_NEUTRAL`. + +### Parameters +- `team`: TeamId - The team ID to filter players. Choose from `TEAM_ALLIANCE`, `TEAM_HORDE`, or `TEAM_NEUTRAL`. + +### Returns +- `players`: number[] - An array of player IDs that match the specified team criteria in the map. + +### Examples +#### Creating a Buff Zone +In this example, we create an area where players of the Alliance team receive a temporary buff when they enter. + +```typescript +enum TeamId { + TEAM_ALLIANCE = 0, + TEAM_HORDE = 1, + TEAM_NEUTRAL = 2 +}; + +const BUFF_SPELL_ID = 469; // Example buff spell ID + +const ApplyBuffToAlliancePlayers: map_event_on_enter = (mapId: number, player: Player) => { + const map = GetMapById(mapId); + const alliancePlayers = map.GetPlayers(TeamId.TEAM_ALLIANCE); + + for (let playerId of alliancePlayers) { + const player = GetPlayerById(playerId); + player.CastSpell(player, BUFF_SPELL_ID, true); // Assumes a function exists to fetch player by ID + } +} + +RegisterMapEvent(MapEvents.MAP_EVENT_ON_PLAYER_ENTER, (...args) => ApplyBuffToAlliancePlayers(...args)); +``` + +#### Horde vs Alliance Announcement +This script announces the number of Horde and Alliance players in a specific map, encouraging PvP interactions. + +```typescript +enum TeamId { + TEAM_ALLIANCE = 0, + TEAM_HORDE = 1, + TEAM_NEUTRAL = 2 +}; + +const AnnounceTeamPresence: map_event_on_update = (mapId: number) => { + const map = GetMapById(mapId); + + const alliancePlayers = map.GetPlayers(TeamId.TEAM_ALLIANCE).length; + const hordePlayers = map.GetPlayers(TeamId.TEAM_HORDE).length; + + SendWorldMessage(`Alliance players in the area: ${alliancePlayers}. Horde players in the area: ${hordePlayers}. Let the battle begin!`); +} + +RegisterMapEvent(MapEvents.MAP_EVENT_ON_UPDATE, (...args) => AnnounceTeamPresence(...args)); +``` + +These examples demonstrate how to use the `GetPlayers` method to identify players of specific teams within a map to apply effects or send messages based on their team affiliation. + +## GetWorldObject +Retrieve a [WorldObject](./worldobject.md) using its GUID if it's spawned on the map. This can be useful for scripts that need to interact with specific objects in the world, such as NPCs, items, or even dynamic objects that are part of quests or events. + +### Parameters +* `guid`: number - Globally Unique Identifier of the [WorldObject](./worldobject.md) you're trying to retrieve. + +### Returns +* `WorldObject | null` - Returns the [WorldObject](./worldobject.md) if found on the current map; otherwise, `null`. + +### Example Usage: +This script demonstrates how to find a specific NPC by GUID and make it say something in the game world. This could be part of a larger event or a custom quest where interacting with specific world entities is required. + +```typescript +const NPC_GUID: number = 12345; // Example GUID of an NPC +const SAY_TEXT: string = "Greetings, adventurers!"; + +// Example event: Player enters the area +const onPlayerEnterArea: player_event_on_area = (event: number, player: Player, newArea: number) => { + // Attempt to find the NPC by its GUID + const npc = player.GetMap().GetWorldObject(NPC_GUID) as Unit | null; + + if (npc !== null && npc.IsNPC()) { + // Make the NPC say something if it's found + npc.Say(SAY_TEXT, 0); // 0 is the default chat type for SAY + } else { + console.error(`NPC with GUID ${NPC_GUID} could not be found or is not spawned.`); + } +} + +// Register the event hook for demonstration purposes +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_AREA_CHANGE, (...args) => onPlayerEnterArea(...args)); +``` + +This example attempts to retrieve a specific NPC on the map using its GUID when a player enters a new area. If the NPC is found and is currently spawned on the map, it will say designated text, offering countless opportunities for dynamic player interactions in the game world. + diff --git a/docs/classes/EObject.md b/docs/classes/EObject.md new file mode 100644 index 0000000..c883c29 --- /dev/null +++ b/docs/classes/EObject.md @@ -0,0 +1,1068 @@ +## GetByteValue + +Extracts a byte value at a specified index and offset within the `EObject`, casting the result to an unsigned 8-bit integer. This function is particularly useful for accessing raw data of game objects in a detailed manner, allowing for advanced manipulation and inspection based on the data's storage sequence. + +### Parameters +* `index`: number - The starting point within the data structure from where you want to begin reading. +* `offset`: number - The offset (in bytes) from the specified index, determining the exact byte to be read and returned. + +### Returns +* `value`: number - The value of the byte at the given index and offset, represented as an unsigned 8-bit integer. + +### Example Usage: + +In this example, we're assuming an enhanced scenario where players can have custom attributes or states defined in their data, perhaps for a modded server feature. Let's say at data index `5`, we have custom bytes that represent various custom states (for simplicity, we'll say each byte at this index could represent a different state, such as invisibility, invulnerability, etc.). Using the `GetByteValue` method, we want to check if a player has a specific state enabled - invisibility in this case, hypothetically stored in the second byte at index `5`. + +```typescript +// Define constants for readability +const CUSTOM_STATE_INDEX = 5; // Hypothetical index for custom states +const INVISIBILITY_OFFSET = 1; // Assuming invisibility state is stored as the second byte at the custom state index + +// Function to check if a player is invisible based on the custom attribute +function checkPlayerInvisibility(player: EObject): boolean { + const invisibilityByte = player.GetByteValue(CUSTOM_STATE_INDEX, INVISIBILITY_OFFSET); + + // Assuming a nonzero value indicates the state is active + return invisibilityByte !== 0; +} + +// Sample usage within an event where you might need to check a player's invisibility state +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_TARGETED, (event: number, player: EObject) => { + if(checkPlayerInvisibility(player)) { + // Handle scenario where player is invisible + console.log("Player is currently invisible!"); + } else { + console.log("Player is visible."); + } +}); +``` + +In the function `checkPlayerInvisibility`, we directly utilize the `GetByteValue` method to obtain the specific byte that indicates whether the invisibility state is active for the player. Based on the obtained value, the function returns true (for invisible) or false (for visible), which could then influence how the player is interacted with in various game scenarios. + +# GetEntry + +This method retrieves the unique entry ID associated with an object. It's important to note that *Players* do not have an "entry" in the same way other entities, such as NPCs or Items, do within the game. This method is particularly useful when trying to distinguish between different types of entities or when specific actions need to be taken based on the object's entry ID. + +### Returns + +- **entry:** number - The entry ID of the object. For Players, this method does not apply. + +### Example Usage: + +This example demonstrates how to check the entry ID of an item a player loots to trigger a special event if the item matches a certain entry ID. + +```typescript +const SPECIAL_ITEM_ENTRY = 12345; // Example entry ID for a special item + +const CheckSpecialItemLoot: player_event_on_loot_item = (event: number, player: Player, item: Item) => { + if(item.GetEntry() === SPECIAL_ITEM_ENTRY) { + // Execute special event, like giving the player a buff or starting a quest. + console.log("Special item looted! Starting special event..."); + // Example: StartSpecialEventForPlayer(player); + } else { + console.log("Regular item looted. Carry on!"); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => CheckSpecialItemLoot(...args)); +``` + +In this script, the `GetEntry` method is utilized to check if the item looted by the player matches a specific entry ID we are interested in. Upon matching, it could trigger additional actions like granting the player a unique buff, starting a quest, or any special event associated with that item. This approach allows for a dynamic way to create interactions based on item loot events while still being general enough to be applied to various scenarios where an Object's entry ID is crucial. + +## GetFloatValue +Retrieves a specific float value from an `EObject` based on the specified index. +This method is essential for accessing various float-type data embedded within objects. + +### Parameters +* `index`: number - The index at which the float value is stored. + +### Returns +* `number` - The floating-point value retrieved from the specified index of the `EObject`. + +### Example Usage: +Monitor a player's swimming height to trigger specific events when they reach a certain depth. This could be used to simulate underwater pressure effects or unlock underwater secrets when a player reaches a specific depth. + +```typescript +const PLAYER_SWIM_DEPTH_EVENT = 25; // Custom event ID +const SWIM_DEPTH_INDEX = 3; // Hypothetical index where swim depth is stored +const CRITICAL_DEPTH = 50.0; // Example depth at which an event is triggered + +// Function to check player's depth and react appropriately +const checkSwimDepth = (player: Player): void => { + let eObject: EObject = player; // Assuming player extends EObject in this context + let currentDepth = eObject.GetFloatValue(SWIM_DEPTH_INDEX); + if(currentDepth >= CRITICAL_DEPTH) { + triggerDeepDiveEvent(player); + } +} + +// Function to handle what happens when the critical depth is reached +const triggerDeepDiveEvent = (player: Player): void => { + // Custom logic for handling the event, e.g., applying effects, sending notifications, etc. + console.log(`Player ${player.GetName()} has reached a critical depth of ${CRITICAL_DEPTH} units.`); + // You can apply effects like pressure, grant achievements, or unlock secrets here. +} + +// Register the custom event +RegisterPlayerEvent(PLAYER_SWIM_DEPTH_EVENT, (...args) => checkSwimDepth(...args)); +``` +In this example, the `checkSwimDepth` function retrieves the player's current swim depth using the `GetFloatValue` method of the `EObject` (assumed here to be inherited by the `Player` class). When a player reaches or exceeds a critical depth, the `triggerDeepDiveEvent` function is called to manage the scenario, such as applying effects, granting achievements, or revealing underwater secrets. + +This approach allows for a dynamic interaction with players based on their in-game behavior, especially for games or mods that feature detailed environmental interactions. + +## GetGUID +This method retrieves the Global Unique Identifier (GUID) of an object. A GUID is a unique identifier that differentiates each entity in the game world. It is essential to note the GUID's uniqueness may vary depending on the core used by the server. For instance, on MaNGOS and cMaNGOS, creatures and game objects may share the same GUID if they are in different maps, but this is not possible within the same map. Conversely, on TrinityCore, each GUID is unique across all maps, ensuring each entity is distinct regardless of its location. + +### Returns +guid: number - The numerical GUID of the object. + +### Example Usage: +This example demonstrates retrieving the GUID of a creature and logging it. It might be particularly useful for debugging purposes or when you want to perform specific actions based on the unique identifier of entities in the game world. + +```typescript +const OnCreatureInteract: creature_event_on_click = (event: number, creature: Creature, player: Player): void => { + const creatureGuid = creature.GetGUID(); + console.log(`Creature GUID: ${creatureGuid}`); + + // Example conditional action based on GUID + if (creatureGuid === someSpecificGuid) { + // Perform specific actions, like starting a quest or triggering an event + player.StartQuest(QUEST_ID); + } +} + +RegisterCreatureEvent(CREATURE_ID, CreatureEvents.CREATURE_EVENT_ON_CLICK, (...args) => OnCreatureInteract(...args)); +``` +In this sample script, when a player interacts with a specific creature, its GUID is retrieved and logged. Additionally, a conditional check is performed to see if the creature's GUID matches a predefined GUID, `someSpecificGuid`, to perform further custom actions such as starting a quest. This approach allows mod developers to implement functionality that reacts dynamically to interactions with unique entities in the game world. + +## GetGUIDLow + +Returns the low-part of the [Object]'s GUID, which is essential for unique identification across various instances or maps depending on the core used (TrinityCore, MaNGOS, or cMaNGOS). + +### Returns +* **lowGuid**: number - The low part of the GUID for the object. + +### Understanding GUIDs +For TrinityCore servers, each object of the same type has a distinct low GUID. This is particularly important for objects in instances, where new GUIDs are generated with each Map creation. Conversely, MaNGOS and cMaNGOS maintain unique low GUIDs on the same map rather than across all instances. Therefore, identifying an object like a creature in these environments requires knowing both the instance ID and its low GUID. + +### Example Usage: +This script demonstrates how a developer might log the low GUID of an object, which could be a creature or player, to potentially track or reference it later uniquely. + +```typescript +// Registers an event that triggers when a creature or object is interacted with. +RegisterGameObjectEvent(GAME_OBJECT_EVENT_ON_GOSSIP_HELLO, (event: number, player: Player, gameObject: GameObject): void => { + const objectLowGuid = gameObject.GetGUIDLow(); + console.log(`GameObject with low GUID: ${objectLowGuid} interacted by ${player.GetName()}.`); + + // Additional logic here to handle interactions based on the object's low GUID. +}); + +// Another example focusing on creature interaction +RegisterCreatureEvent(CREATURE_EVENT_ON_DAMAGE_TAKEN, (event: number, creature: Creature, attacker: Unit, damage: number): void => { + const creatureLowGuid = creature.GetGUIDLow(); + console.log(`Creature with low GUID: ${creatureLowGuid} took damage from ${attacker.GetTypeName()}. Damage: ${damage}`); + + // This could be useful for tracking damage to specific instances of creatures across different map instances. +}); +``` +In these examples, `gameObject.GetGUIDLow()` and `creature.GetGUIDLow()` are utilized to fetch the low GUIDs of various entities. This demonstrates how to uniquely identify and interact with different objects across server instances, pivotal for developing mods or scripts that depend on object identification in AzerothCore mods using Eluna. + +# GetInt32Value + +Retrieves the data located at the specified index and casts it to a signed 32-bit integer. This can be particularly useful when dealing with game objects or units' statuses, values, or identifiers that are stored as integers. + +### Parameters + +- `index`: number - The index position from which the integer value needs to be retrieved. + +### Returns + +- `value`: number - The data at the specified index, casted to a signed 32-bit integer. + +### Example Usage: + +Imagine a scenario where you need to check if an environmental object (like a chest or a door in a game) is locked or unlocked based on a status value stored in its properties. The status values could be set in a way where `0` represents "unlocked" and any non-zero value represents different locked states. Let's see how `GetInt32Value` can help in determining the lock state: + +```typescript +const LOCK_STATUS_INDEX = 10; // Hypothetical index for lock status +const OBJECT_ID = 12345; // Example object ID for a specific game object + +// Event listener for when a player interacts with an object +const onObjectInteract: game_event_on_object_interaction = (event: number, player: Player, object: EObject): void => { + // Ensure the object is the specific object we're interested in + if(object.GetEntry() == OBJECT_ID) { + const lockStatus = object.GetInt32Value(LOCK_STATUS_INDEX); + + if(lockStatus == 0) { + player.SendMessage("The object is unlocked!"); + } else { + // Handle different locked states, for simplicity we're just informing it's locked + player.SendMessage("The object is locked with status: " + lockStatus.toString()); + } + } +} + +// Register the event listener for object interaction +RegisterGameObjectEvent(OBJECT_ID, GameEvents.GAME_EVENT_ON_OBJECT_INTERACTION, (...args) => onObjectInteract(...args)); +``` + +In this script, we define a listener for when a player interacts with a game object. When the interaction happens with our specific object of interest (identified by `OBJECT_ID`), we use `GetInt32Value` to retrieve the lock status from the object. Depending on the value, we send a message to the player indicating whether the object is locked or unlocked. This utility can be extended to a variety of game scenarios where object properties need to be quickly assessed and acted upon. + +## GetScale +This method is used to retrieve the scale or size of the Object. It is applicable to WorldObjects, which include creatures, game objects, and other entities present in the game world. However, it is important to note that items do not have a "scale" property and therefore, this method will not affect them. + +### Returns +* **scale**: number - The scale/size value of the Object. This is a numerical value representing how large or small an object appears in the game world. + +### Example Usage: +Below is an example script that adjusts the scale of a creature based on certain conditions. If the creature is a dragon, it makes it larger; otherwise, it reduces the size. + +```typescript +// Define constants for creature IDs to check against +const DRAGON_CREATURE_ID = 100; // Example creature ID for a dragon +const DEFAULT_SCALE = 1; // Default scale for most creatures +const DRAGON_SCALE = 3; // Increased scale for dragons + +// Event handler for when a creature spawns. +const onCreatureSpawn: creature_event_on_spawn = (event: number, creature: Creature): void => { + // Check if the creature is a dragon + if (creature.GetEntry() == DRAGON_CREATURE_ID) { + // Increase the scale for dragons + creature.SetScale(DRAGON_SCALE); + } else { + // Set default scale for non-dragon creatures + creature.SetScale(DEFAULT_SCALE); + } +} + +// Register the event handler for the CREATURE_EVENT_ON_SPAWN event +RegisterCreatureEvent(DRAGON_CREATURE_ID, CreatureEvents.CREATURE_EVENT_ON_SPAWN, (...args) => onCreatureSpawn(...args)); +``` +In this script, when a creature spawns, it checks if the creature is a dragon by comparing its entry ID with a predefined constant `DRAGON_CREATURE_ID`. If it matches, it increases the creature's scale using the `SetScale` method with the `DRAGON_SCALE` value. For all other creatures, it resets their scale to the default value using `DEFAULT_SCALE`. This allows for dynamic adjustments of creature sizes based on their type, enhancing the gameplay experience or meeting specific scripting needs. + +## GetTypeId + +This method retrieves the `TypeId` of the Eluna `Object`, which helps in identifying the type of the Eluna `Object` instance in a broader enumeration. Each type in the enumeration corresponds to a different kind of entity in the World of Warcraft game. + +### Returns +`number` - The integer value representing the type id of the object. The possible `TypeID` values are documented as: +- `TYPEID_OBJECT`: 0 +- `TYPEID_ITEM`: 1 +- `TYPEID_CONTAINER`: 2 +- `TYPEID_UNIT`: 3 +- `TYPEID_PLAYER`: 4 +- `TYPEID_GAMEOBJECT`: 5 +- `TYPEID_DYNAMICOBJECT`: 6 +- `TYPEID_CORPSE`: 7 + +### Example Usage: + +Let's set up a scenario in which you would like to print the `TypeId` of various game entities to understand what type of entity you are interacting with. This might be especially useful inside generic handlers or when dealing with an array of different kinds of `Object`. + +```typescript +// Generic handler for when any entity is clicked +const onEntityClicked: entity_event_on_click = (/* event parameters, usually includes the entity */ entity: EObject): void => { + + const typeId = entity.GetTypeId(); + + console.log("Clicked entity TypeID:", typeId); + + // Example of using the typeId to perform specific logic based on the type of entity + switch (typeId) { + case 0: + console.log("This is a base Object."); + break; + case 1: + console.log("This is an Item."); + break; + case 3: + console.log("This is a Unit."); + break; + case 4: + console.log("This is a Player."); + // Perform player-specific logic + break; + default: + console.log("This is a different type of entity."); + } +} + +// Example of registering the event - the actual syntax for registration will depend on the system/framework in use +RegisterEntityEvent(/* appropriate event identifiers */, (...args) => onEntityClicked(...args)); +``` + +### Notes: +- Understanding the `TypeId` of an object is critical for performing type-specific logic in your scripts. +- The `GetTypeId` method allows for efficient type checks and is integral in many systems within mod-eluna scripts. +- Always ensure you compare the `TypeId` with the documented enum values for predictable behavior. + +## GetUInt16Value +Retrieves the data located at the specific index and offset within an EObject, casted to a signed 16-bit integer. This is particularly useful when you need to extract a precise 16-bit piece of data from a larger structure, such as an entity's properties in AzerothCore's database. + +### Parameters +- **index**: number - The index in the EObject where the desired data begins. +- **offset**: number - The offset within the 32-bit block at the specified index to retrieve a 16-bit value. For example, to get the second 16-bit value, you would use an offset of 1. + +### Returns +- **value**: number - The data at the specified index and offset, casted to a signed 16-bit integer. + +### Example Usage +Suppose you have an EObject representing some entity in the game where each index contains a 32-bit block of information. This example demonstrates how to retrieve the second half-word from the 10th index, which could contain important entity attributes like health, mana, or custom server-defined properties. + +```typescript +const exampleObject: EObject = new EObject(); + +// Function to process entity attributes +function processAttributes(eObject: EObject): void { + const INDEX = 10; // Assuming the 10th index holds the entity's attributes in 32-bit format + const OFFSET = 1; // To get the second half-word of the 32-bit block + + let entityAttribute = eObject.GetUInt16Value(INDEX, OFFSET); + + console.log(`Entity Attribute at index ${INDEX} with offset ${OFFSET}:`, entityAttribute); + // Additional logic to utilize the entityAttribute value can be placed here +} + +// Example usage of processAttributes +processAttributes(exampleObject); +``` +In this scenario, by calling `GetUInt16Value(10, 1)`, you're effectively retrieving the second 16-bit segment from a 32-bit block located at index 10 of the `EObject`. This can be incredibly valuable when working with custom scripts or mods in AzerothCore, especially in complex systems where entities have numerous attributes stored in a condensed format. + +## GetUInt32Value + +This method retrieves data from an object based on the specified index and casts it to an unsigned 32-bit integer. This can be especially useful when you need to access specific information about game objects, players, units, etc., where the data is stored in a structured manner, and each index corresponds to different pieces of information. + +### Parameters + +* **index**: number - The index at which the data is stored. Each index corresponds to different data, depending on the object. + +### Returns + +* **value**: number - The data stored at the specified index, casted to an unsigned 32-bit integer. + +### Example Usage: + +In this example, we will use the `GetUInt32Value` method to retrieve a player's level, assuming the level is stored at index 1 (Note: The actual index might differ; this is just for demonstration purposes). + +```typescript +const PlayerLevelIndex = 1; // Hypothetical index where player's level is stored + +const GetPlayerLevel: modPlayerEvent = (player: Player): void => { + // Retrieve the player's level using GetUInt32Value + let playerLevel = player.GetUInt32Value(PlayerLevelIndex); + + console.log(`Player Level: ${playerLevel}`); + // Additional logic based on player level can be added here +} + +// Register the event for when player information needs to be displayed or checked +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => GetPlayerLevel(...args)); +``` + +This script snippet demonstrates how to retrieve and log the player's level on login. It showcases the practical use of the `GetUInt32Value` method in accessing specific data associated with an object within the AzerothCore framework and the mod-eluna scripting engine. + +## GetUInt64Value + +Retrieves stored data at the given index and returns it as an unsigned 64-bit integer. This method is particularly useful when interacting with game entities where properties are identified by their index, providing a way to access various entity attributes efficiently. + +### Parameters +- **index**: number - The index identifying the data to be retrieved. + +### Returns +- **value**: number - The data at the specified index, cast to an unsigned 64-bit integer. + +### Example Usage: +Scenario: Increasing a player's gold based on an item's sell price by retrieving its value from the database index. + +Let's assume we have an item with the database index for its sell price. Using `GetUInt64Value`, we can fetch the sell price directly and then adjust the player's gold accordingly. + +```typescript +const ITEM_SELL_PRICE_INDEX = 9; // Hypothetical index for item sell price +const GOLD_ADDED_PER_ITEM_SELL_PRICE = 100; // Hypothetical conversion rate + +const AdjustPlayerGoldBasedOnItem: player_event_on_loot_item = (event: number, player: Player, item: Item) => { + // Obtain the item's sell price + const itemSellPrice = item.GetUInt64Value(ITEM_SELL_PRICE_INDEX); + + // Convert item sell price to additional gold for the player + const additionalGold = itemSellPrice * GOLD_ADDED_PER_ITEM_SELL_PRICE; + + // Assuming a method exists to add gold to player + player.ModifyGold(additionalGold); + + console.log(`Added ${additionalGold} gold to player based on item's sell price.`); +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => AdjustPlayerGoldBasedOnItem(...args)); +``` +In this example, whenever a player loots an item, the `AdjustPlayerGoldBasedOnItem` function retrieves the item's sell price using `GetUInt64Value` with the specified index. It then calculates the additional gold to be added to the player's total based on a hypothetical conversion rate and adds it to the player's gold. This showcases how `GetUInt64Value` can be used in gameplay scripting to enhance player experience by dynamically adjusting game parameters based on item attributes. + +Based on the provided examples, here is the markdown documentation for the `HasFlag` method of the `EObject` class. + +## HasFlag +This method checks if the specified flag is set on the object. It can be used to verify various states or conditions of game entities facilitated by flags. + +### Parameters +* `index`: number - The index where the flag is stored. This could be tied to specific characteristics or states. +* `flag`: number - The specific flag to check for within the given index. + +### Returns +boolean - Returns `true` if the flag is set, otherwise `false`. + +### Example Usage: +In this example, we will check if a creature has a specific flag that enables a certain behavior or feature. Assuming `CREATURE_FLAG_UNK1 = 1` represents a hypothetical flag. + +```typescript +const CREATURE_FLAG_UNK1 = 1; + +const onCreatureSpawn: creature_event_on_spawn = (event: number, creature: Creature): void => { + // Assuming `0` is an index where certain creature flags are stored + if (creature.HasFlag(0, CREATURE_FLAG_UNK1)) { + console.log("Creature has the special flag set!"); + // Additional logic can be implemented here, knowing the flag is set + } else { + console.log("Creature does not have the special flag set."); + } +} + +RegisterCreatureEvent(YOUR_CREATURE_ENTRY, CreatureEvents.CREATURE_EVENT_ON_SPAWN, (...args) => onCreatureSpawn(...args)); +``` + +In this scenario, upon the spawning of the creature, it checks for a flag at index `0`. This logic enables developers to execute specific code based on whether the condition (the flag being set) is met. This functionality is critical for dynamic game behavior and conditions that depend on various states of game entities. + +It is important to note that the `index` and `flag` values are highly dependent on the implementation details of the game's engine and scripts. Therefore, the selection of these values must align with the documented or known flag storage strategy within the game architecture. + +# IsInWorld +Checks whether the [Object] is currently in the world map. + +This method is critical for ensuring that operations are only performed on objects that are actively part of the game world, such as players, items, or creatures. Performing actions on objects not in the world can lead to unexpected behavior or errors. + +### Returns +- `boolean` - `true` if the [Object] is in the world, otherwise `false`. + +### Example Usage: +The following script demonstrates how to use the `IsInWorld` method to check if a player is in the world before attempting to add an item to their inventory. This ensures that the operation only proceeds if the player is actively part of the game world. + +```typescript +// Define the item entry for a reward item +const REWARD_ITEM_ENTRY = 19019; // Thunderfury, Blessed Blade of the Windseeker + +/** + * Rewards a player with a specific item if they are in the world. + * @param player - The player to reward the item to. + */ +function rewardPlayerItem(player: Player) { + if (player.IsInWorld()) { + // Attempt to add the item to the player's inventory + const addedItem = player.AddItem(REWARD_ITEM_ENTRY, 1); + if (addedItem) { + console.log(`Successfully added reward item to ${player.GetName()}'s inventory.`); + } else { + console.error(`Failed to add reward item to ${player.GetName()}'s inventory. Inventory may be full.`); + } + } else { + console.error(`${player.GetName()} is not in the world. Cannot proceed with giving the reward item.`); + } +} + +// Example usage: register a player event where upon login, the player receives a reward item (if in the world) +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (playerId: number, player: Player) => { + rewardPlayerItem(player); +}); +``` + +This example demonstrates a practical use of the `IsInWorld` method to add a level of safety and error handling to scripts. When developing mods for AzerothCore using mod-eluna, proper checks like this ensure a smoother and more stable gameplay experience. + + +## RemoveFlag +This method is used to manipulate the flags of an object by removing a specified flag from the value at the given index. Flags are generally used to toggle or indicate the presence of various states or capabilities. By removing a flag, you effectively change the properties or behavior associated with the object. + +### Parameters +* `index`: number - The index at which the flag value is located. This parameter signifies the specific property or state you want to alter. +* `flag`: number - The numerical value of the flag you want to remove. Flags are often defined as enums or constants in code for better readability. + +### Example Usage +Consider an object that represents a character status, and you have flags to toggle states like `IsInvisible`, `CanFly`, or `IsInvulnerable`. Below is a simplified example of how `RemoveFlag` might be used to make a character visible again by removing the `IsInvisible` flag. + +```typescript +// Assume these are pre-defined constants for the sake of this example. +const StatusIndexes = { + Abilities: 0, // Index for abilities-related flags +}; + +const AbilityFlags = { + IsInvisible: 1 << 0, // For simplicity, assume this is 1 + CanFly: 1 << 1, + IsInvulnerable: 1 << 2, +}; + +class Character extends EObject { + // Example method to make the character visible. + makeVisible() { + this.RemoveFlag(StatusIndexes.Abilities, AbilityFlags.IsInvisible); + } +} + +const myCharacter = new Character(); +// Initially, the character might be invisible due to certain gameplay mechanics. + +// When a specific event occurs, we want to make the character visible again. +myCharacter.makeVisible(); + +// At this point, RemoveFlag would have been used to alter the Abilities flags by removing the IsInvisible part. +``` + +In this example, `RemoveFlag` is used as a method of the `Character` class, which is assumed to extend `EObject`. Depending on the internal implementation of `RemoveFlag`, the method directly manipulates the state indicated by the `index` parameter, ensuring the `flag` specified is cleared, hence toggling the associated state or behavior. + +## SetByteValue +This method is used to modify specific data of an EObject by setting an 8-bit (byte-size) unsigned integer value at a given index and offset. This is particularly useful when dealing with low-level data manipulation tasks such as setting flags, statuses, or properties that are represented as bytes. + +### Parameters +- `index`: number - The index at which the byte value needs to be set. +- `offset`: number - The offset within the given index to target the specific byte. +- `value`: number - The value to set, which will be converted to an unsigned 8-bit integer. + +### Example Usage: +This example demonstrates how you might use `SetByteValue` to change the status of an EObject, such as toggling a flag that indicates whether an object is active or inactive. +```typescript +// Assuming there's a function to get a specific game object that we want to modify. +const gameObject: EObject = GetSomeGameObject(); + +// Define constants or variables for indexes and offsets for readability +const STATUS_INDEX = 1; // Hypothetical index where status flags are stored +const ACTIVE_OFFSET = 0; // Hypothetical offset for an "active" status flag +const NEW_STATUS_VALUE = 1; // Value to indicate "active" + +// Function to activate an EObject +function activateObject(obj: EObject) { + obj.SetByteValue(STATUS_INDEX, ACTIVE_OFFSET, NEW_STATUS_VALUE); +} + +// Call the function with our gameObject. +activateObject(gameObject); + +// This could be part of a larger script, for example, activating a game object +// when a player enters a certain zone or completes a quest. +``` +In the above script, `STATUS_INDEX` and `ACTIVE_OFFSET` are used to target the specific byte within the game object's data structure that represents its "active" status. `NEW_STATUS_VALUE` is used to set this byte to 1, indicating that the object should now be considered active. This simplistic approach shows how you might encapsulate this functionality within a function for reuse throughout your scripts or mod. + +## SetFlag + +Sets a specific flag in the entity's data value located at the provided index. The operation ensures the flag remains set even if it was previously in place. This method is typically used to mark an entity with certain properties or states without altering other flags already set in the data value. To revert or remove a flag, refer to the complementary method `RemoveFlag`. + +### Parameters +- `index`: number - The index in the data array where the flag is to be set. This index corresponds to a specific property or state of the entity. +- `value`: number - The flag value to be set. This is usually represented by a specific bit within the data value that, when set to 1, indicates the flag's presence. + +### Example Usage: + +Adding a fictional "Invincibility" flag to an entity, assuming the flag is represented by the value 2 (or, in binary, `10`) and is stored at index 0 of the entity's data array. + +```typescript +const ENTITY_INVINCIBILITY_FLAG = 2; // Assuming the invincibility flag value is 2 +const DATA_INDEX = 0; // Assuming the relevant data for flags is stored at index 0 + +const onEntitySpawn: entity_event_on_spawn = (event: number, spawnedEntity: EObject) => { + // Set the invincibility flag for the spawned entity + spawnedEntity.SetFlag(DATA_INDEX, ENTITY_INVINCIBILITY_FLAG); + + // Additional logic upon entity spawn can be placed here +} + +// Assume this function registers an event for when an entity spawns in the game world +RegisterEntityEvent(EntityEvents.ENTITY_EVENT_ON_SPAWN, (...args) => onEntitySpawn(...args)); +``` + +In the above example, `SetFlag` is invoked for an entity upon its spawn, applying the "Invincibility" flag based on predefined index and flag values. This showcases how to modify entity states dynamically through game events using `SetFlag`. Proper understanding of the underlying data structure and flag representation is crucial for effective use of this method. + +## SetFloatValue +This method sets a floating point value on an `EObject` at the specified index. This is particularly useful for manipulating game object properties that expect a floating point number. The value is converted into a single-precision floating point before it's set, ensuring compatibility with the game's data handling. + +### Parameters +* **index:** `number` - The index at which the value is to be set. This typically corresponds to specific properties or attributes of the object. +* **value:** `number` - The value to set, which will be converted to a floating-point number. + +### Example Usage: +The following script demonstrates adjusting the scale of a game object dynamically. In this example, when a player interacts with a game object, its scale is increased by a factor of 1.5, making the object appear larger in the game world. + +```typescript +const SCALE_INDEX = 3; // Assume 3 is the index where the object's scale is stored. +const SCALE_FACTOR = 1.5; + +const onGameObjectUse: gameobject_event_on_use = (event: number, player: Player, gameObject: GameObject): void => { + + // Get the current scale of the game object. + const currentScale = gameObject.GetFloatValue(SCALE_INDEX); + + // Calculate the new scale + const newScale = currentScale * SCALE_FACTOR; + + // Set the new scale back on the game object + gameObject.SetFloatValue(SCALE_INDEX, newScale); + + player.SendBroadcastMessage(`Adjusted the scale of ${gameObject.GetName()} to ${newScale}.`); +} + +// Register the event handler for game object interaction +RegisterGameObjectEvent(YOUR_GAMEOBJECT_ENTRY, GameObjectEvents.GO_EVENT_ON_USE, (...args) => onGameObjectUse(...args)); +``` + +This script could be tailored to various use-cases, such as dynamically adjusting the size of game objects based on specific triggers or conditions, among other potential modifications to game objects. Understanding the indices for different object properties is crucial for effectively using this method. + +## SetInt16Value + +The `SetInt16Value` method is used to store a value converted to a signed 16-bit integer (short) in the data for the `EObject`. This method takes an index to identify the data slot, an offset within that slot, and the value to be stored. This can be particularly useful for manipulating low-level data for custom gameplay mechanics or features. + +### Parameters +- `index`: number - The index of the data slot. This identifies where in the object's data array the 16-bit integer will be stored. +- `offset`: number - The offset within the specified index where the 16-bit integer value starts. This allows for more precise data manipulation within a single index. +- `value`: number - The value to be converted to a 16-bit integer and stored. This value is then assigned at the specified index and offset. + +### Example Usage: +The script ensures that when a special item is used, a custom value is stored in the player's data. This value could later influence gameplay features or unlock custom abilities. The example assumes there are predefined constants for index and offset for simplicity. + +```typescript +const EOBJECT_DATA_INDEX = 10; +const EOBJECT_DATA_OFFSET = 2; + +const SPECIAL_ITEM_USAGE: player_event_on_use_item = (event: number, player: Player, item: Item) => { + const SPECIAL_ITEM_ENTRY = 12345; + + if(item.GetEntry() == SPECIAL_ITEM_ENTRY) { + // Assuming '123' is a significant value in our custom mod logic. + player.SetInt16Value(EOBJECT_DATA_INDEX, EOBJECT_DATA_OFFSET, 123); + + // Notify the player that a special power has been unlocked or modified. + player.SendBroadcastMessage("A mysterious force imbues you with newfound abilities."); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_USE_ITEM, (...args) => SPECIAL_ITEM_USAGE(...args)); +``` +In this usage scenario, when a player uses the item with the entry ID `12345`, a value of `123` is stored in their object data at the specified index and offset. The stored value could be used by other scripts or game mechanics to alter the player's gameplay experience, such as activating special abilities or affecting status effects based on custom conditions defined within your mod for AzerothCore. + +# SetInt32Value +Sets the data for an `EObject` at the specified index to a given value. The value is converted to and stored as a signed 32-bit integer. This is often used in manipulating game object states, character attributes, or any scripted behavior that involves numeric data changes at a granular level. + +### Parameters + +- **index**: number - The index at which the data will be set. This corresponds to specific object properties or attributes and is integral to correctly applying the value to the intended aspect of the `EObject`. + +- **value**: number - The value to be set at the specified index. This value is converted to a signed 32-bit integer before being applied. + +### Example Usage: + +The following script demonstrates adjusting a player's health by directly manipulating game object data. In a more practical scenario, this method might be used within complex scripts where direct control over object states is necessary, such as custom event triggers or unique game mechanics. + +```typescript +// Assume 'player' is an existing instance of a Player, which is an extension of EObject. +const HEALTH_INDEX = 2; // Theoretical index for health in the data array. +const EXTRA_HEALTH = 500; // Additional health to grant the player. + +/** + * This function adds extra health to a player. + * It retrieves the current health value, adds the extra health, + * and then sets the new health value. + * @param player The player to adjust health for. + */ +function AddExtraHealth(player: Player): void { + let currentHealth = player.GetInt32Value(HEALTH_INDEX); // Assuming GetInt32Value is a method to get current int32 values. + let newHealth = currentHealth + EXTRA_HEALTH; + player.SetInt32Value(HEALTH_INDEX, newHealth); + + console.log(`Added ${EXTRA_HEALTH} health to player. New health: ${newHealth}`); +} + +// Event listener for a custom event when a player consumes a specific health potion. +RegisterPlayerEvent(PlayerEvents.CUSTOM_EVENT_PLAYER_CONSUME_HEALTH_POTION, (player: Player) => { + AddExtraHealth(player); +}); +``` + +This example demonstrates a scenario where a player consumes a particular health potion, triggering a custom event that grants them additional health. The `SetInt32Value` method is used to apply the health bonus directly to the player's health attribute, showcasing the method's utility in directly manipulating object data within game scripts. + +## SetScale +Sets the scale/size of the [Object] to a specified value. This can be used to adjust the visual size of an in-game object without altering its inherent properties or behaviors. + +### Parameters +* `scale`: number - The new scale value to set for the object. Values greater than 1 increase the size of the object, values less than 1 decrease the size, and a value of 1 sets the object to its default size. + +### Example Usage: +This script can be used to dynamically adjust the size of an object when a player interacts with it, creating an effect where the object grows or shrinks based on certain conditions. + +```typescript +// Define a custom event handler for when a player interacts with an object +const onObjectInteraction: player_event_on_gameobject_use = (player: Player, object: GameObject): void => { + if(object.GetGUID() == YOUR_SPECIFIC_OBJECT_GUID) { + // Scale up the object size by 50% upon interaction + object.SetScale(1.5); + // Optionally, notify the player + player.SendBroadcastMessage("You have magically altered the size of the object!"); + } +} + +// Register the custom event handler +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_GAMEOBJECT_USE, (...args) => onObjectInteraction(...args)); +``` + +In this example, `YOUR_SPECIFIC_OBJECT_GUID` should be replaced with the GUID (Globally Unique Identifier) of the object you wish to apply the scale change to. The `SendBroadcastMessage` method is used to send a feedback message to the player, indicating that their interaction has caused the object to change size. + +This example demonstrates how to integrate dynamic object interactions within the game world, enhancing player experience by making the environment responsive to their actions. + +## SetUInt16Value +Sets the data for the object at the specified index and offset to the given value, converting the value to an unsigned 16-bit integer. This method is crucial when you need to manipulate complex data structures or update specific parts of an object's state efficiently. + +### Parameters
+* `index`: number - The index in the object's data store where the value should be set. Different indices may correspond to different attributes or properties of the object. +* `offset`: number - The offset within the specified index at which the value should be set. This allows for more granular control over the data being manipulated. +* `value`: number - The new value to set. This value is converted to an unsigned 16-bit integer before being stored. + +### Example Usage: +Below is an example script that demonstrates how to use `SetUInt16Value` to update a player's health status displayed as part of a custom UI feature. This method directly manipulates the underlying data structures for immediate effect, bypassing the usual API functions. Use with caution. + +```typescript +// Assuming EObject is an extensible object class supporting direct data manipulation. +// A hypothetical scenario where we need to update a health display offset in a custom UI component for a player's health bar. + +class CustomPlayerUI { + private static readonly HEALTH_DISPLAY_INDEX: number = 1; // Hypothetical index for health display + private static readonly HEALTH_OFFSET: number = 0; // Offset for the health in a larger 16-bit integer block + + /** + * Updates the health display for the custom UI element of a player. + * @param player The player object whose health display needs updating. + * @param newHealth The new health value to display. Note: Values are capped at the unsigned 16-bit integer max value. + */ + static updateHealthDisplay(player: EObject, newHealth: number): void { + // Cap the health value to the max value of an unsigned 16-bit integer + const healthValue = Math.min(65535, newHealth); + + // Update the player's UI health display by setting the new health value at the appropriate index and offset + player.SetUInt16Value(CustomPlayerUI.HEALTH_DISPLAY_INDEX, CustomPlayerUI.HEALTH_OFFSET, healthValue); + + console.log(`Updated player's health display to ${healthValue}.`); + } +} + +// Example usage: +// player is an instance of EObject representing the player +// Let's assume we want to set the player's health display to 30000 +CustomPlayerUI.updateHealthDisplay(player, 30000); +``` + +This method is especially useful in scenarios where the game's default UI components or data presentation layers are being extended or modified. Careful consideration and testing are recommended to ensure the game's stability and data integrity. + +## SetUInt32Value +This method is used to modify the data of the EObject by setting a value at a specified index, converting the provided value to an unsigned 32-bit integer. Useful for altering characteristics of game entities that are represented by this object. + +### Parameters +* `index`: number - The index at which the value should be set. Refer to the entity's documentation for details on what each index controls. +* `value`: number - The value to set at the specified index, which will be converted to an unsigned 32-bit integer. + +### Example Usage: +In a scenario where you might want to adjust a player's health dynamically through an event, you could use the `SetUInt32Value` method as part of the event handling. Below is an illustrative example where we set the health of a player entity when they complete a specific task or action within the game. + +Let's assume the health index for our player entity is `0` (this is an illustrative index; in practice, you will need to refer to the documentation or entity definition to find the correct index for health). + +```typescript +const HEALTH_INDEX = 0; // Assuming 0 is the index for health +const NEW_HEALTH_VALUE = 10000; // Set a new health value + +const onPlayerCompleteTask: player_event_on_complete_task = (player: EObject) => { + + // Checks if the player is in a condition that warrants health modification + if (playerNeedsHealthAdjustment(player)) { + // Sets the player's health to a new value + player.SetUInt32Value(HEALTH_INDEX, NEW_HEALTH_VALUE); + sendMessageToPlayer(player, `Your health has been set to ${NEW_HEALTH_VALUE}!`); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_COMPLETE_TASK, (...args) => onPlayerCompleteTask(...args)); + +function playerNeedsHealthAdjustment(player: EObject): boolean { + // Include logic to determine if the player's health needs to be adjusted + // This could be based on the player's current health, achievements, or other conditions + // For simplicity, this example returns true + return true; +} + +function sendMessageToPlayer(player: EObject, message: string): void { + // Implement a function to send a message to the player + // This could be through the game's chat system, a UI popup, or another method + // This function is a placeholder to illustrate where you might notify the player of the health change +} +``` + +In this example: +- `onPlayerCompleteTask` defines an event that is triggered when a player completes a specific task. +- It checks if the player meets a condition where their health should be adjusted using `playerNeedsHealthAdjustment`. +- The player's health is then set to `NEW_HEALTH_VALUE` using `SetUInt32Value`. +- Optionally, you can notify the player of this change using a custom message function, `sendMessageToPlayer`, depending on your game's mechanism for player communication. + +# SetUInt64Value + +This method is used to set the data at a specified index to a given value, with the value being converted into an unsigned 64-bit integer. This operation is fundamental in controlling and managing the state of objects within the game, particularly for custom modifications that need to programmatically adjust object properties. + +### Parameters + +- **index**: `number` - The index at which to set the value. This typically corresponds to a specific property or attribute within an EObject. +- **value**: `number` - The value to set at the given index. This value is converted to an unsigned 64-bit integer before being applied. + +### Example Usage: + +In the following scenario, we have a custom mod that rewards players with a unique artifact that has its power level represented as an unsigned 64-bit integer. This script listens for a specific player event, checks if the player has the artifact, and then uses `SetUInt64Value` to enhance its power level. + +```typescript +// An example event where a player completes a challenging dungeon +const onDungeonComplete: dungeon_event_on_complete = (eventId: number, player: Player, dungeonId: number): void => { + // Assuming 100001 is the artifact's unique entry ID + const ARTIFACT_ENTRY_ID = 100001; + // The artifact's power level index + const POWER_LEVEL_INDEX = 10; + // The amount of power to add to the artifact + const POWER_BOOST = 1000; + + // Check if a player has the artifact in their inventory + let artifact = player.GetItemById(ARTIFACT_ENTRY_ID); + if (artifact) { + // Get the artifact's current power level + let currentPower = artifact.GetUInt64Value(POWER_LEVEL_INDEX); + // Set the artifact's new power level + artifact.SetUInt64Value(POWER_LEVEL_INDEX, currentPower + POWER_BOOST); + + player.SendBroadcastMessage("Your artifact has grown more powerful!"); + } +} + +RegisterDungeonEvent(DungeonEvents.DUNGEON_EVENT_ON_COMPLETE, (...args) => onDungeonComplete(...args)); +``` +In this script: +- We define `onDungeonComplete`, a function that reacts to the completion of a dungeon. +- We check if the player possesses a specific artifact by its entry ID. +- We retrieve the artifact's current power level using a theoretical `GetUInt64Value` method (for the sake of this example). +- We then increase the artifact's power level by a predetermined amount using `SetUInt64Value`. +- Finally, we provide feedback to the player by sending them a broadcast message. + +This example illustrates how to use `SetUInt64Value` to manipulate game object properties dynamically, allowing for a broad range of custom behaviors and enhancements in mod development for Azerothcore with mod-eluna. + +## ToCorpse +Attempt to convert the current Object to a Corpse type. This method is particularly useful when you need to perform actions or retrieve information specific to a Corpse object. If the object is not of type Corpse, it returns `nil`. + +### Returns +corpse: [Corpse](./corpse.md) - The Corpse object if the conversion was successful, `nil` otherwise. + +### Example Usage: +This script aims to demonstrate how to check if a killed entity's corpse can be interacted with for quest or mechanic purposes within certain events or conditions. It checks if the entity is a corpse and then prints a message to the system log. + +```typescript +// A sample event where an entity dies and you want to check if it's a corpse +const onEntityDeath: entity_event_on_death = (event: number, entity: EObject, killer: Unit): void => { + + let corpse = entity.ToCorpse(); // Attempt to convert the entity to a Corpse + + if (corpse) { + console.log("Entity is a corpse. Proceed with quest or mechanic interactions."); + // Additional logic can be implemented here, such as checking if the corpse meets certain quest conditions + } + else { + console.log("Entity is not a corpse. No further action taken."); + } +} + +// Registering the custom event for demonstration purposes +RegisterEntityEvent(MyCustomEntityIDs.MY_ENTITY_ID, EntityEvents.ENTITY_EVENT_ON_DEATH, (...args) => onEntityDeath(...args)); +``` +This example is intended for situations where specific actions need to be taken with entities that can leave corpses (for example, checking if a player has killed a particular NPC for a quest). It succinctly checks if an entity is a corpse upon death and logs the outcome, which can be expanded with further logic as needed. + +## ToCreature + +This method attempts to convert a general [Object] into a more specific [Creature] object type. This can be particularly useful in situations where you have an object reference and you need to ensure it is a creature to perform creature-specific operations. If the conversion is not possible (i.e., the object is not actually a creature), the method will return `nil`, indicating the conversion failure. + +### Returns +* `Creature` or `nil` - Returns a [Creature](./creature.md) if the [Object] is indeed a [Creature]. If not, `nil` is returned. + +### Example Usage: +The following script illustrates a scenario where an object might be a creature. It first checks if the conversion is possible by calling `ToCreature()`. If successful (i.e., not `nil`), it proceeds to call a [Creature]-specific method on the newly converted creature object. + +```typescript +// The 'objectFound' variable simulates obtaining an object from the game world. +// The exact method of obtaining this object will depend on your specific scenario (e.g., collision, proximity event). +let objectFound: EObject = getObject(); + +const onObjectInteract: generic_event_handler = (): void => { + let creature = objectFound.ToCreature(); + + if (creature != null) { + // Successfully converted to Creature; you can now call Creature-specific methods. + creature.DoSomethingSpecificToCreatures(); + console.log("Object was a creature and has been handled accordingly."); + } else { + console.log("The object is not a creature."); + } +} + +// Register an event or callback that triggers 'onObjectInteract'. +// For the sake of this example, the triggering mechanism is left generic. +registerSomeEventOrCallback(...args => onObjectInteract(...args)); +``` + +This example highlights a generic use case and should be adjusted to fit the specific circumstances in which you need to check and convert objects to creatures within the AzerothCore modding framework. + +## ToGameObject + +Attempts to convert the [Object] into a [GameObject]. This is particularly useful when the type of the [Object] is uncertain and you want to manipulate it as a [GameObject]. If the conversion is not possible (i.e., the [Object] is not a [GameObject]), the method will return `nil`, indicating that the operation failed. + +### Returns +* GameObject or `nil`: The method returns the converted [GameObject] if the [Object] is indeed a [GameObject]. If the conversion is not possible, it returns `nil`. + +### Example Usage: + +The following script demonstrates how to safely attempt to convert an [Object] to a [GameObject] and then perform operations on the [GameObject] if the conversion was successful. The script checks if a unit's target is a GameObject and, if so, prints the GameObject's entry ID. + +```typescript +const OnSpellCast: player_event_on_cast_spell = (event: number, player: Player, spell: Spell, skipCheck: boolean, target: Object): void => { + // Attempt to convert the target to a GameObject + const gameObject = target.ToGameObject(); + + if (gameObject) { + // Successfully converted to GameObject + print(`Target GameObject Entry ID: ${gameObject.GetEntry()}`); + } else { + // Conversion failed + print("Target is not a GameObject."); + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_CAST_SPELL, (...args) => OnSpellCast(...args)); +``` + +In this example, `OnSpellCast` is a callback for the PLAYER_EVENT_ON_CAST_SPELL event. When a spell is cast, the script checks if the target of the spell is a GameObject by attempting to convert the target object. It then either prints the GameObject's entry ID if the conversion was successful or indicates that the target is not a GameObject. + +This approach ensures type safety and allows for GameObject-specific operations to be performed only on objects that are indeed GameObjects, avoiding runtime errors and simplifying complex type-checking logic. + +## ToPlayer + +Attempts to convert the [Object] to a [Player]. If the [Object] is not a [Player], it returns `nil`. This method can be very useful when you're not sure if an object is a player, especially when scripting events where both [Player]s and other [Unit]s might be involved. + +### Returns +- `nil` if the [Object] cannot be converted into a [Player] +- `[Player]` instance if the conversion is successful + +### Example Usage +The following example demonstrates how to safely check if an object is a player and then perform some player-specific operations if the conversion is successful. + +Imagine we have a script that is meant to grant a blessing buff to players when they interact with a certain NPC. We'll first check if the interacting entity is a `Player` and then grant them a buff. + +```typescript +// Define a handler for when an entity interacts with our special NPC +const OnEntityInteractSpecialNPC: entity_event_on_player_interaction = (event: number, entity: EObject, specialNPCId: number): void => { + + // Check if the entity is indeed a player + const player = entity.ToPlayer(); + + // If not a player, do nothing + if(!player) { + return; + } + + // Specific NPC Id we want to check interaction with + const SPECIAL_NPC_ID = 12345; // Example NPC Id + + // Check if the interaction is with our special NPC + if(specialNPCId == SPECIAL_NPC_ID) { + + // If so, grant the player a blessing buff + const BLESSING_BUFF_ID = 43210; // Example Buff Id + + // Applying the blessing buff to the player + player.AddAura(BLESSING_BUFF_ID, player); + + // Log or announce the blessing for the player + console.log(`Blessing granted to ${player.GetName()}.`); + } +} + +// Register our handler for the Entity Interaction event +RegisterEntityEvent(EntityEvents.ENTITY_EVENT_ON_INTERACTION, (...args) => OnEntityInteractSpecialNPC(...args)); +``` + +This script checks if the entity interacting with a specific NPC is a player and, if so, grants them a special "blessing" buff. This demonstrates how the `ToPlayer()` method can be integral in ensuring that scripts dealing with entities handle them appropriately based on their type. + +## ToUnit + +Attempts to convert the [EObject](./eobject.md) instance to a [Unit](./unit.md) instance. If the [EObject](./eobject.md) is not actually a [Unit](./unit.md) (for example, if it's an [Item](./item.md) or a [GameObject](./gameobject.md)), the method returns `nil`, indicating the conversion cannot be made. Useful for scripts where entity type checking is necessary before performing operations specific to [Unit](./unit.md) entities. + +### Returns +unit: [Unit](./unit.md) or `nil` - The converted [Unit](./unit.md) if the [EObject](./eobject.md) is a [Unit](./unit.md), otherwise `nil`. + +### Example Usage: +In a script that enhances a player's companion NPC upon entering a specific zone, ensuring the companion is indeed a [Unit](./unit.md) before applying changes. + +```typescript +const ZONE_ID_FOR_EVENT = 400; // Example zone ID + +// Event handler when a player enters a new zone +const onPlayerEnterZone: player_event_on_enter_zone = (event: number, player: Player, newZone: number): void => { + if (newZone === ZONE_ID_FOR_EVENT) { + // Assuming GetCompanion returns an EObject which could be a Unit or something else + let companion: EObject = player.GetCompanion(); + let companionUnit: Unit = companion.ToUnit(); + + if (companionUnit != null) { + // Perform operations on the companion Unit + companionUnit.SetMaxHealth(2000); // Example: setting max health of the companion + console.log("Companion's max health has been set to 2000."); + } else { + console.log("Player's companion is not a Unit. Cannot enhance."); + } + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_ENTER_ZONE, (...args) => onPlayerEnterZone(...args)); +``` + +This code snippet demonstrates the use of `ToUnit` method to safely convert a player's companion from an [EObject](./eobject.md) to a [Unit](./unit.md) before attempting to adjust the companion's health. It ensures script integrity by checking the object type, thereby preventing potential errors that would arise from attempting to execute [Unit](./unit.md)-specific operations on a non-[Unit](./unit.md) object. + +## UpdateUInt32Value +Sets the data for the entity at a specified index to the given value, converting it to an unsigned 32-bit integer. This method is typically used to modify the state or properties of game objects or entities in a controlled manner. + +### Parameters
+* `index`: number - The index at which to update the data. This usually corresponds to specific attributes or properties of the entity. +* `value`: number - The new value to be set at the specified index. This value is converted to an unsigned 32-bit integer. + +### Example Usage: +In this example, we are updating a player's health attribute. In a game context, this might be used within a custom healing spell or effect. + +```typescript +const UPDATE_HEALTH_INDEX = 25; // Hypothetical index for health attribute +const HEAL_AMOUNT = 100; + +/** + * Custom function to heal a player using UpdateUInt32Value method. + * This is a simplified example; actual game mechanics can be more complex. + * + * @param player - The player entity to heal. + */ +function healPlayer(player: EObject): void { + // Retrieve current health, for demonstration purposes let's assume a GetHealth method exists + let currentHealth = player.GetHealth(); + + // Calculate new health value + let newHealth = currentHealth + HEAL_AMOUNT; + + // Update player's health attribute to the new value + player.UpdateUInt32Value(UPDATE_HEALTH_INDEX, newHealth); + + console.log(`Player healed! New health: ${newHealth}`); +} + +// Example usage within an event listener or a similar context +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_DAMAGE_TAKEN, (player: EObject) => { + // Call healPlayer within an appropriate context, e.g., after taking damage + healPlayer(player); +}); +``` + +In this example, a hypothetical `healPlayer` function is defined, which utilizes the `UpdateUInt32Value` method to increase a player's health by a predetermined amount. This function can be invoked in various game scenarios, such as after a player takes damage, to simulate a healing effect. Note that index constants and methods like `GetHealth` are context-dependent and might vary based on the game's data structure. + diff --git a/docs/classes/Item.md b/docs/classes/Item.md new file mode 100644 index 0000000..7c5c04f --- /dev/null +++ b/docs/classes/Item.md @@ -0,0 +1,1741 @@ +## CanBeTraded +Determines if the [Item] can be traded to other players. This can be helpful in scripts that need to confirm item tradability, for instance, in loot distribution systems or trade verification processes. + +### Returns +boolean - Returns `true` if the [Item] can be traded, `false` otherwise. + +### Example Usage +Implementing a system that ensures a specific valuable item can only be looted and then traded to players within a certain level range, to prevent abuse or exploitation of game mechanics. This script checks if the item can be traded before proceeding with the loot distribution logic. + +```typescript +const VALUABLE_ITEM_ENTRY = 12345; // Example item entry ID +const MIN_LEVEL = 20; // Minimum player level to trade the item +const MAX_LEVEL = 40; // Maximum player level to trade the item + +const OnLootItem: player_event_on_loot_item = (event: number, player: Player, item: Item): void => { + if (item.GetEntry() === VALUABLE_ITEM_ENTRY && item.CanBeTraded()) { + const playerLevel = player.GetLevel(); + + if (playerLevel >= MIN_LEVEL && playerLevel <= MAX_LEVEL) { + // Logic to trade the item to the player + console.log(`Item ${VALUABLE_ITEM_ENTRY} can be traded to ${player.GetName()}.`); + } else { + console.log(`Player ${player.GetName()} does not meet the level requirements to trade item ${VALUABLE_ITEM_ENTRY}.`); + } + } else { + console.log(`Item ${VALUABLE_ITEM_ENTRY} cannot be traded.`); + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => OnLootItem(...args)); +``` +In this script, after a player loots an item, it checks if the item is the specific valuable item and whether it can be traded. If both conditions are true, it further checks if the player's level is within the specified range. Based on these conditions, it either logs a message indicating that the item can be traded to the player, or it logs a message stating that the player does not meet the requirements to trade the item, or that the item itself cannot be traded. + +## ClearEnchantment +This method removes an enchantment from an item at a specified slot. This functionality is particularly useful for customizing items, managing gear sets, or modifying items during debugging or special events. + +### Parameters + +- **enchantSlot**: number - The slot number where the enchantment to be removed is located. + +### Returns + +- **success**: boolean - Returns `true` if the enchantment was successfully removed from the item. Returns `false` if the operation failed (e.g., no enchantment in the specified slot). + +### Example Usage: + +In this example, a script is used to remove enchantments from a player’s weapon during a custom event. The enchantment slot numbers typically range from 0 to 4, with 0 usually representing the primary enchantment. + +```typescript +const CUSTOM_EVENT_ID: number = 123; // Example custom event ID +const WEAPON_ENCHANT_SLOT: number = 0; // Primary enchantment slot + +// Event handler for custom item modification event +const onCustomEvent: custom_event_on_item_modify = (event: number, player: Player, item: Item): void => { + if (event === CUSTOM_EVENT_ID) { + // Assuming the item is a weapon and the player wants to clear the primary enchantment + const success = item.ClearEnchantment(WEAPON_ENCHANT_SLOT); + if (success) { + player.SendBroadcastMessage("Enchantment successfully removed!"); + } else { + player.SendBroadcastMessage("Failed to remove enchantment. Ensure the slot is correct."); + } + } +}; + +// Registering the custom event with the appropriate handler function +RegisterPlayerEvent(PlayerEvents.CUSTOM_EVENT_ID, (...args) => onCustomEvent(...args)); + +``` + +This script listens for a custom event, `CUSTOM_EVENT_ID`, which triggers the `onCustomEvent` function. When the event occurs for an item (in this scenario, presumed to be a weapon), the script attempts to clear the enchantment in the primary slot. The success or failure of this operation is communicated to the player via a broadcast message. + +This example illustrates how to interact with an item's enchantments dynamically, offering customization or adaptation based on gameplay scenarios, helping maintain balance, or providing players with unique experiences during server events. + +## GetAllowableClass +Returns a bitmask representing the player classes that are allowed to use the item. Classes not represented by the bitmask will be unable to use the item. Player class codes are defined in the game's core code and database, typically following a pattern where each class is represented by a power of 2 (e.g., Warrior = 1, Paladin = 2, Hunter = 4, etc.). + +### Returns +- **classMask**: `number` - A bitmask representing the allowable classes for this item. + +### Example Usage: +This script enables a custom item reward behavior where the item can only be rewarded if it's usable by the player's class. This enhances gameplay by ensuring players receive rewards tailored to their class. + +```typescript +const CUSTOM_ITEM_ENTRY = 12345; // Example item entry ID + +// Player event for item rewards based on class. +const RewardItemIfClassAllowed: player_event_on_level_up = (event: number, player: Player) => { + let item = CreateItem(CUSTOM_ITEM_ENTRY, player); // Assume CreateItem instantiates an Item object. + + let allowableClassMask = item.GetAllowableClass(); + let playerClassMask = 1 << (player.GetClass() - 1); // Convert player's class into a bitmask. + + // Check if the player's class is allowed to use the item. + if ((allowableClassMask & playerClassMask) !== 0) { + player.AddItem(CUSTOM_ITEM_ENTRY, 1); // Reward item. + player.SendBroadcastMessage("Congratulations! You've received a class-specific item reward."); + } else { + player.SendBroadcastMessage("This item is not suitable for your class."); + } +} + +// Register the event to trigger on player level up. +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LEVEL_UP, (...args) => RewardItemIfClassAllowed(...args)); +``` + +In this example, `GetAllowableClass` is used to determine whether an item is suitable for the player based on their class. It makes use of bitwise operations to check if the player's class is included in the allowable classes for the item. This script could be particularly useful in custom quests, events, or loot systems where class-specific rewards are a feature. + +## GetAllowableRace +This method returns a bitmask representing the races that are allowed to use the given item. Each bit in the bitmask corresponds to a race as defined in the game. The method is especially useful for scripts or mods that need to enforce item restrictions based on player race. + +### Returns +`number` - A bitmask representing the races allowed to use the item. Each bit in the bitmask corresponds to a specific race. For example, if the bitmask is `3`, it means the first two races in the game's race enumeration can use this item. + +### Example Usage: +The following script example demonstrates how to use the `GetAllowableRace` method to check whether a human (race id 1 in the game's enumeration) can use the item or not. It involves bitwise operations to check if the specific bit related to humans is set in the bitmask returned by `GetAllowableRace`. + +```typescript +const HUMAN_RACE_BITMASK = 1 << (1 - 1); // Humans are typically race id 1 in AzerothCore's enumeration, shifting 1 by 0 places. + +const CanHumanUseItem = (item: Item): boolean => { + const allowableRaces = item.GetAllowableRace(); + return (allowableRaces & HUMAN_RACE_BITMASK) !== 0; +} + +const CheckItemForHuman: player_event_on_loot_item = (event: number, player: Player, item: Item): void => { + if (player.GetRace() === 1) { // Assuming 1 is the ID for humans + if (!CanHumanUseItem(item)) { + player.SendNotification("You cannot use this item due to your race."); + } + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => CheckItemForHuman(...args)); +``` + +In this script: +- We define `HUMAN_RACE_BITMASK` to correspond to the bitmask value of Humans in the game. We assume 1 as the ID for humans in AzerothCore's enumeration of races, and we use bitwise left shift to set the first bit in our bitmask. +- The `CanHumanUseItem` function uses bitwise AND (`&`) to compare the item's allowable races with the `HUMAN_RACE_BITMASK`. If the result is non-zero, it means the bit for humans is set, and thus humans can use the item. +- In the `CheckItemForHuman` event handler function, we check if the looting player is a human (`player.GetRace() === 1`). If true, we then check if the human can use the looted item by calling `CanHumanUseItem`. If not, we send a notification to the player. + +This script is a simple demonstration of how to use the `GetAllowableRace` method to enforce race-based item usage restrictions. Such checks could be essential for custom quests, items, or server rulesets to ensure that certain items remain exclusive to specific races. + +# GetBagSize + +Returns the bag size of a specified [Item] if it is a bag; otherwise, it returns 0. This method is useful when determining if an item can hold other items, which is essential for inventory management scripts or mods that interact with the player's carrying capacity. + +### Returns +* **size**: number - The size of the bag (i.e., how many slots it has). Returns 0 if the item is not a bag. + +### Example Usage: + +In this example, we'll create a script that checks whether a newly acquired item is a bag. If the item is a bag, it logs the bag size to help with inventory management strategies, such as allocating items to bags with sufficient space or identifying which bags to replace for upgrades. + +```typescript +const OnLootItem: player_event_on_loot_item = (event: number, player: Player, item: Item): void => { + const bagSize = item.GetBagSize(); + + // Check if the item is a bag by seeing if the bag size is greater than 0 + if(bagSize > 0) { + console.log(`Looted a bag with ${bagSize} slots.`); + // Additional logic to handle the bag, like checking for bag upgrades. + } else { + console.log("Looted an item that's not a bag."); + } +} + +// Register the event to trigger the above script when a player loots an item. +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => OnLootItem(...args)); +``` +In this script, we're utilizing the `GetBagSize` method to check the item's capability as a container. This method aids significantly in inventory management scripts, where understanding an item's function as a storage unit is vital. It promotes a more interactive and dynamic approach to handling looted or acquired items, enhancing the gaming experience in mods built for AzerothCore using mod-eluna. + +# GetBagSlot +This method retrieves the current bag slot number where the [Item] is located. This can be useful for inventory management scripts or functions that require to know in which slot a particular item is positioned within a player's inventory. + +### Returns +- `number` - The bag slot number of the item. If the item is not in a bag, returns -1. + +### Example Usage: +This script snippet demonstrates how to check the bag slot of a specific item and print a message with the slot number. If the item is not found in any bag slot, it prints a message stating the item is not placed in any bag. + +```typescript +const ITEM_ENTRY = 12345; // Example item entry ID + +const PrintItemBagSlot: player_event_on_login = (event: number, player: Player) => { + // Assume the player has the item in their inventory + const items = player.GetInventoryItems(ITEM_ENTRY); + + if (items.length > 0) { + const item = items[0]; // Get the first item of the specified entry + const bagSlot = item.GetBagSlot(); + + if (bagSlot !== -1) { + player.SendBroadcastMessage(`Your item is located in bag slot ${bagSlot}.`); + } else { + player.SendBroadcastMessage("Your item is not placed in any bag."); + } + } else { + player.SendBroadcastMessage("You do not have the specified item in your inventory."); + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => PrintItemBagSlot(...args)); +``` +In this example, `GetInventoryItems` is a hypothetical function that retrieves a list of items by their entry ID from the player's inventory (this function is not defined in the provided class definitions, so replace it with the correct method to get items by entry ID if needed). The `SendBroadcastMessage` method sends a message visible to the player, informing them of the item's bag slot or if the item isn't located in any bag. + +## GetBuyCount +This method returns the default purchase count of the specified item. This is particularly useful when trying to understand the quantity of an item that is bought by default from a vendor in-game. For items that can be purchased from NPCs, this could be used to programmatically verify or utilize the base purchase quantity in scripts or modifications. + +### Returns +count: number - The default number of items purchased in a single transaction from a vendor. + +### Example Usage: +Let's consider an example where a custom vendor sells exclusive items, and we want to ensure players receive the correct quantity for special items, based on their default buy count. This can be utilized in a function that handles player interactions with this custom vendor. + +```typescript +const CUSTOM_ITEM_ENTRY = 12345; // Example Item Entry ID + +const onPlayerVendorShow: player_event_on_vendor_show = (player: Player, vendor: Creature) => { + // Assuming `GetVendorItems` is a hypothetical method returning item entries vendor sells + const itemsForSale = vendor.GetVendorItems(); + + // Check if our custom item is part of this vendor's items + const hasCustomItem = itemsForSale.some(item => item.entry === CUSTOM_ITEM_ENTRY); + + if(hasCustomItem) { + const customItem = new Item(CUSTOM_ITEM_ENTRY); // Assuming `Item` can be instantiated for the sake of example + const buyCount = customItem.GetBuyCount(); + + // Notify player about the item and its default buy count + player.SendBroadcastMessage(`Special Offer! Get ${buyCount} units of a unique item from this vendor.`); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_VENDOR_SHOW, (...args) => onPlayerVendorShow(...args)); +``` +In this example, when a player interacts with a vendor, it checks if the vendor sells a specific custom item. If the item is available, it retrieves the item's default buy count by using the `GetBuyCount` method. Then, it notifies the player about the special offer including how many units of the item they would receive, enhancing the player's in-game shopping experience. This application can be particularly useful in custom scripts for modified servers where vendors offer unique items or rates. + +## GetBuyPrice +This method returns the purchase price of the specified item. The purchase price is the amount of in-game currency (e.g., gold, silver, copper) that a player must pay to acquire the item from an NPC vendor. + +### Returns +- `number`: The purchase price of the item in copper units. Note: In AzerothCore, prices are usually represented in copper units, where 100 copper = 1 silver and 10,000 copper = 1 gold. + +### Example Usage: +This script allows you to adjust the pricing of items for players based on certain conditions (like being in a guild, having a reputation, or during special events). The idea is to offer discounts or increase prices dynamically. + +```typescript +const SPECIAL_GUILD_ID = 1234; // Example guild ID +const DISCOUNT_PERCENTAGE = 10; // 10% Discount + +const onItemPurchase: player_event_on_vendor_buy = (event: number, player: Player, item: Item, itemCount: number, vendor: Creature) => { + let originalPrice = item.GetBuyPrice(); + let finalPrice = originalPrice; + + // Check if the player is in the special guild + if (player.GetGuildId() === SPECIAL_GUILD_ID) { + let discount = (originalPrice * DISCOUNT_PERCENTAGE) / 100; + finalPrice -= discount; + player.SendBroadcastMessage(`Congratulations! You have received a ${DISCOUNT_PERCENTAGE}% discount on your purchase.`); + } + + // Further logic can be implemented to adjust `finalPrice` based on other conditions + + // Assuming there's a method to adjust the final price (this is a hypothetical example) + player.AdjustFinalPrice(item, finalPrice); + + // Note: This is a conceptual example. AzerothCore's actual methods and event triggers might differ. + // Ensure to check the documentation or source code for precise implementation details. +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_VENDOR_BUY, (...args) => onItemPurchase(...args)); +``` +This script checks if the player is part of a specific guild and applies a discount to the purchase price of an item. It takes into consideration the original purchase price obtained via `GetBuyPrice()`, calculates a discount, and hypothetically adjusts the final purchase price (note that `AdjustFinalPrice` is used as a conceptual method in this example). The player is notified about the discount through a broadcast message. Remember, this example assumes the existence of certain methods and behaviors for illustrative purposes, and actual implementation may require adapting to the available API in AzerothCore and mod-eluna. + +Based on your request, here is the documentation for the `GetClass` method in the `Item` class: + +## GetClass +Retrieves the class categorization of the item. Item classes are defined within the game and represent broad categories like weapons, armor, consumables, etc. This can be especially useful for scripts that need to handle items differently based on their type. + +### Returns +classId: number - The numerical identifier for the item's class. This corresponds to values defined in the game's item class enumeration which can be referenced via the core documentation or database definitions. + +### Example Usage: +In this example, we're defining a script that awards players with additional points in a custom leveling system anytime they loot an item of the 'weapon' class. The points awarded could be used in a custom vendor or upgrade system. + +```typescript +const WEAPON_CLASS_ID = 2; // Assuming '2' represents the 'weapon' class in the game's item class enumeration +const POINTS_PER_WEAPON = 10; + +const onItemLooted: player_event_on_loot_item = (event: number, player: Player, item: Item): void => { + // Check if the looted item is of the 'weapon' class + if (item.GetClass() == WEAPON_CLASS_ID) { + // Award points to the player for looting a weapon + awardPoints(player, POINTS_PER_WEAPON); + player.SendBroadcastMessage(`Congratulations! You've earned ${POINTS_PER_WEAPON} points for looting a weapon.`); + } +} + +/** + * Awards points to a player in a custom leveling or reward system. + * + * @param player - The player to award points to. + * @param points - The number of points to award. + */ +function awardPoints(player: Player, points: number): void { + // Implementation for awarding points could involve updating a database or in-memory store. + console.log(`Awarding ${points} points to player with GUID: ${player.GetGUID()}.`); +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => onItemLooted(...args)); +``` + +This documentation and example provide an actionable and clear method for utilizing the `GetClass` function of an `Item` within the AzerothCore framework and its mod-eluna scripting engine. + +## GetCount +Returns the current stack count of the Item. This is particularly useful for managing inventory, batch processing of items, and conditions that depend on the quantity of a specific item in the player's possession. + +### Returns +count: number - The stack count of the item. + +### Example Usage: +A simple script to check if the player has at least a certain number of a specific item and take action based on the result. In this example, we verify if the player has at least 10 units of an item with entry ID 12345. If so, an action is triggered - for instance, granting a reward, messaging, or starting an event. + +```typescript +const ITEM_ENTRY_ID = 12345; +const REQUIRED_COUNT = 10; + +const CheckPlayerItem: player_event_on_login = (event: number, player: Player): void => { + const items = player.GetInventoryItemsByEntry(ITEM_ENTRY_ID); + let totalCount = 0; + + for (let item of items) { + totalCount += item.GetCount(); + } + + if(totalCount >= REQUIRED_COUNT) { + // Player has the required number of items + // Trigger your action here. For example: + player.SendBroadcastMessage("Congratulations! You have enough items."); + // Consider adding more actions, such as rewarding the player. + } else { + player.SendBroadcastMessage("You don't have enough items. You need " + (REQUIRED_COUNT - totalCount) + " more."); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => CheckPlayerItem(...args)); +``` + +The `GetInventoryItemsByEntry` method isn't directly mentioned in the provided class definition but is used here for demonstration purposes, assuming an implementation that retrieves all items of a specified entry from the player's inventory. This code exemplifies a practical use scenario for the `GetCount` method, showcasing its utility in scripts that involve inventory management or conditional actions based on item quantities. + +## GetDisplayId +Retrieves the display ID of the item. This can be particularly useful for custom scripts that alter the appearance of items dynamically, or for logging and debugging purposes to ensure the correct items are being manipulated based on their display IDs. + +### Returns +displayId: number - The unique display ID of the item. + +### Example Usage: +This script demonstrates how to log the display ID of an item when a player loots it. This can be helpful for tracking item usage or for debugging purposes in custom loot distribution systems. + +```typescript +const OnItemLoot: player_event_on_loot_item = (event: number, player: Player, item: Item): void => { + const itemDisplayId = item.GetDisplayId(); + console.log(`Player ${player.GetName()} looted an item with Display ID: ${itemDisplayId}`); +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => OnItemLoot(...args)); +``` + +In this example, every time a player loots an item, the item's display ID is logged to the console. This could be extended to check for specific display IDs to trigger custom effects, grant achievements, or alter item behavior dynamically. + +## GetEnchantmentId +Retrieve the enchantment ID associated with a specific slot on the item. Each item can have multiple enchantment slots, where various enchantments with unique IDs can be applied. This function helps identify the specific enchantment applied to a designated slot. + +### Parameters +* enchantSlot: number - The specific slot number on the item from which you wish to retrieve the enchantment ID. Different slots represent different types of enchantments that can be applied to an item. + +### Returns +* enchantmentId: number - The ID of the enchantment present in the specified slot or `-1` if no enchantment is found in the given slot. + +### Example Usage: +The script below is designed to check if the weapon a player is currently equipped with has a specific enchantment (`Lifestealing Enchantment`, for instance, with an imaginary enchantment ID of `1234`). If the enchantment is found in one of the weapon slots, a special effect is applied to the player. + +```typescript +const LIFESTEALING_ENCHANTMENT_ID = 1234; +const WEAPON_SLOT_MAIN_HAND = 15; // Assuming slot `15` is the main hand weapon slot +const WEAPON_SLOT_OFF_HAND = 16; // Assuming slot `16` is the off-hand weapon slot + +const onPlayerEquip: player_event_on_equip_item = (event: number, player: Player, item: Item, bagSlot: number, slot: number) => { + + // Check both the main hand and off-hand weapon slots for the enchantment + if(slot === WEAPON_SLOT_MAIN_HAND || slot === WEAPON_SLOT_OFF_HAND) { + + // Assuming '0' is the slot representing a primary enchantment on the weapon + // This part might need to be adjusted as per the server's enchanting slot conventions + const enchantmentId = item.GetEnchantmentId(0); + + if(enchantmentId === LIFESTEALING_ENCHANTMENT_ID) { + // Apply a special effect because the weapon has the Lifestealing enchantment + console.log(`Player ${player.GetName()} equipped a weapon with Lifestealing in slot ${slot}. Applying special effect.`); + // Here, you could call another function or method to apply the specific effect to the player + } else { + console.log(`Player ${player.GetName()} equipped a weapon without Lifestealing in slot ${slot}.`); + } + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_EQUIP_ITEM, (...args) => onPlayerEquip(...args)); +``` + +This script could be enhanced to check for multiple enchantments, handle different slots more dynamically, or manage various special effects based on the enchantment found. It's an example of how to utilize `GetEnchantmentId` to trigger gameplay mechanics based on item enchantments. + +## GetInventoryType + +Returns the inventory type (slot category) of the item. This is useful for determining where an item can be worn or how it can be used. For a more detailed understanding of inventory types, refer to the `InventoryType` definitions in the World of Warcraft API documentation. + +### Returns +- **type**: number - The inventory type identifier of the item. For example, `1` for head, `2` for neck, etc. + +### Example Usage +This example script will print the inventory type of a player's currently equipped head item. It demonstrates how to retrieve an item from a specific slot and then use the `GetInventoryType` method to identify its inventory type. This is particularly useful for customizing player gear checks or enhancing UI elements. + +```typescript +const PLAYER_SLOT_HEAD: number = 1; // Slot ID for head items + +const OnInspectPlayerHead: player_event_on_login = (event: number, player: Player): void => { + const headItem: Item = player.GetItemBySlot(PLAYER_SLOT_HEAD); + if(headItem) { + const inventoryType: number = headItem.GetInventoryType(); + player.SendBroadcastMessage(`Your head item's inventory type is: ${inventoryType}`); + } else { + player.SendBroadcastMessage("You have no item equipped in the head slot."); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => OnInspectPlayerHead(...args)); +``` + +The above script should be attached to a player login event listener, where upon each login, it checks the player's head slot for an item. If an item is found, it retrieves and reports the inventory type of that item back to the player through a broadcast message. This example may be adapted to check different item slots or to perform actions based on the type of items a player is wearing or carrying. + +## GetItemLevel +Returns the level of the item. This can be useful for scripts that need to check the level of items players are carrying or using, ultimately allowing for more complex interactions based on item level, such as custom rewards or restrictions based on gear level. + +### Returns +level: number - The level of the item. + +### Example Usage: +A script that provides players with a special reward if they're wielding an item of a certain level or higher. This can be particularly useful for custom events or challenges. + +```typescript +const MIN_ITEM_LEVEL_FOR_REWARD = 200; + +const RewardPlayerWithHighLevelGear: player_event_on_equip_item = (event: number, player: Player, item: Item, bagSlot: number) => { + + // Only check the main hand weapon (slot 15) for this example + if(bagSlot === 15) { + let itemLevel = item.GetItemLevel(); + + if (itemLevel >= MIN_ITEM_LEVEL_FOR_REWARD) { + // Award the player for having a high-level item equipped + // This could be a rare item, a title, etc. Depends on your server setup + player.AddItem(YOUR_REWARD_ITEM_ENTRY, 1); + player.SendBroadcastMessage("Congratulations! Your high-level gear has earned you a special reward!"); + } + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_EQUIP_ITEM, (...args) => RewardPlayerWithHighLevelGear(...args)); +``` + +In this example, we're focusing on rewarding players who equip a main hand weapon of a certain item level or higher. The event `PLAYER_EVENT_ON_EQUIP_ITEM` triggers our custom function, which checks if the equipped item in the main hand (bag slot 15) meets the minimum item level requirement for a reward. + +Modify the `MIN_ITEM_LEVEL_FOR_REWARD` and `YOUR_REWARD_ITEM_ENTRY` to fit your server's conditions and rewards. This script encourages players to seek out higher level items for potential rewards, adding an extra layer of engagement with the game's loot system. + +## GetItemLink +Generates and returns the chat link of the item in the specified or default locale. This chat link can be used in player chat messages to show details about the item directly in the chat window. Useful for sharing item details with other players or for scripting UI elements that require item information. + +### Parameters +* locale?: `LocaleConstant` (optional) - The locale constant to determine the language of the item link. Defaults to `LOCALE_enUS` if not specified. + +### Returns +* link: `string` - The generated chat link for the item that can be used in player messages. + +### Locale Constants +The method supports the following locale constants for generating the item link in different languages: +```typescript +enum LocaleConstant { + LOCALE_enUS = 0, // English (United States) + LOCALE_koKR = 1, // Korean (Korea) + LOCALE_frFR = 2, // French (France) + LOCALE_deDE = 3, // German (Germany) + LOCALE_zhCN = 4, // Chinese (China) + LOCALE_zhTW = 5, // Chinese (Taiwan) + LOCALE_esES = 6, // Spanish (Spain) + LOCALE_esMX = 7, // Spanish (Mexico) + LOCALE_ruRU = 8 // Russian (Russia) +}; +``` + +### Example Usage: +To share an item link in a global chat or to embed item information within a custom UI element, use the `GetItemLink` method. Below is an example scenario where a player finds a rare item, and a script shares this achievement in the global chat with the item link. + +```typescript +// Assuming we have a predefined function to react to an item being looted +const OnItemLooted: player_event_on_loot_item = (event: number, player: Player, item: Item) => { + // Getting the item link in the default English language + const itemLink = item.GetItemLink(LocaleConstant.LOCALE_enUS); + + // Constructing a message to share in global chat + const message = `${player.GetName()} has found a rare item: ${itemLink}!`; + + // Send the message to the global chat (pseudo-function, replace with actual API call) + SendGlobalMessage(message); +} + +// Register the event with the PlayerEvents enum (pseudo-code for registering the event handler) +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => OnItemLooted(...args)); +``` +In this script, whenever a player loots an item, the `OnItemLooted` function is triggered. It retrieves the item's chat link in English and constructs a celebratory message that includes the item link. This message is then shared in a global chat channel, allowing other players to see the item's details directly in the chat by clicking on the link. + +# GetItemSet + +Retrieves the item set ID of the given item. Useful for scripting specific behaviors based on item sets, such as granting bonuses when a player equips multiple items from the same set. The item set IDs can be referenced in the World Database `item_set` table. For more information about item sets and their bonuses, you can find more details here: [AzerothCore item sets](https://www.azerothcore.org/wiki/item_set). + +### Returns +`setId`: number - The ID of the item set to which the [Item](./item.md) belongs. If the item is not part of a set, the method returns 0. + +### Example Usage: +Grant a special buff to the player if they complete an item set. In this example, a player receives a powerful buff if they equip all items from a fictional item set with the ID of `123`. + +```typescript +const ITEM_SET_ID = 123; +const BUFF_ID = 54321; // Fictional buff ID for demonstration + +const onItemEquipped: player_event_on_equip_item = (event: number, player: Player, item: Item, bag: number, slot: number): void => { + // Checking if the equipped item contributes to the target item set + if(item.GetItemSet() == ITEM_SET_ID) { + // Check for player's equipped items to see if all items of the set are equipped + let setItemCount = 0; + const EQUIPPED_ITEMS = player.GetEquippedItems(); + for (let equippedItem of EQUIPPED_ITEMS) { + if (equippedItem.GetItemSet() == ITEM_SET_ID) { + setItemCount++; + } + } + // Assuming the set consists of 4 items - apply buff if all items are equipped + if(setItemCount == 4) { + player.AddAura(BUFF_ID, player); // Apply the buff + player.SendBroadcastMessage("You have equipped all items of the set. Special powers have been granted!"); + } + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_EQUIP_ITEM, (...args) => onItemEquipped(...args)); +``` +In this example, when a player equips an item, the `onItemEquipped` event handler checks if the item is part of the specified item set. If so, the script counts how many items of the set the player has equipped. If all items of the set are equipped, it grants the player a special buff and sends a message to the player about their newly acquired powers. + +## GetMaxStackCount + +Returns the maximum number of times an item can stack within a single inventory slot. This might be particularly useful when scripting inventory-related checks or when trying to add items to a player's inventory programmatically. + +### Returns + +- **maxStackCount**: number - The maximum number of times the item can stack in the inventory. + +### Example Usage: + +In this example, a custom function is utilized to prevent the automatic addition of items to a player's inventory when the potential new stack would exceed the item's maximum stack count. It checks the player's current amount of the item, determines if adding more would exceed the max stack, and if so, splits the addition into multiple inventory slots if available. + +```typescript +function addItemSafely(player: Player, itemEntry: number, amountToAdd: number): void { + const existingStack = player.GetItemByEntry(itemEntry); + const maxStack = existingStack.GetMaxStackCount(); + let currentCount = existingStack ? existingStack.GetCount() : 0; + const spaceNeeded = Math.ceil((currentCount + amountToAdd) / maxStack); + + if (player.GetItemCount(itemEntry) + amountToAdd > maxStack * spaceNeeded) { + console.log("Not enough space in inventory to add item without exceeding max stack size."); + return; + } + + while (amountToAdd > 0) { + if (currentCount + amountToAdd > maxStack) { + player.AddItem(itemEntry, maxStack - currentCount); + amountToAdd -= (maxStack - currentCount); + currentCount = 0; // Reset for next potential stack. + } else { + player.AddItem(itemEntry, amountToAdd); + break; + } + } +} +``` + +This script ensures that when items are added to a player's inventory, they adhere to the maximum stack count specified for each item, reducing the risk of inadvertently overflowing an inventory slot and potentially losing items due to stack limits. + +Remember, actual behavior might slightly vary depending on the specifics of your AzerothCore server's configuration and the version of mod-eluna you're utilizing. Always test scripts in a controlled environment before deploying them on a live server. + +## GetName +Retrieve the name of the item. This method can be especially useful when creating scripts that involve item transactions or logging item-related activities. + +### Returns +name: string - The name of the item as defined in the World Database `item_template` table. + +### Example Usage: +This example demonstrates how to announce the name of a looted item to the whole server. Such a feature might be utilized for broadcasting the loot of rare items, enhancing the community experience. + +```typescript +const AnnounceLoot: player_event_on_loot_item = (event: number, player: Player, item: Item) => { + + const itemName = item.GetName(); + const announcement = `${player.GetName()} has looted: ${itemName}!`; + + // This fictional function represents a way to announce messages server-wide. + // The implementation details can vary. + AnnounceToServer(announcement); + +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => AnnounceLoot(...args)); +``` +In this example, when a player loots an item, the `AnnounceLoot` function is called. Inside this function, we extract the name of the item using `item.GetName()`. We then construct an announcement string that includes the name of the player (retrieved by a hypothetical `player.GetName()` function for demonstrative purposes) and the name of the item. Finally, we pass this announcement string to a fictional `AnnounceToServer` function, which we are assuming broadcasts the message to all players on the server. This example demonstrates an engaging way to utilize the `GetName` method of the `Item` class to enhance player interaction and engagement on the server. + +## GetOwner +Retrieves the [Player](./player.md) instance who currently owns the item in question. This method is handy for identifying which player possesses a specific item, particularly useful in scenarios where item ownership needs to be verified or actions need to be taken based on the owner. + +### Returns +Returns the [Player](./player.md) instance who owns the item. This can be used to interact with the player, such as sending notifications, granting additional items or experience, or any other player-specific interactions. + +### Example Usage: +Script for rewarding the player with additional experience points upon identifying the owner of a rare item. + +```typescript +const RARE_ITEM_ENTRY = 12345; // Placeholder for a rare item entry ID +const XP_BONUS_FOR_RARE_ITEM = 1000; // Experience points to grant + +const onItemLooted: player_event_on_loot_item = (event: number, player: Player, item: Item) => { + + // Ensure the looted item matches the rare item entry ID + if(item.GetEntry() == RARE_ITEM_ENTRY) { + const itemOwner = item.GetOwner(); // Retrieves the owner of the item + + // Provide additional XP to the owner as a reward + if (itemOwner) { + itemOwner.GiveXP(XP_BONUS_FOR_RARE_ITEM); + itemOwner.SendBroadcastMessage(`Congratulations! You've been awarded an additional ${XP_BONUS_FOR_RARE_ITEM} experience points for looting a rare item.`); + } + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => onItemLooted(...args)); +``` + +This example script demonstrates a scenario where a player loots a rare item, and upon doing so, the script checks the item's ownership. If the player is indeed the owner of the rare item, they are granted additional experience points as a reward. This use of the `GetOwner` method enables a direct and efficient way to enhance player engagement and reward systems based on item interactions. + +## GetOwnerGUID +Retrieves the Globally Unique Identifier (GUID) of the owner of the item. + +### Returns +No return value (`void`). This implies a potential use case of this method would involve additional steps to retrieve or work with the owner's GUID after it has been obtained. + +### Example Usage: + +Let's say we want to check if an item's owner is part of a specific Guild, and if so, apply a special effect to them. To do this, we first need to obtain the item owner's GUID using `GetOwnerGUID()`. Note that this example adds hypothetical methods for obtaining a player by their GUID and checking their guild membership for illustrative purposes. + +```typescript +// Hypothetical method to get a player object by GUID +function GetPlayerByGUID(guid: string): Player | null { + // Implementation to retrieve player by GUID +} + +// Hypothetical method to check if a player is in a given guild by name +function IsPlayerInGuild(player: Player, guildName: string): boolean { + // Implementation to check guild membership +} + +const CheckItemOwnerGuild: player_event_on_loot_item = (event: number, player: Player, item: Item): void => { + // First obtain the item owner's GUID + const ownerGUID = item.GetOwnerGUID(); + + // Then, get the player object using the owner's GUID + const itemOwner = GetPlayerByGUID(ownerGUID); + + if (itemOwner) { + // Check if the item's owner is part of the "Elite Raiders" guild + if (IsPlayerInGuild(itemOwner, "Elite Raiders")) { + // If so, apply a special effect (hypothetical method) + ApplySpecialEffectToPlayer(itemOwner); + } else { + // Handle case where the owner is not part of the specified guild + console.log("Item's owner is not part of 'Elite Raiders' guild."); + } + } else { + // Handle case where owner could not be found + console.log("Item's owner could not be found."); + } +} + +// Registering the event to check the guild membership whenever an item is looted +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => CheckItemOwnerGuild(...args)); +``` + +In this example, `GetOwnerGUID()` is used in a more complex logic flow involving player and guild verification. Notice that this showcases how one might use such a method as part of a bigger system, even though the method itself does not return detailed information directly. + +# GetQuality + + Retrieve the quality level of an item. Every item in World of Warcraft has an associated quality level that indicates its rarity and overall value. This method accesses that value directly from an item instance. For more detailed information about item quality and what each level represents, you can explore the [Item Quality](https://wowpedia.fandom.com/wiki/Item_quality) on Wowpedia. + +### Returns +- **quality**: `number` - Numeric value representing the item's quality. These values correspond to the following qualities: + - 0: Poor (Grey) + - 1: Common (White) + - 2: Uncommon (Green) + - 3: Rare (Blue) + - 4: Epic (Purple) + - 5: Legendary (Orange) + - 6: Artifact (Golden Yellow) + - 7: Heirloom (Light Yellow) + +### Example Usage: +Below is an example where we check the quality of a looted item and then execute specific logic based on the item's quality. The script prints a congratulatory message if the player loots an item of epic quality or higher. + +```typescript +const onLootItem: player_event_on_loot_item =(event: number, player: Player, item: Item) => { + const itemQuality = item.GetQuality(); + + // Checks if the looted item is of Epic quality or higher. + if(itemQuality >= 4) { + player.SendBroadcastMessage("Congratulations! You've looted an item of Epic or higher quality!"); + } +} + +// Registering the event that handles item looting +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => onLootItem(...args)); +``` + +In this snippet, the `GetQuality` method is used to retrieve the quality of the item that was just looted. Depending on the quality, it might trigger a congratulatory message for the player, making the moment of acquiring a high-quality item even more special. This example integrates seamlessly with mod-eluna on Azerothcore, allowing for enriched and interactive player experiences based on game events. + + +## GetRandomProperty + +This method retrieves the random property ID assigned to an item. Each item in AzerothCore can have random properties which alter its characteristics. The random property ID corresponds to entries in the `item_random_properties` table of the World Database. + +### Returns +- `number` - The random property ID of the item. + +### Example Usage + +This script example demonstrates how to check the random property of an item a player loots, specifically looking for a certain random property ID. If the item has the desired random property, a special message is logged. + +```typescript +const DESIRED_RANDOM_PROPERTY_ID = 123; // Example random property ID + +const OnLootRandomPropertyItem: player_event_on_loot_item = (event: number, player: Player, item: Item): void => { + let randomPropertyId = item.GetRandomProperty(); + + if (randomPropertyId == DESIRED_RANDOM_PROPERTY_ID) { + console.log(`Player ${player.GetName()} looted an item with the desired random property!`); + // Additional actions could be performed here, such as rewarding the player + } else { + console.log(`The looted item does not have the desired random property. ID: ${randomPropertyId}`); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => OnLootRandomPropertyItem(...args)); +``` + +This script can be developed further depending on the server's needs, such as implementing specific actions when an item with the desired property is found, or tracking which players find items with rare properties. + +## GetRandomSuffix +This method allows you to retrieve a random suffix for an item if applicable. Suffixes in Azerothcore can modify the name and attributes of an item, making it unique or more powerful. Applying a random suffix can be particularly useful in custom scripts where item variability is desired for quest rewards, loot drops, or other player interactions. + +### Parameters +This method does not require any parameters. + +### Returns +This method returns `void`. It is typically used for its side effect rather than its return value. + +### Example Usage: +In the following example, a custom function is created to award a player with a randomized item upon completing a special event. The `GetRandomSuffix` method is used to ensure the item has a random suffix, adding uniqueness and potential value to the reward. + +```typescript +const SPECIAL_ITEM_ENTRY = 12345; // Example item entry ID + +const AwardRandomizedSpecialItem: player_event_on_custom_event = (event: number, player: Player) => { + // Create a new item instance from the item entry + let specialItem = player.AddItem(SPECIAL_ITEM_ENTRY, 1); + + // Apply a random suffix to the item + if(specialItem) { + specialItem.GetRandomSuffix(); + } + + // Notify the player + player.SendBroadcastMessage("Congratulations! You've received a special item with a unique trait."); +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_CUSTOM_EVENT, (...args) => AwardRandomizedSpecialItem(...args)); +``` + +In this example, assuming that `SPECIAL_ITEM_ENTRY` corresponds to an item in the `item_template` table that supports suffixes, this script would grant players a unique version of the item each time the event is triggered. The use of `GetRandomSuffix` ensures each item awarded could have different attributes, enhancing gameplay variety and player interest. + +## GetRequiredLevel +Retrieves the minimum character level required to use the specified item. Ensuring that players meet the necessary level requirements before equipping or using an item is crucial for maintaining game balance and enhancing the gaming experience by setting achievable progression goals. + +### Returns +level: number - The minimum level a player needs to reach to be able to use the item. + +### Example Usage: +Enforce level requirements for special event items to ensure they are used by the intended level bracket. This example checks if players are eligible to use an event reward item and sends a notification if they don't meet the requirement. + +```typescript +const EVENT_REWARD_ITEM_ENTRY = 12345; // Example item entry + +const CheckItemLevelRequirement: player_event_on_loot_item = (event: number, player: Player, item: Item) => { + if (item.GetEntry() == EVENT_REWARD_ITEM_ENTRY) { + const requiredLevel = item.GetRequiredLevel(); + if (player.GetLevel() < requiredLevel) { + player.SendNotification(`You must be at least level ${requiredLevel} to use this item.`); + } else { + player.SendNotification(`Congratulations! You can use your event reward item.`); + } + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => CheckItemLevelRequirement(...args)); +``` + +In this script, when players loot an item with the entry ID of `EVENT_REWARD_ITEM_ENTRY`, the script checks if the player's level is less than the required level to use the item. If the player is not of the required level, they are sent a notification stating the level requirement; otherwise, they are congratulated and informed they can use the item. This enhances the gaming experience by providing clear feedback to players about item usage requirements. + +## GetSellPrice + +Returns the sell price in copper of the [Item]. + +### Returns +price: number - The sell price of the item in copper. + +### Example Usage: + +In this example, a script automatically calculates the total sell price of the player's items and prints it to the console. Useful for inventory management or deciding on loots. + +```typescript +const CalculateTotalSellPrice: player_event_on_loot_item = (event: number, player: Player, item: Item): void => { + let totalSellPrice = 0; + + // Assume getInventoryItems is a function that returns an array of Item objects the player has + const inventoryItems: Item[] = getInventoryItems(player); + + for (let item of inventoryItems) { + totalSellPrice += item.GetSellPrice(); + } + + console.log(`Total sell price of inventory: ${totalSellPrice} copper.`); +} + +// Utility function to simulate fetching player's inventory items +function getInventoryItems(player: Player): Item[] { + // This function is hypothetical and serves as a stand-in for how you might acquire items from a player's inventory. + // In a real scenario, you would use appropriate methods provided by the mod-eluna API to access a player's inventory. + return []; // Returning an empty array for the sake of this example. +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => CalculateTotalSellPrice(...args)); +``` + +In this script, we introduce a hypothetical `getInventoryItems` function that retrieves a list of `Item` objects from the player's inventory. For each item, we calculate the total sell price by summing up the sell prices of individual items. This total sell price is then logged to the console, giving a quick way to assess the potential gold return from selling all inventory items. + +Please note that in a real mod-eluna script, the approach to retrieving a player's inventory items might differ based on the specific methods available within the mod-eluna API for Azerothcore. This example assumes a simplistic approach for illustrative purposes. + +# GetSlot + +Retrieves the current slot index where the item is located in the player's inventory. + +### Returns +slotIndex: number - The index of the slot where the item is found, starting from 0. + +### Example Usage: +This snippet ensures that a specific powerful item, identified by its entry ID, is equipped in the correct slot before allowing the player to enter a high-level dungeon. This demonstrates a practical use of `GetSlot` to verify item placement within a player's inventory. + +```typescript +const POWERFUL_ITEM_ENTRY_ID = 12345; // Example item entry ID for a powerful item +const REQUIRED_SLOT_INDEX = 15; // Slot index for the main hand weapon + +const onPlayerEnterDungeon: player_event_on_map_enter = (player: Player) => { + const inventory = player.GetInventoryItems(); + + let isPowerfulItemEquipped = inventory.some(item => { + return item.GetEntry() === POWERFUL_ITEM_ENTRY_ID && item.GetSlot() === REQUIRED_SLOT_INDEX; + }); + + if (!isPowerfulItemEquipped) { + player.SendNotification("You must equip the Legendary Sword in your main hand to enter this dungeon."); + // Additional code to prevent entry or teleport out + } else { + player.SendNotification("Welcome, warrior. Your equipment is in order."); + // Proceed with dungeon entry + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_MAP_ENTER, (...args) => onPlayerEnterDungeon(...args)); +``` + +In the example above, a player attempting to enter the dungeon will have their inventory scanned for a specific "Legendary Sword" (a placeholder for the actual item entry ID). This check is done using the `GetSlot` method to ensure not only that the player possesses the item but also that it is equipped in the correct slot (main hand weapon slot in this case). If the item is not equipped properly, the player is notified and could be prevented from entering the dungeon. This approach reinforces the importance of not only having certain items but also their proper use and placement for game mechanics or specific events. + +## GetSpellId + +This method retrieves the spell ID associated with the item by a specified spell index. Items in AzerothCore can have spells tied to them, such as on-use effects, procs, or other actions that occur under specific circumstances. The spell index refers to the position of the spell in the item's data structure, starting from 0. + +### Parameters +- **spellIndex**: number - The index of the spell in the item's spell list. + +### Returns +- **spellId**: number - The ID of the spell tied to the item at the specified index. + +### Example Usage: +In this example, we implement a function to cast the spell of a specific item that a player has equipped. This can be particularly useful for custom scripts where you want to trigger item effects under custom conditions. + +```typescript +const ITEM_SPELL_INDEX = 0; // Assuming we're interested in the first spell of the item + +function castItemSpell(player: Player, itemEntry: number): void { + const item: Item = player.GetItemByEntry(itemEntry); + if (!item) { + console.log("The player does not have the specified item."); + return; + } + + const spellId: number = item.GetSpellId(ITEM_SPELL_INDEX); + if (spellId <= 0) { + console.log("No valid spell found for the specified index."); + return; + } + + player.CastSpell(player, spellId, true); +} + +// Usage example: Casting an effect of an item a player might have equipped or in inventory. +// Consider itemEntry to be the entry ID of an item with a usable spell effect. +const ITEM_ENTRY_ID = 12345; // Example item ID (replace with an actual item ID) + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_COMMAND, (type: number, player: Player) => { + castItemSpell(player, ITEM_ENTRY_ID); +}); +``` + +In this implementation, we create a utility function `castItemSpell` that a player can trigger, potentially through a custom command or a specific gameplay event. It looks for an item with the given entry ID in the player's inventory. If the item exists, it retrieves the spell ID associated with the item at the specified index (`ITEM_SPELL_INDEX`) and casts that spell on the player. + +This technique can be adapted for various gameplay mechanics, such as custom quests, events, or enhancing player interactions with items in unique ways. + +## GetSpellTrigger +Retrieve the spell trigger associated with the item based on the specified spell index. +This method helps in understanding the conditions under which a spell tied to an item is triggered. + +### Parameters +* **spellIndex**: number - The index of the spell for which the trigger is to be retrieved. Index usually starts from 0. + +### Returns +* **spellTrigger**: number - The trigger condition of the specified spell. Different numbers correspond to different types of triggers, as defined in your server's core documentation or source code. + +### Example Usage: +Let's create a script to inform a player about the spell trigger condition of a specific item's spell. This is particularly useful when dealing with items that have multiple spell effects or triggers. + +```typescript +const ITEM_ENTRY = 12345; // Example item entry +const SPELL_INDEX = 0; // Typically, the first spell associated with an item is at index 0 + +const onInspectItem: player_event_on_inspect_item = (player: Player, item: Item) => { + if (item.GetEntry() == ITEM_ENTRY) { + const spellTrigger = item.GetSpellTrigger(SPELL_INDEX); + + switch(spellTrigger){ + case 0: + player.SendMessage("This spell is triggered by Use."); + break; + case 1: + player.SendMessage("This spell is triggered on Equip."); + break; + case 2: + player.SendMessage("This spell has a Chance on Hit trigger."); + break; + default: + player.SendMessage("This item's spell trigger is not standard."); + break; + } + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_INSPECT_ITEM, (...args) => onInspectItem(...args)); +``` + +This example script can be expanded or refined according to your needs. It provides a basic framework for utilizing the `GetSpellTrigger` method to interact with players about item functionalities in the World of Azeroth. By adjusting the `ITEM_ENTRY` and `SPELL_INDEX`, you can tailor this script to any item and investigate its spell trigger conditions. Remember to consult your server's core documentation for the exact meanings of different spell trigger numeric codes. + +# GetStatsCount +Retrieve the number of different stats the item has. This can include stats such as Strength, Agility, Stamina, etc., depending on the item's properties in the World Database's `item_template` table. + +### Returns +void - No direct return value since the example provided lacks specific details. + +### Example Usage: +The following example assumes you want to check the stats count of a particular item a player receives, possibly to log or implement custom behavior based on the complexity of the item (indicated by the number of stats it possesses). + +```typescript +const ItemStatsLogger: player_event_on_loot_item = (event: number, player: Player, item: Item): void => { + // Assuming GetStatsCount should return a number rather than void, + // and it's just an example limitation. + // This would log the count of stats an item has when a player loots it. + const statsCount = item.GetStatsCount(); + + console.log(`Item ID ${item.GetEntry()} has ${statsCount} stats.`); + + // Custom behavior could be implemented here, such as: + if (statsCount > 5) { + console.log("This item is complex and highly valuable!"); + // Additional custom behavior can be implemented based on item complexity. + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => ItemStatsLogger(...args)); +``` + +**Note:** In the given TypeScript class definition, `GetStatsCount()` is specified to return `void`, which doesn't align with its presumed functionality of returning a count value (typically a number). In practical documentation or implementation, the method signature should likely return a `number` instead of `void` to reflect its purpose. The example above is adjusted under the assumption that `GetStatsCount()` should indeed return a number, illustrating how it might be utilized in a scenario where the count of an item's stats is relevant. + +## GetSubClass +This method retrieves the subclass of the item. The item subclass represents specific categories within the main item class, providing further distinction. For instance, in weapon items, subclasses define whether an item is a sword, axe, bow, etc. These subclasses are aligned with the `subclass` field within the `item_template` table in the AzerothCore database. More information about subclasses can be explored through the [AzerothCore documentation](https://www.azerothcore.org/wiki/item_template). + +### Returns +- `number`: The subclass ID of the item as defined in the database. + +### Example Usage +In this example, we check the subclass of a weapon looted by a player to apply a specific effect if it's a sword (subclass ID 0). + +First, ensure you have a listener for the player looting an item, then check if the item looted is a weapon. If it is, identify whether its subclass indicates it's a sword. If all conditions are met, apply an effect to the player, such as increasing their experience gain temporarily. + +```typescript +const SWORD_SUBCLASS_ID = 0; // Subclass ID for swords +const EXPERIENCE_BUFF_ID = 48406; // Hypothetical buff ID for increased experience gain + +const onPlayerLootItem: player_event_on_loot_item = (event: number, player: Player, item: Item) => { + // Confirm the item is a weapon by checking its class. For simplicity, let's assume class 2 is Weapons. + if(item.GetClass() === 2) { + // Check if the subclass of the weapon is a sword + if(item.GetSubClass() === SWORD_SUBCLASS_ID) { + // Apply a hypothetical effect/buff to the player for looting a sword + player.AddAura(EXPERIENCE_BUFF_ID, player); + console.log("Sword looted! Experience gain increased temporarily."); + } + } +} + +// Register the event listener for PLAYER_EVENT_ON_LOOT_ITEM +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => onPlayerLootItem(...args)); +``` +This script enhancing gameplay by rewarding players who loot specific item types (in this case, swords) aligns with interesting event-driven mechanics that can be implemented in mods for AzerothCore. + +## HasQuest +Determines if the item is associated with a specific quest. This is helpful when scripting interactions that depend on whether an item is a quest item. + +### Parameters +- **questId:** number - The quest ID to check the item for. + +### Returns +- **boolean:** Returns `true` if the Item has the specified quest tied to it, `false` otherwise. + +### Example Usage: +The following script checks if the looted item is part of a quest that requires collection. If so, it logs a message to the server console. + +```typescript +const onItemLooted: player_event_on_loot_item = (event: number, player: Player, item: Item): void => { + + const QUEST_ID_NEED_FOR_QUEST = 12345; // Example quest ID + if(item.HasQuest(QUEST_ID_NEED_FOR_QUEST)) { + console.log(`Player ${player.GetName()} has looted an item required for their quest.`); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => onItemLooted(...args)); +``` + +In this example, we're enhancing the player's interaction with looted items by providing feedback or altering the game's behavior based on whether the item is associated with an ongoing quest. This can be particularly useful in custom events or scenarios where quest items play a significant role. + +This method simplifies quest-related item handling, especially when working with custom quests or adjusting loot tables dynamically. The provided example showcases a basic application within a loot event, but the potential applications can vary widely depending on the script's context within the game. + +## IsArmorVellum +Determines if the current item is an Armor Vellum. Armor Vellums are special items that enchanters can use to store armor enchantments for later use or sale. + +### Returns +boolean - Returns `true` if the item is an Armor Vellum, `false` otherwise. + +### Example Usage: + +A common usage scenario for this could be to create a function that checks if the player has an Armor Vellum in their inventory, and if so, apply an enchantment to it. + +```typescript +const ARMOR_VELLUM_ENTRY = 38682; // Example entry ID for Armor Vellum, this value should be replaced by the actual entry ID from your database. + +// Function to check if the player has an Armor Vellum in their inventory +function checkAndEnchantArmorVellum(player: Player, enchantmentId: number): void { + const playerItems = player.GetInventoryItems(); // Assuming GetInventoryItems() is a method that retrieves all items in a player's inventory + + for (const item of playerItems) { + if (item.GetEntry() === ARMOR_VELLUM_ENTRY && item.IsArmorVellum()) { + // Logic to apply enchantment to the vellum + console.log(`Enchantment ${enchantmentId} applied to Armor Vellum!`); + return; + } + } + + console.log("No Armor Vellum found in the inventory."); +} + +// This event hook could be placed somewhere in your mod where it makes sense to trigger this check. +// Example: When player obtains a new item or interacts with something specific. +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_RECEIVE_ITEM, (player: Player) => { + const ENCHANTMENT_ID = 54321; // Example enchantment ID, this should be replaced with actual id + checkAndEnchantArmorVellum(player, ENCHANTMENT_ID); +}); +``` + +This script attempts to find an Armor Vellum item in the player's inventory. If found, it "applies" an enchantment specified by `enchantmentId` to the vellum. This example doesn't cover the actual application of an enchantment, as that process depends on external systems and the specifics of mod-eluna and AzerothCore configurations. It's meant to illustrate how the `IsArmorVellum` method can be integrated into a larger gameplay mechanic. + +## IsBag +Checks whether the item is a type of bag or not. + +### Returns +boolean: 'true' if the [Item] is considered a bag, 'false' if it's not a bag. + +### Example Usage: +Before equipping an item or adding it to a special inventory slot, it's useful to verify if the item is a bag. This is crucial for inventory management systems or automatic gear equipping scripts where bags should be handled differently from other types of items. + +```typescript +const PLAYER_EVENT_ON_EQUIP_ITEM: number = 29; // This is a made up event for demonstration, replace with the actual event ID for equipping items. + +const onEquipItem: (player: Player, item: Item) => void = (player, item) => { + if (item.IsBag()) { + console.log("The item trying to be equipped is a bag."); + // Additional logic for handling bag items + // Maybe move it to a bag-specific inventory slot, or alert the player, etc. + } else { + console.log("The item trying to be equipped is not a bag."); + // Proceed with regular item equipping logic + } +}; + +RegisterPlayerEvent(PLAYER_EVENT_ON_EQUIP_ITEM, (...args) => onEquipItem(...args)); +``` + +In this example, when a player attempts to equip an item, it first checks if the item is a bag. Depending on the result, it can execute different logic paths, such as managing inventory slots specific to bags or alerting the player. This approach is beneficial for creating more intuitive and error-free player interactions with their inventory. + +## IsBoundAccountWide +Determines if the given item is bound to the account, meaning it can be accessed by other characters within the same account. Useful for checking the tradability and sharing of items across characters. + +### Returns +boolean - Returns `true` if the item is account bound, `false` otherwise. + +### Example Usage: +This script checks if a recently looted item is account bound. If it is, a message is sent to the player congratulating them. This could be part of a larger function to handle account-wide achievements or rewards. +```typescript +const CheckItemBoundStatus: player_event_on_loot_item = (event: number, player: Player, item: Item): void => { + if (item.IsBoundAccountWide()) { + player.SendAreaTriggerMessage("Congratulations! Your looted item is account bound and can be shared with your other characters."); + } else { + player.SendAreaTriggerMessage("This item is character-specific and cannot be shared with your other characters."); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => CheckItemBoundStatus(...args)); +``` +This example script can be easily integrated into existing systems to provide clear feedback to players about the items they acquire, enhancing their understanding and planning for character development and item management. + +## IsBoundByEnchant +Determines if an item is bound to a player as a result of an enchantment. Binds from enchantments are typically a result of certain enchanting procedures that make the item specifically attached to the player, preventing other players from using or picking up the item. + +### Returns +boolean: Returns `true` if the item is bound to a player by an enchant, `false` otherwise. + +### Example Usage: +This script checks if a player's equipped item is bound by enchantment when trying to trade it, and cancels the trade if the condition is true. This can be useful in preventing accidentally trading items that are personally enchanted and bound. + +```typescript +const CancelTradeIfItemEnchanted: player_event_on_trade = (eventId: number, player: Player, tradeId: number) => { + const trade = player.GetTrade(); + + if (trade) { + for (let i = 0; i < trade.GetItemCount(); i++) { + const item = trade.GetItem(i); + if(item.IsBoundByEnchant()) { + player.SendMessageBox(`You cannot trade ${item.GetName()} as it is bound to you by an enchant.`); + trade.Cancel(); + return; + } + } + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_TRADE, (...args) => CancelTradeIfItemEnchanted(...args)); +``` +The above example begins with a function `CancelTradeIfItemEnchanted` that is called during the `PLAYER_EVENT_ON_TRADE` event. Inside, it checks each item in the ongoing trade for a bound by enchant condition using `IsBoundByEnchant()`. If any item returns true, indicating it is enchanted and bound to the player, the trade is canceled, and the player gets a warning message explaining why the trade was blocked. + +Such precautions ensure that items which have been specifically enchanted to be bound to a player are not accidentally or inadvertently traded away, keeping personalized or valuable enchantments safe. + +# IsBroken + +Checks if the [Item](./item.md) is broken. In the context of AzerothCore and mod-Eluna, an item is considered broken if its durability has reached 0, meaning it cannot be used until it's repaired. + +### Returns +*boolean* - Returns `true` if the item is broken (durability = 0), otherwise returns `false`. + +### Example Usage: + +This script demonstrates how to check if the player's equipped items are broken upon logging in, notifying the player if any of their gear needs repair. + +```typescript +const onPlayerLogin: player_event_on_login = (event: number, player: Player): void => { + const EQUIPMENT_SLOTS = 19; // Total number of equipment slots in WoW + + for (let i = 0; i < EQUIPMENT_SLOTS; i++) { + const item = player.GetEquippedItemBySlot(i); + if (item && item.IsBroken()) { + player.SendNotification("One or more of your items are broken! Visit a repair NPC."); + break; // Exit loop after finding the first broken item + } + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => onPlayerLogin(...args)); +``` + +In this script, we iterate through all possible equipment slots of a player when they log in. For each slot, we check if there is an item equipped and whether that item is broken using the `IsBroken` method. If a broken item is found, a notification is sent to the player advising them to repair their gear. The script then exits the loop to prevent spamming the player with multiple notifications if they have more than one broken item equipped. + +## IsConjuredConsumable +Determines if the item is a conjured consumable or not. Conjured consumables are items that are generally created by spells or abilities, such as a Mage's ability to conjure food and water for consumption. + +### Returns +`boolean` - Returns 'true' if the item is a conjured consumable product, 'false' otherwise. + +### Example Usage: +This example script identifies conjured consumable items a player tries to use and sends a custom notification to the player. + +```typescript +const onItemUse: player_event_on_use_item = (event: number, player: Player, item: Item): void => { + + if(item.IsConjuredConsumable()) { + player.SendNotification("You are about to use a conjured consumable item!"); + } else { + player.SendNotification("This item is not a conjured consumable."); + } + +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_USE_ITEM, (...args) => onItemUse(...args)); +``` + +In this script, the `onItemUse` function is registered to the *PLAYER_EVENT_ON_USE_ITEM* event, ensuring it runs whenever a player uses an item. Inside the function, it checks if the used item is a conjured consumable by calling the `IsConjuredConsumable` method on the `item` object. Depending on the result, it sends a notification to the player using `SendNotification`. + +This method can help in creating gameplay mechanics or features that rely on identifying whether an item is conjured, allowing for unique interactions or checks within a game's world facilitated by the mod-eluna environment on AzerothCore. + +## IsCurrencyToken +Determines if the item is considered a currency token within the game. Currency tokens are typically used for transactions and purchases without being a traditional currency like gold. This method can be useful for scripts that need to differentiate between regular items and currency tokens, such as custom vendors or loot distribution systems. + + +### Returns +`boolean` - Returns `true` if the [Item](./item.md) is a currency token, `false` otherwise. + +### Example Usage +In this example, we create a custom event where the player interacts with a specific object in the game world, let's say a custom NPC or object that represents a special vendor. When the player interacts with this entity, we check the player's inventory for a specific currency token item to determine if they can access special merchandise or rewards. + +```typescript +const SPECIAL_CURRENCY_ID = 12345; // This should be replaced with the actual Item entry ID of the currency token. + +const OnSpecialVendorInteraction: player_event_on_gossip = (event: number, player: Player, object: GameObject) => { + // Loop through the player's items + for(let bagSlot = 0; bagSlot < MAX_PLAYER_BAG_SLOTS; bagSlot++) { + const item = player.GetItemByPos(INVENTORY_SLOT_BAG_0, bagSlot); // INVENTORY_SLOT_BAG_0 represents the player's main bag. + if(item !== null && item.GetEntry() == SPECIAL_CURRENCY_ID) { + if(item.IsCurrencyToken()) { + // The item is a currency token, proceed with the special interaction + player.SendMessage("You have the special currency token! Access granted."); + // Insert logic here for what happens next, such as opening a custom vendor list + return; + } + } + } + + // If the loop completes without finding the currency token, or it's not a currency token + player.SendMessage("You do not have the required currency token."); +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_GOSSIP, (...args) => OnSpecialVendorInteraction(...args)); +``` + +In this example, `MAX_PLAYER_BAG_SLOTS` represents a placeholder for the actual maximum number of slots in a player's bag, and `INVENTORY_SLOT_BAG_0` represents the main inventory bag. This script initializes upon a specific gossip event with an NPC or object. It iterates through the player’s bag slots, checking for an item with the specified ID. If the item exists and `IsCurrencyToken` returns true, it proceeds with the custom logic, such as granting access to special items or bonuses. If the currency token isn't found or doesn't meet the criteria, the player receives a message indicating the lack of required currency token. + +## IsEquipped +This method determines whether the item is currently equipped by the player. It returns `true` if the item is equipped, otherwise `false`. + +### Returns +- **boolean**: A boolean value indicating whether the item is equipped (`true`) or not (`false`). + +### Example Usage: +This script checks whether the specified item is equipped by the player. If the item is equipped, it executes further actions such as enhancing the item's capabilities or integrating with other custom logic tailored for your AzerothCore mod environment. + +```typescript +// Example Item Entry for Thunderfury, Blessed Blade of the Windseeker +const THUNDERFURY_ENTRY = 19019; + +const OnPlayerEquip: player_event_on_equip_item = (event: number, player: Player, item: Item, bag: number, slot: number): void => { + + // Check if the equipped item is Thunderfury + if (item.GetEntry() === THUNDERFURY_ENTRY) { + + // Check if Thunderfury is actually equipped to prevent unnecessary checks + if (item.IsEquipped()) { + console.log("Thunderfury, Blessed Blade of the Windseeker is equipped!"); + + // Custom logic goes here, for example, applying an extra buff + player.AddAura(22888, player); // Assuming 22888 is a custom buff for demonstration + + // Further custom logic can be added here + // This could involve interacting with other parts of the player's state, + // mod functionality, or triggering other events + } + } +} + +// Registering the hook for the player equip item event +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_EQUIP_ITEM, (...args) => OnPlayerEquip(...args)); +``` + +In this example, when a player equips an item, the `OnPlayerEquip` function is triggered. It first checks if the equipped item is Thunderfury by comparing the item's entry ID. If it is Thunderfury and is confirmed to be equipped through the `IsEquipped` method, the script logs a message and applies a hypothetical buff to the player. This is a fundamental demonstration; however, the actual implementation can include more complex logic, such as integrating with custom systems or applying conditions based on the player's state. + +## IsInBag +Determines whether the item is currently stored in a player's bag. + +### Returns +boolean: Returns `true` if the item is in a bag, `false` otherwise. + +### Example Usage: +This script checks if a specific item is in the player's bag and informs the player about it. Useful for quests or events that require players to gather specific items. + +```typescript +const ITEM_ENTRY_ID = 12345; // Example Item Entry ID + +const CheckItemInBag: player_event_on_loot_item = (event: number, player: Player, item: Item) => { + // Check if the looted item is the one we're interested in + if(item.GetEntry() == ITEM_ENTRY_ID) { + // Now that we found the item, let's check if it's in the player's bag + if(item.IsInBag()) { + // Inform the player + player.SendBroadcastMessage("You have the required item in your bag."); + } else { + player.SendBroadcastMessage("You found the item, but it's not in your bag yet. Make sure to store it properly!"); + } + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => CheckItemInBag(...args)); +``` +In this example, when a player loots an item, it checks if the item's entry ID matches the specified `ITEM_ENTRY_ID`. If it does, it then checks if the item is in the player's bag using the `IsInBag` method. Depending on the outcome, it sends a message to the player either acknowledging the item is properly stored in their bag or reminding them to put it in their bag. + +## IsInTrade + +Checks whether the item is currently being traded. It enables scripts to identify if an item is in the middle of a trade process, providing a way to prevent specific actions, or to log or manage trading behaviors in custom ways. + +### Returns +- **isTrading**: boolean - Returns `true` if the item is currently in a trade window, `false` otherwise. + +### Example Usage +Below is an example script to prevent an item with a specific entry ID from being traded if it meets certain conditions. It could be part of a larger system to log attempts to trade rare or unique items, or to enforce game rules around the trading of specific items. + +```typescript +const ITEM_NOT_TRADEABLE_IF_EQUIPPED_ENTRY_ID = 12345; // Example item entry ID + +// Hook into the trading system to check for item trade attempts +const onAttemptToTrade: player_event_on_attempt_trade = (event: number, player: Player, item: Item): void => { + + // Check if the item being traded matches our specific criteria + if(item.GetEntry() == ITEM_NOT_TRADEABLE_IF_EQUIPPED_ENTRY_ID && item.IsEquipped()) { + if(item.IsInTrade()) { + player.SendNotification("This item cannot be traded right now."); + CancelTrade(); // Hypothetical function to cancel the ongoing trade + } + } +} + +// Register the event +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_ATTEMPT_TRADE, (...args) => onAttemptToTrade(...args)); +``` + +In this example, the script adds a layer of control over the trading process of items by employing the `IsInTrade()` method from the `Item` class. If the item in question matches certain criteria (in this case, being a specific item and currently equipped), the trade attempt can be intervened with a notification to the player, and the operation could be cancelled. This pattern enables the creation of complex trade validation logic, enhancing the game's integrity or customizing the trading experience according to server rules or gameplay mechanics. + +## IsLocked +This method checks if the player's selected item is locked or not. + +### Returns +bool: boolean - Returns `true` if the [Item](./item.md) is locked, and `false` otherwise. + +### Example Usage +The following script is used to check if the player's currently equipped weapon is locked, and if so, it sends a warning message to the player. This can be useful for ensuring players are aware of their item's status or for implementing custom gameplay mechanics around item locking. + +```typescript +const CheckWeaponLockStatus: player_event_on_equip_item = (event: number, player: Player, item: Item, bag: number, slot: number): void => { + // Assuming the weapon is equipped in the main hand slot (slot 15) + if (slot === 15) { + if (item.IsLocked()) { + player.SendBroadcastMessage("Your weapon is currently locked and cannot be used."); + } else { + player.SendBroadcastMessage("Your weapon is unlocked and ready for battle."); + } + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_EQUIP_ITEM, (...args) => CheckWeaponLockStatus(...args)); +``` +In this example, the `CheckWeaponLockStatus` function is hooked to the `PLAYER_EVENT_ON_EQUIP_ITEM` event. Every time a player equips an item, this function checks if the item equipped in the main hand (slot 15) is locked. Depending on the item's lock status, it sends a message to the player informing them about the state of their weapon. + +Remember, in AzerothCore mod-eluna, specific slot indexes are used to identify where an item is equipped. In this example, slot 15 represents the main hand weapon slot. This script ensures that players are fully aware of the operability of their main weapon, enhancing gameplay integrity and immersion. + +## IsNotBoundToPlayer +Determines if the item is not currently bound to the specified player. Item binding is a common mechanic in MMORPGs which restricts the transferability of items to other players after being equipped or picked up. This method allows for checking the item's binding status in relation to a given player. + +### Parameters +* player: [Player](./player.md) - The player to check the item's binding status against. + +### Returns +* boolean - Returns `true` if the item is not bound to the player, otherwise returns `false`. + +### Example Usage +In this example, before allowing a player to trade an item, we check if the item is not bound to them. This could be part of a larger trading system within a custom mod for AzerothCore using mod-eluna. This system might include additional checks for item conditions such as durability, level requirements, or special status (e.g., quest items). + +```typescript +// Function to initiate a trade between two players for a specific item +const initiateTrade: trade_event_on_trade_attempt = (event: number, sender: Player, receiver: Player, item: Item): void => { + // Check if the item is not bound to the sender + if (item.IsNotBoundToPlayer(sender)) { + // Further code to handle item trade logistics + console.log(`Item can be traded from ${sender.GetName()} to ${receiver.GetName()}.`); + // Example code to physically transfer the item could go here + } else { + // Inform the sender the item cannot be traded as it's bound to them + console.log(`Item is bound and cannot be traded.`); + sender.SendNotification(`You cannot trade bound items.`); + } +}; + +// Registering the custom trade attempt event with a hypothetical trade event listener +RegisterTradeEvent(TradeEvents.TRADE_EVENT_ON_TRADE_ATTEMPT, (...args) => initiateTrade(...args)); +``` + +In this example, when a trade is attempted, it checks whether the item involved is bound to the sender. If the item is not bound, a message is logged to the console (presumably for debugging purposes or could be replaced with actual trade logic), and if it is bound, it informs the sender that the item cannot be traded. This helps ensure the game's item trading rules are respected, adding an extra layer of depth to player interactions and the virtual economy. + +## IsNotEmptyBag +Determines whether the item is a bag that contains any items. Useful for validating inventory before performing operations that rely on empty or non-empty bags. + +### Returns +- `boolean`: Returns `true` if the item is a bag and it is not empty, `false` otherwise. + +### Example Usage: +This script checks if a specific bag in the player's inventory is not empty and sends a notification message to the player. This could be part of a larger inventory management system or a pre-check before an action that requires an empty bag. + +```typescript +const CHECK_BAG_SLOT = 19; // Example bag slot ID + +// Function to check and notify about bag status +const NotifyIfBagNotEmpty: player_event_on_login = (event: number, player: Player): void => { + const bagItem: Item = player.GetItemByPos(255, CHECK_BAG_SLOT); + + if (bagItem && bagItem.IsNotEmptyBag()) { + player.SendBroadcastMessage("The specified bag is not empty. Please empty your bag before proceeding."); + } else { + player.SendBroadcastMessage("Your bag is empty or not a bag. You can proceed."); + } +} + +// Register the event for player login to run the bag check +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => NotifyIfBagNotEmpty(...args)); +``` + +In this example, `player.GetItemByPos(255, CHECK_BAG_SLOT)` is a fictional method assumed to retrieve an item based on its bag (255 for the main backpack) and slot position. Replace it with the actual method you would use to access an item in the player's inventory in your environment. + +The example demonstrates a basic utility operation where the status of a player's bag might influence gameplay or system logic, serving as a template for more complex inventory interactions or checks. + +## IsPotion +This method determines whether the Item instance is classified as a potion within the game. A potion typically refers to a consumable item that players can use to gain buffs, heal, or perform other specific functions. This method is essential for scripts that need to handle potions differently from other types of items. + +### Returns +boolean: Returns `true` if the Item is a potion; otherwise, returns `false`. + +### Example Usage: +The following script checks if an item looted by the player is a potion. If it is, the script grants the player an additional potion of the same type, simulating a "loot bonus" effect for potions. + +```typescript +const POTION_BONUS_EVENT: player_event_on_loot_item = (event: number, player: Player, item: Item) => { + + // Check if the looted item is a potion + if(item.IsPotion()) { + // Get the entry ID of the potion + const potionEntryId = item.GetEntry(); + + // Grant the player an additional potion of the same type + player.AddItem(potionEntryId, 1); + + // Optionally, inform the player about the bonus potion + player.SendBroadcastMessage(`You've received a bonus potion for looting a potion!`); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => POTION_BONUS_EVENT(...args)); +``` +In this example, the `IsPotion` method is used to verify whether the item that triggered the `PLAYER_EVENT_ON_LOOT_ITEM` event is a potion. If the verification returns `true`, the script proceeds to give the player an additional potion of that type. Additionally, a broadcast message is sent to the player to inform them about the bonus potion received. This illustrates a creative way to enhance the gaming experience by rewarding players for looting specific types of items. + +## IsSoulBound +Checks if the item is soulbound. Soulbound items are bound to the player and cannot be traded or sold to other players. + +### Returns +* boolean - `true` if the item is soulbound, `false` otherwise. + +### Example Usage: +Script to check if a recently looted item is soulbound and notify the player. + +```typescript +const onLootItem: player_event_on_loot_item = (event: number, player: Player, item: Item): void => { + if (item.IsSoulBound()) { + player.SendBroadcastMessage(`The item [${item.GetEntry()}] is soulbound.`); + } else { + player.SendBroadcastMessage(`The item [${item.GetEntry()}] is not soulbound, you can trade or sell it.`); + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => onLootItem(...args)); +``` + +This script hooks into the `PLAYER_EVENT_ON_LOOT_ITEM` event to check every item a player loots. If the item is found to be soulbound, it notifies the player with a message that the item cannot be traded or sold. Otherwise, it informs the player that the item is not soulbound, indicating that it can be freely traded or sold. + +## IsWeaponVellum +Checks if the item is a Weapon Vellum. Weapon Vellums are consumable items that players use to store enchantments for later application to weapons. + +### Returns +boolean - Returns `true` if the item is a Weapon Vellum, `false` otherwise. + +### Example Usage: + +This function could be particularly useful in a scenario where you want to apply a specific action based on whether the item is a Weapon Vellum or not. For example, you might have a custom script that rewards players with enchantments but wants to ensure the player is using a Weapon Vellum. + +```typescript +const OnItemReceive: player_event_on_loot_item = (event: number, player: Player, item: Item) => { + // Check if the looted item is a weapon vellum + if (item.IsWeaponVellum()) { + // Assume we have a function that logs a special event when weapon vellums are looted + LogSpecialEvent(player, item); + player.SendBroadcastMessage("You've looted a Weapon Vellum! Make sure to use it wisely."); + } else { + player.SendBroadcastMessage("This item is not a Weapon Vellum."); + } +} + +// Register the loot event to trigger our custom Weapon Vellum check +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => OnItemReceive(...args)); + +function LogSpecialEvent(player: Player, item: Item): void { + // Implementation of logging or handling the special event + console.log(`Player ${player.GetName()} looted a Weapon Vellum.`); +} +``` + +The example illustrates how you might use the `IsWeaponVellum` method in a practical scenario within a mod for mod-eluna on AzerothCore. By identifying whether an item is a Weapon Vellum, you can trigger specific in-game events, notifications, or logging for further interaction or statistical analysis. + +## SaveToDB +This method saves the state of the [Item] to the database. This is particularly useful for preserving changes to an item's state, such as ownership, enchantments, or quantity adjustments. This ensures that any modifications made to an item during runtime are retained across server restarts or player logouts, contributing to a consistent and continuous gameplay experience. + +### Example Usage: +In this script, we automatically add a custom enchantment to a newly looted item and then save the item's state to the database to ensure the enchantment is retained. + +```typescript +const ENCHANTMENT_ID = 333; // Example enchantment ID +const ITEM_ENTRY = 12345; // Example item entry + +const AddEnchantmentAndSave: player_event_on_loot_item = (event: number, player: Player, item: Item): void => { + if(item.GetEntry() == ITEM_ENTRY) { + // Simulate adding an enchantment to the item + // Assuming AddEnchantment is a method that adds an enchantment to the item + // This is a fictional example for demonstration purposes + item.AddEnchantment(ENCHANTMENT_ID, 0); + + // Save the item's state to the database + item.SaveToDB(); + + // Inform the player + player.SendBroadcastMessage("A custom enchantment has been added to your item, and its state has been saved!"); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => AddEnchantmentAndSave(...args)); +``` + +In this sample, a custom function `AddEnchantmentAndSave` is registered to run whenever a player loots an item (`PLAYER_EVENT_ON_LOOT_ITEM`). When the looted item matches the specified `ITEM_ENTRY`, a fictional `AddEnchantment` method is called to simulate adding an enchantment to the item. Immediately following this alteration, `SaveToDB` is invoked to persist the item's modified state to the database. This ensures that the enchantment and any other changes remain attached to the item, even if the player logs out or the server restarts. The player is also notified via a broadcast message about the enchantment addition and the item's preservation. + +## SetBinding + +This method sets the binding status of an `Item`. By setting binding to 'true', the item becomes soulbound to the player and cannot be traded. Setting it to 'false' will make the item unbound, allowing it to be traded or sold. This method is particularly useful in custom scripts where certain items' binding statuses need to be dynamically altered based on specific conditions or events. + +### Parameters +- setBinding: boolean - Determines the binding state of the item. `true` for soulbound and `false` for unbound. + +### Example Usage: + +In this example, we are rewarding a player with a special item when they complete a custom event. This item is initially not soulbound to allow the player a chance to trade or sell it. However, if the player equips the item, it will become soulbound to prevent it from being traded after use. + +```typescript +const SPECIAL_ITEM_ENTRY = 12345; // Example item entry ID + +const RewardItem: player_event_on_custom_event = (event: number, player: Player) => { + // Add the special, initially unbound item to the player's inventory + const item = player.AddItem(SPECIAL_ITEM_ENTRY, 1); + item.SetBinding(false); +} + +const OnPlayerEquip: player_event_on_equip_item = (event: number, player: Player, item: Item, bag: number, slot: number) => { + // Check if the equipped item is the special item + if(item.GetEntry() == SPECIAL_ITEM_ENTRY) { + // Make the item soulbound when equipped + item.SetBinding(true); + + player.SendBroadcastMessage("Your special item has now become soulbound!"); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_CUSTOM, (...args) => RewardItem(...args)); +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_EQUIP_ITEM, (...args) => OnPlayerEquip(...args)); +``` + +In this script, the `RewardItem` function is called to reward a player with a special item that is not initially soulbound, allowing them the freedom to trade or sell the item if they decide not to use it. The `OnPlayerEquip` function listens for an event where the player equips an item. If the equipped item matches the special item's entry ID, it calls `SetBinding(true)` on the item to make it soulbound, and informs the player with a broadcast message. This ensures the item can be freely traded until it is consciously used by the player, at which point it becomes bound to them. + +## SetCount + +This method updates the stack count of the given [Item] in the player's inventory. It is particularly useful when managing items programmatically, for instance, in custom quests or events where the quantity of an item needs to be adjusted according to gameplay events. + +### Parameters +- `count`: number - The new stack count for the [Item]. Setting this to zero effectively removes the item from the player's inventory. + +### Example Usage: +Let's say we want to create a system where a player can exchange a certain number of tokens for a reward. After the exchange, we need to update the quantity of the spent tokens in the player's inventory. Below is an example script that reduces the number of tokens by a fixed amount after an exchange action. + +```typescript +const TOKEN_ITEM_ENTRY = 12345; // Example Item Entry ID for a 'Token' item. +const TOKENS_NEEDED_FOR_EXCHANGE = 10; + +// Function to handle the token exchange process. +const onExchangeTokens: some_event = (player: Player): void => { + const tokens = player.GetItemByEntry(TOKEN_ITEM_ENTRY); + + if (tokens) { + const currentTokenCount = tokens.GetCount(); + + // Check if the player has enough tokens for the exchange + if (currentTokenCount >= TOKENS_NEEDED_FOR_EXCHANGE) { + // Reduce the tokens by the required amount for the exchange + tokens.SetCount(currentTokenCount - TOKENS_NEEDED_FOR_EXCHANGE); + + // Reward the player, handle other parts of the exchange process here. + // For example: player.AddItem(REWARD_ITEM_ENTRY, 1); + + player.SendBroadcastMessage("Exchange successful."); + } else { + player.SendBroadcastMessage("You do not have enough tokens for this exchange."); + } + } else { + player.SendBroadcastMessage("You do not have any tokens."); + } +} + +// Register the custom function to some event, depending on when you want the token exchange to happen. +// Example: RegisterPlayerEvent(PlayerEvents.CUSTOM_EVENT_ON_TOKEN_EXCHANGE, onExchangeTokens); +``` + +This script showcases how to use the `SetCount` method to decrease the quantity of a particular item in the player's inventory. It first checks if the player owns the item and has enough quantity for the exchange. Then, it updates the item's quantity accordingly. This example can be modified to fit various gameplay mechanics involving items and their quantities. + +## SetEnchantment +This method applies a specified enchantment to the item within a defined slot. It's commonly used to enchant gear pieces in-game, providing various enhancements to the player's abilities or stats. Enchantment IDs correspond to the specific abilities or boosts they provide, while the slot indicates where on the item the enchantment is applied. + +### Parameters +- `enchantId`: number - The ID of the enchantment to apply. Refer to the enchantment definitions in the AzerothCore database for the correct IDs. +- `enchantSlot`: number - The slot number where the enchantment will be applied. Each item has a specific set of slots available for enchanting. + +### Returns +- `result`: boolean - Returns `true` if the enchantment was successfully applied, `false` otherwise. + +### Example Usage: +Boost a player's weapon by applying a Crusader enchantment when they reach a certain level. Crusader is known for its healing effect and strength increase, making it a valuable enchant for leveling players. + +```typescript +const CRUSADER_ENCHANT_ID = 20034; // Example enchantment ID for Crusader +const WEAPON_SLOT = 0; // Assuming 0 is the main weapon slot + +const onPlayerLevelUp: player_event_on_level_change = (event: number, player: Player, oldLevel: number, newLevel: number): void => { + // Check if the player has reached level 60 + if (newLevel === 60) { + const playerWeapon = player.GetEquippedItemBySlot(WEAPON_SLOT); // Retrieves the item in the weapon slot + + // Ensure the player has a weapon equipped in the designated slot + if (playerWeapon) { + const enchantApplied = playerWeapon.SetEnchantment(CRUSADER_ENCHANT_ID, WEAPON_SLOT); + + if (enchantApplied) { + player.SendBroadcastMessage("Your weapon has been enchanted with Crusader!"); // Notify the player + } else { + player.SendBroadcastMessage("Failed to apply Crusader enchantment. Please check your weapon and try again."); + } + } else { + player.SendBroadcastMessage("You need to have a weapon equipped to receive the Crusader enchantment."); + } + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LEVEL_CHANGE, (...args) => onPlayerLevelUp(...args)); +``` + +This script checks for the player's level upon leveling up; if they've reached level 60, it attempts to apply the Crusader enchantment to their main weapon slot. It notifies the player about the success or failure of the operation. Note that the actual enchantment ID, weapon slot, and event hook should be adjusted to fit your server configuration and needs. + +## SetOwner +Assigns ownership of the item to the specified player. The owner of an item is able to utilize or interact with the item within the game. + +### Parameters +- player: [Player](./player.md) - The player to set as the item's owner. + +### Example Usage: +The following script sets a recently looted item's owner to the player who looted it. This can be useful for tracking item ownership for custom events or mechanics. + +```typescript +const onItemLooted: player_event_on_loot_item = (event: number, player: Player, item: Item): void => { + // Sets the player as owner of the looted item + item.SetOwner(player); + + // Optionally, you could have a message or a log here + // e.g., console.log(player.GetName() + " is now the owner of the item " + item.GetEntry()); +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => onItemLooted(...args)); +``` + +In this example, the script is intended to be used within a larger system leveraging the mod-eluna framework on Azerothcore. The `SetOwner` method facilitates a fundamental aspect of player-item interaction by ensuring that items are associated with their rightful owners, which can be pivotal for both gameplay mechanics and administrative purposes. + diff --git a/docs/classes/Player.md b/docs/classes/Player.md index 39848b4..c3b209c 100644 --- a/docs/classes/Player.md +++ b/docs/classes/Player.md @@ -9517,3 +9517,2474 @@ In this example: This script provides the player with real-time feedback on their kills and offers a little extra recognition when they reach a milestone number of kills. +## SendPacket +Sends a [WorldPacket](./worldpacket.md) to the player's client. This method can be used to send various types of data and information to the player, such as system messages, spell visual effects, sound effects, and more. + +### Parameters +* packet: [WorldPacket](./worldpacket.md) - The WorldPacket object to send to the player. +* selfOnly?: boolean - If set to 'true', the packet will only be sent to the player. If set to 'false' or omitted, the packet will be sent to the player and their surrounding players within visible range. + +### Example Usage +Sending a custom message to the player with a visual effect and sound: +```typescript +const VISUAL_EFFECT_ENTRY = 123; +const SOUND_EFFECT_ENTRY = 456; + +const SendCustomMessage = (player: Player, message: string) => { + const packet = new WorldPacket(Opcodes.SMSG_MESSAGECHAT); + packet.WriteUInt8(ChatMsg.CHAT_MSG_SYSTEM); + packet.WriteUInt32(Language.LANG_UNIVERSAL); + packet.WriteUInt64(0); + packet.WriteUInt32(0); + packet.WriteString(message); + packet.WriteUInt8(0); + player.SendPacket(packet); + + const visualPacket = new WorldPacket(Opcodes.SMSG_PLAY_SPELL_VISUAL); + visualPacket.WriteUInt64(player.GetGUID()); + visualPacket.WriteUInt32(VISUAL_EFFECT_ENTRY); + player.SendPacket(visualPacket, true); + + player.PlayDirectSound(SOUND_EFFECT_ENTRY); +}; + +const OnPlayerLogin: player_event_on_login = (event: number, player: Player) => { + SendCustomMessage(player, "Welcome to the server! Here's a special effect just for you."); +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => OnPlayerLogin(...args)); +``` + +In this example, when a player logs in, the `SendCustomMessage` function is called. It creates a new `WorldPacket` with the `SMSG_MESSAGECHAT` opcode to send a system message to the player. The packet is populated with the necessary data, such as the message type, language, and the actual message content. + +After sending the system message, another `WorldPacket` is created with the `SMSG_PLAY_SPELL_VISUAL` opcode to play a visual effect on the player. The player's GUID and the visual effect entry ID are written to the packet. The `selfOnly` parameter is set to 'true' to ensure that the visual effect is only visible to the player and not to surrounding players. + +Finally, the `PlayDirectSound` method is called to play a sound effect for the player. + +This example demonstrates how the `SendPacket` method can be used in combination with other methods and opcodes to create immersive experiences for players by sending custom messages, visual effects, and sound effects. + +## SendQuestTemplate +This method sends a quest offer window to the player for the specified quest. The quest details are taken from the `quest_template` table in the world database. + +### Parameters +* questId: number - The ID of the quest to offer, as found in the `quest_template` table. +* activateAccept?: boolean - Optional parameter. If set to true, the quest will be automatically accepted if the player is eligible. Defaults to false. + +### Example Usage +This example shows how to offer a daily quest to a player when they login, and automatically accept it if they are eligible. + +```typescript +const DAILY_QUEST_ID = 12345; + +function OnLogin(event: PlayerEvents, player: Player) { + // Check if the player is eligible for the daily quest + if (player.CanCompleteQuest(DAILY_QUEST_ID)) { + // Get the current server time + const now = new Date(); + + // Check if the quest has already been completed today + const lastCompleted = player.GetQuestRewardStatus(DAILY_QUEST_ID); + if (!lastCompleted || (now.getTime() - lastCompleted.getTime()) >= 86400000) { + // Offer the quest and automatically accept it + player.SendQuestTemplate(DAILY_QUEST_ID, true); + + // Inform the player that the quest has been accepted + player.SendBroadcastMessage(`You have accepted the daily quest '${GetQuestTemplate(DAILY_QUEST_ID).LogTitle}'.`); + } + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, OnLogin); +``` + +In this example: +1. We define a constant `DAILY_QUEST_ID` to store the ID of the daily quest we want to offer. +2. We register a `PLAYER_EVENT_ON_LOGIN` event handler to run our logic when a player logs in. +3. We check if the player is eligible to complete the quest using `CanCompleteQuest()`. +4. If the player is eligible, we get the current server time using `new Date()`. +5. We check if the player has already completed the quest today by comparing the last completion time (if any) to the current time. If the quest hasn't been completed or it's been more than 24 hours (86400000 ms) since the last completion, we proceed. +6. We offer the quest to the player using `SendQuestTemplate()`, passing `true` as the second parameter to automatically accept the quest if the player is eligible. +7. Finally, we send a message to the player informing them that they have accepted the daily quest, using `SendBroadcastMessage()` and the quest's `LogTitle` from the `quest_template` table. + +This example demonstrates how to use the `SendQuestTemplate()` method in a practical scenario, while also showcasing other related methods and techniques commonly used in quest scripting. + +## SendShowBank +Sends a bank window to the player from a specified WorldObject. This is typically used to allow players to access their bank from NPCs, objects or other interactive game objects. + +### Parameters +* sender: [WorldObject](./worldobject.md) - The WorldObject that is sending the bank window to the player. + +### Example Usage +This example shows how to create an NPC that allows players to access their bank when interacting with it. + +```typescript +const BANK_NPC_ENTRY = 1000; + +// Create a gossip hello hook for the bank NPC +const BankNPCGossipHello: gossip_hello = (event: number, player: Player, object: WorldObject): boolean => { + // Add a gossip item to open the bank + player.GossipMenuAddItem(GossipIcon.Banker, "I would like to access my bank.", 0, 1); + + // Send the gossip menu to the player + player.GossipSendMenu(0, object.GetGUID()); + + return true; +}; + +// Create a gossip select hook for the bank NPC +const BankNPCGossipSelect: gossip_select = (event: number, player: Player, object: WorldObject, sender: number, action: number): boolean => { + // Check if the player selected the bank gossip option + if (action === 1) { + // Close the gossip menu + player.GossipComplete(); + + // Send the bank window to the player + player.SendShowBank(object); + } + + return true; +}; + +// Register the gossip hooks for the bank NPC +RegisterCreatureGossipEvent(BANK_NPC_ENTRY, GOSSIP_EVENT_ON_HELLO, (...args) => BankNPCGossipHello(...args)); +RegisterCreatureGossipEvent(BANK_NPC_ENTRY, GOSSIP_EVENT_ON_SELECT, (...args) => BankNPCGossipSelect(...args)); +``` + +In this example, we create an NPC with the entry ID `BANK_NPC_ENTRY`. When a player interacts with this NPC, the `BankNPCGossipHello` function is called, which adds a gossip item to the menu allowing the player to access their bank. + +When the player selects the bank gossip option, the `BankNPCGossipSelect` function is called. It checks if the selected action corresponds to the bank option (action === 1) and if so, it closes the gossip menu using `player.GossipComplete()` and sends the bank window to the player using `player.SendShowBank(object)`, passing the NPC object as the sender. + +Finally, we register the gossip hooks for the bank NPC using `RegisterCreatureGossipEvent` for both the `GOSSIP_EVENT_ON_HELLO` and `GOSSIP_EVENT_ON_SELECT` events, associating them with their respective handler functions. + +With this script, players can interact with the designated bank NPC to conveniently access their bank storage without having to visit a physical bank location in the game world. + +## SendShowMailBox +Shows the mailbox window to the player. If a guid is provided, the mailbox window will be opened with that specific mailbox. + +### Parameters +* guid (optional): number - The GUID of the mailbox to open. If not provided, the nearest mailbox will be used. + +### Example Usage +This example demonstrates how to open the mailbox window for a player when they interact with a specific gameobject. In this case, a custom mailbox with a specific GUID. + +```typescript +const CUSTOM_MAILBOX_GUID = 12345; // Replace with the GUID of your custom mailbox gameobject + +const OnGossipHello: player_event_on_gossip_hello = (event: number, player: Player, object: GameObject) => { + if (object.GetDBTableGUIDLow() === CUSTOM_MAILBOX_GUID) { + // Show a custom gossip menu + player.GossipMenuAddItem(0, "Open Mailbox", 0, 1); + player.GossipSendMenu(0, object); + } +}; + +const OnGossipSelect: player_event_on_gossip_select = (event: number, player: Player, object: GameObject, sender: number, action: number) => { + if (object.GetDBTableGUIDLow() === CUSTOM_MAILBOX_GUID && action === 1) { + // Open the mailbox window with the specific GUID + player.SendShowMailBox(CUSTOM_MAILBOX_GUID); + player.GossipComplete(); + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_GOSSIP_HELLO, (...args) => OnGossipHello(...args)); +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_GOSSIP_SELECT, (...args) => OnGossipSelect(...args)); +``` + +In this example: +1. We define a constant `CUSTOM_MAILBOX_GUID` to store the GUID of our custom mailbox gameobject. +2. In the `OnGossipHello` event, we check if the interacted object has the same GUID as our custom mailbox. + - If it matches, we add a gossip menu item "Open Mailbox" with an action ID of 1. + - We send the gossip menu to the player. +3. In the `OnGossipSelect` event, we check if the selected object is our custom mailbox and if the action ID is 1. + - If the conditions are met, we call `player.SendShowMailBox(CUSTOM_MAILBOX_GUID)` to open the mailbox window with the specific GUID. + - We call `player.GossipComplete()` to close the gossip window. +4. Finally, we register the `OnGossipHello` and `OnGossipSelect` events to handle the player interactions. + +This example showcases how to create a custom mailbox gameobject and open the mailbox window for the player when they interact with it using gossip menus. + +## SendSpiritResurrect +This method will send a resurrect request to the player's spirit healer. This is the same resurrect that a player can do from a spirit healer after dying. This will not work if the player's body is still in the world. The player must be at a graveyard as a ghost for this to function properly. + +### Parameters +None + +### Example Usage: +This script will allow a GM to cast a revive spell on a player's spirit to resurrect them as long as they are already at a graveyard in spirit form. + +```typescript +const REVIVE_SPELL_ID = 99999; + +const SpellCast = (event: any, caster: Unit, spellTarget: Unit, spellId: number): void => { + if(spellId == REVIVE_SPELL_ID) + { + if(caster instanceof Player && spellTarget instanceof Player) + { + // Check if the player is casting the spell on theirself + if(caster.GetGUID() !== spellTarget.GetGUID()) + { + caster.SendBroadcastMessage("You can only cast this spell on yourself.") + return; + } + + // Check if player is alive + if(spellTarget.IsAlive()) + { + caster.SendBroadcastMessage("You can't resurrect yourself if you are still alive."); + return; + } + + // Check if player is in a graveyard + if(!spellTarget.IsInGraveyard()) + { + caster.SendBroadcastMessage("You must be at a graveyard in your spirit form to resurrect."); + return; + } + + spellTarget.SendSpiritResurrect(); + spellTarget.SendBroadcastMessage("You have been resurrected by the power of the Light!"); + } + } +} + +RegisterServerEvent(ServerEvents.CREATURE_EVENT_ON_SPELL_CAST, (...args) => SpellCast(...args)); +``` + +In this example, we have created a custom spell that will allow a player to resurrect their spirit at a graveyard. First, we check if the player is casting the spell on theirself as this spell should not work on other players. Next, we make sure the player is not alive, as you cannot resurrect yourself while alive. We then check to make sure the player is at a graveyard in spirit form. If all the conditions are met, we call the SendSpiritResurrect() method to send the resurrect request to the player. Finally, we send a message to the player to let them know they have been resurrected. + +## SendTabardVendorActivate +This method sends a tabard vendor window to the player from the specified WorldObject. It allows players to interact with a tabard vendor and purchase tabards. + +### Parameters +* sender: [WorldObject](./worldobject.md) - The WorldObject that represents the tabard vendor. + +### Example Usage +In this example, we create a custom NPC that acts as a tabard vendor. When the player interacts with the NPC, it sends the tabard vendor window to the player. + +```typescript +const TABARD_VENDOR_ENTRY = 1234; // Custom NPC entry ID + +// Create a custom NPC +const CreateTabardVendor = (): void => { + const vendorPosition = { x: 0, y: 0, z: 0, o: 0 }; // Set the desired position and orientation + const vendorMap = 0; // Set the desired map ID + + const vendor = InstanceData.GetCreature(TABARD_VENDOR_ENTRY, vendorMap, vendorPosition); + + if (!vendor) { + // Spawn the custom NPC if it doesn't exist + vendor = InstanceData.AddCreature(TABARD_VENDOR_ENTRY, vendorMap, vendorPosition); + + if (vendor) { + // Set the NPC flags to make it a gossip NPC + vendor.SetFlag(UnitFlags.UNIT_NPC_FLAG_GOSSIP, 0); + } + } +}; + +// Called when the player talks to the tabard vendor NPC +const OnTabardVendorHello: vehicle_event_on_hello = (event: number, player: Player, vendor: Creature): void => { + // Check if the NPC is the custom tabard vendor + if (vendor.GetEntry() === TABARD_VENDOR_ENTRY) { + // Send the tabard vendor window to the player + player.SendTabardVendorActivate(vendor); + } +}; + +// Register the events +RegisterCreatureEvent(CreatureEvents.CREATURE_EVENT_ON_SPAWN, (...args) => CreateTabardVendor(...args)); +RegisterCreatureEvent(CreatureEvents.CREATURE_EVENT_ON_GOSSIP_HELLO, (...args) => OnTabardVendorHello(...args)); +``` + +In this script: +1. We define a custom NPC entry ID (`TABARD_VENDOR_ENTRY`) for the tabard vendor. +2. In the `CreateTabardVendor` function, we check if the custom NPC already exists. If it doesn't, we spawn the NPC at the desired position and map, and set the necessary NPC flags. +3. We register the `CreatureEvents.CREATURE_EVENT_ON_SPAWN` event to call the `CreateTabardVendor` function when the server starts up. +4. In the `OnTabardVendorHello` function, we check if the NPC that the player interacted with is the custom tabard vendor. If it is, we call the `SendTabardVendorActivate` method, passing the vendor object as the sender. +5. We register the `CreatureEvents.CREATURE_EVENT_ON_GOSSIP_HELLO` event to call the `OnTabardVendorHello` function when the player interacts with the tabard vendor NPC. + +With this script, players can interact with the custom tabard vendor NPC, and the tabard vendor window will be sent to them, allowing them to purchase tabards. + +## SendTaxiMenu +Sends a flightmaster window to the player from the specified creature. This allows the player to interact with the creature as if it were a flightmaster, opening up the taxi destination window. + +### Parameters +* sender: [Creature](./creature.md) - The creature to send the taxi menu from, acting as a flightmaster + +### Example Usage: +Create a custom flightmaster NPC that can send players to specific locations based on their level and reputation. +```typescript +const CUSTOM_FLIGHTMASTER_ENTRY = 1000000; +const STORMWIND_TAXI_NODE = 2; +const IRONFORGE_TAXI_NODE = 6; +const GNOMEREGAN_TAXI_NODE = 27; + +const OnGossipHello: creature_event_on_gossip_hello = (event: number, creature: Creature, player: Player) => { + if (creature.GetEntry() === CUSTOM_FLIGHTMASTER_ENTRY) { + player.GossipMenuAddItem(0, "Fly to Stormwind", 1, 0); + + if (player.GetLevel() >= 20 && player.GetReputationRank(54) >= 4) { // Gnomeregan Exiles - Friendly + player.GossipMenuAddItem(0, "Fly to Ironforge", 2, 0); + } + + if (player.GetLevel() >= 30 && player.GetReputationRank(54) >= 6) { // Gnomeregan Exiles - Honored + player.GossipMenuAddItem(0, "Fly to Gnomeregan", 3, 0); + } + + player.GossipSendMenu(1, creature.GetGUID()); + } +}; + +const OnGossipSelect: creature_event_on_gossip_select = (event: number, creature: Creature, player: Player, sender: any, action: number) => { + if (creature.GetEntry() === CUSTOM_FLIGHTMASTER_ENTRY) { + player.GossipComplete(); + + switch (action) { + case 1: + player.SendTaxiMenu(creature); + player.ActivateTaxiPathTo(STORMWIND_TAXI_NODE); + break; + case 2: + player.SendTaxiMenu(creature); + player.ActivateTaxiPathTo(IRONFORGE_TAXI_NODE); + break; + case 3: + player.SendTaxiMenu(creature); + player.ActivateTaxiPathTo(GNOMEREGAN_TAXI_NODE); + break; + } + } +}; + +RegisterCreatureEvent(CUSTOM_FLIGHTMASTER_ENTRY, CreatureEvents.CREATURE_EVENT_ON_GOSSIP_HELLO, OnGossipHello); +RegisterCreatureEvent(CUSTOM_FLIGHTMASTER_ENTRY, CreatureEvents.CREATURE_EVENT_ON_GOSSIP_SELECT, OnGossipSelect); +``` +In this example, we create a custom flightmaster NPC that opens a gossip menu with different flight options based on the player's level and reputation with the Gnomeregan Exiles faction. When the player selects an option, the `SendTaxiMenu` method is called to open the flightmaster window, and then the player is sent to the corresponding taxi node using `ActivateTaxiPathTo`. + +## SendTrainerList +This method sends a trainer window to the player from the specified creature. The trainer window allows the player to browse and learn new spells and abilities from the creature trainer. + +### Parameters +* sender: [Creature](./creature.md) - The creature that will act as the trainer and send the trainer window to the player. + +### Example Usage +In this example, when a player interacts with a creature (e.g., clicks on it), the script checks if the creature's entry matches a specific trainer entry. If it does, the creature sends the trainer window to the player, allowing them to browse and learn new spells and abilities. + +```typescript +const TRAINER_ENTRY = 123; // Replace with the desired trainer entry ID + +const onGossipHello: player_event_on_gossip_hello = (event: number, player: Player, creature: Creature) => { + if (creature.GetEntry() === TRAINER_ENTRY) { + creature.SendTrainerList(player); + return; + } + + // Other gossip handling logic for non-trainer creatures + // ... + + player.GossipComplete(); +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_GOSSIP_HELLO, (...args) => onGossipHello(...args)); +``` + +In this script: +1. We define a constant `TRAINER_ENTRY` to store the entry ID of the desired trainer creature. +2. We register a player event handler for the `PLAYER_EVENT_ON_GOSSIP_HELLO` event using `RegisterPlayerEvent`. +3. Inside the event handler, we check if the interacted creature's entry matches the `TRAINER_ENTRY`. +4. If it matches, we call `creature.SendTrainerList(player)` to send the trainer window to the player. +5. If the creature is not a trainer, we can handle other gossip-related logic or simply call `player.GossipComplete()` to close the gossip window. + +By using this script, when a player interacts with a creature that matches the specified trainer entry, the creature will send the trainer window to the player, allowing them to learn new spells and abilities. + +Note: Make sure to replace `TRAINER_ENTRY` with the actual entry ID of the trainer creature you want to use in your script. + +## SetAcceptWhispers +This method allows you to set whether the player accepts whispers from other players or not. If set to false, the player will not receive whispers from other players. + +### Parameters +* acceptWhispers: boolean (optional) - Set to true to allow the player to receive whispers, false to block whispers. If no value is provided, it will toggle the current setting. + +### Example Usage +This example demonstrates how to toggle the acceptance of whispers for a player based on their level: + +```typescript +const CONFIG_WHISPER_LEVEL_THRESHOLD = 10; + +const onLogin: player_event_on_login = (event: number, player: Player) => { + const playerLevel = player.GetLevel(); + + if (playerLevel < CONFIG_WHISPER_LEVEL_THRESHOLD) { + // Disable whispers for players below the level threshold + player.SetAcceptWhispers(false); + player.SendBroadcastMessage(`You are currently not accepting whispers until you reach level ${CONFIG_WHISPER_LEVEL_THRESHOLD}.`); + } else { + // Enable whispers for players at or above the level threshold + player.SetAcceptWhispers(true); + player.SendBroadcastMessage("You are now accepting whispers from other players."); + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => onLogin(...args)); +``` + +In this example: +1. We define a constant `CONFIG_WHISPER_LEVEL_THRESHOLD` to set the minimum level required for a player to accept whispers. +2. We register the `PLAYER_EVENT_ON_LOGIN` event to execute the `onLogin` function whenever a player logs in. +3. Inside the `onLogin` function, we retrieve the player's level using `player.GetLevel()`. +4. We check if the player's level is below the `CONFIG_WHISPER_LEVEL_THRESHOLD`. + - If the level is below the threshold, we disable whispers for the player using `player.SetAcceptWhispers(false)` and send them a broadcast message informing them about the level requirement. + - If the level is at or above the threshold, we enable whispers for the player using `player.SetAcceptWhispers(true)` and send them a broadcast message indicating that they are now accepting whispers. + +This script ensures that players below a certain level threshold do not receive whispers, while players at or above the threshold can receive whispers from other players. The acceptance of whispers is automatically toggled based on the player's level when they log in. + +## SetAchievement +This method allows you to grant an achievement to a player by using the achievement ID. Achievements can be found in the `achievement_reward` table in the world database. For more information about achievements, you can refer to the AzerothCore wiki: https://www.azerothcore.org/wiki/achievement_reward + +### Parameters +* achievementId: number - The ID of the achievement to grant to the player. + +### Example Usage +In this example, we will grant the player the "Jenkins" achievement (ID: 1038) when they kill a specific creature. + +```typescript +const JENKINS_ACHIEVEMENT_ID = 1038; +const LEROY_JENKINS_CREATURE_ID = 123456; + +const onCreatureKill: creature_event_on_killed = (event: number, creature: Creature, killer: Unit) => { + if (creature.GetEntry() === LEROY_JENKINS_CREATURE_ID && killer.IsPlayer()) { + const player = killer.ToPlayer(); + if (!player.HasAchieved(JENKINS_ACHIEVEMENT_ID)) { + player.SetAchievement(JENKINS_ACHIEVEMENT_ID); + player.SendBroadcastMessage("You have earned the 'Jenkins' achievement!"); + } + } +}; + +RegisterCreatureEvent(LEROY_JENKINS_CREATURE_ID, CreatureEvents.CREATURE_EVENT_ON_KILLED, (...args) => onCreatureKill(...args)); +``` + +In this script: +1. We define constants for the "Jenkins" achievement ID and the creature ID for "Leroy Jenkins". +2. We register a creature event handler for the `CREATURE_EVENT_ON_KILLED` event. +3. When a creature is killed, we check if the killed creature is "Leroy Jenkins" and if the killer is a player. +4. If the conditions are met, we convert the `killer` object to a `Player` object using `ToPlayer()`. +5. We check if the player has already earned the "Jenkins" achievement using `HasAchieved()`. +6. If the player hasn't earned the achievement yet, we grant it to them using `SetAchievement()`. +7. Finally, we send a broadcast message to the player informing them that they have earned the achievement. + +This script demonstrates how to grant an achievement to a player based on a specific condition, such as killing a particular creature. You can adapt this script to grant achievements based on various other conditions or criteria. + +## SetArenaPoints +Sets the player's Arena Points to the specified amount. Arena Points are used as a currency to purchase items from Arena Vendors. This method allows you to directly set the player's Arena Points to a desired value. + +### Parameters +* arenaPoints: number - The amount of Arena Points to set for the player. + +### Example Usage +Here's an example of how to use the `SetArenaPoints` method to reward players with Arena Points based on their performance in a custom arena event: + +```typescript +const ARENA_EVENT_ID = 1; +const ARENA_POINTS_REWARD = 100; + +const onArenaFinish: player_event_on_arena_finish = (event: number, player: Player, arenaType: number, isWinner: boolean) => { + if (arenaType === ARENA_EVENT_ID) { + if (isWinner) { + const currentArenaPoints = player.GetArenaPoints(); + const newArenaPoints = currentArenaPoints + ARENA_POINTS_REWARD; + player.SetArenaPoints(newArenaPoints); + player.SendBroadcastMessage(`Congratulations! You have been awarded ${ARENA_POINTS_REWARD} Arena Points for winning the event.`); + } else { + player.SendBroadcastMessage("Better luck next time! Keep practicing to earn Arena Points."); + } + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_ARENA_FINISH, (...args) => onArenaFinish(...args)); +``` + +In this example: +1. We define constants for the custom arena event ID (`ARENA_EVENT_ID`) and the amount of Arena Points to reward (`ARENA_POINTS_REWARD`). +2. We register a player event handler for the `PLAYER_EVENT_ON_ARENA_FINISH` event using `RegisterPlayerEvent`. +3. Inside the event handler, we check if the arena type matches our custom arena event ID. +4. If the player is the winner (`isWinner` is true), we retrieve their current Arena Points using `GetArenaPoints()`. +5. We calculate the new Arena Points by adding the reward amount to the current points. +6. We use the `SetArenaPoints` method to set the player's Arena Points to the new value. +7. We send a broadcast message to the player informing them about the Arena Points reward. +8. If the player is not the winner, we send a different message encouraging them to keep practicing. + +This example demonstrates how you can use the `SetArenaPoints` method in combination with other player events and methods to create a custom arena event that rewards players with Arena Points based on their performance. + +Note: Make sure to replace `ARENA_EVENT_ID` and `ARENA_POINTS_REWARD` with appropriate values based on your specific arena event and reward system. + +## SetAtLoginFlag +Sets a flag on the player that triggers an action upon their next login. These flags can be used to grant items, run scripts, or perform other actions when the player logs in. + +### Parameters +* flag: number - The login flag to set on the player. The available flags are: + * 0 - None + * 1 - Change Race + * 2 - Rename + * 3 - Customize (Paid name change, appearance change, or race change) + * 4 - Reset Spells + * 5 - Reset Talents + * 6 - Restore Delete + * 16 - Refer-A-Friend + +### Example Usage +This example listens for the `PLAYER_EVENT_ON_KILL` event and checks if the victim is a rare spawn. If so, it sets a login flag on the player to grant them a special item the next time they log in. + +```typescript +const RARE_SPAWN_ENTRY = 123456; +const SPECIAL_ITEM_ENTRY = 654321; + +const OnPlayerKill: player_event_on_kill = (event: number, player: Player, victim: Unit) => { + if (victim.GetEntry() == RARE_SPAWN_ENTRY) { + let hasItem = false; + for (let i = 0; i < player.GetItemCount(); i++) { + let item = player.GetItemByPos(255, i); + if (item && item.GetEntry() == SPECIAL_ITEM_ENTRY) { + hasItem = true; + break; + } + } + + if (!hasItem) { + player.SetAtLoginFlag(1); + ChatHandler.SendMessageToPlayer(player, "You have been granted a special item for slaying the rare spawn. It will be in your mailbox the next time you log in."); + } + } +} + +const OnLogin: player_event_on_login = (event: number, player: Player) => { + if (player.HasAtLoginFlag(1)) { + player.RemoveAtLoginFlag(1); + MailDraft("Rare Spawn Reward", "Congratulations on slaying the rare spawn! Please accept this special item as a reward.") + .AddItem(SPECIAL_ITEM_ENTRY) + .SendMailTo(player, MailStationery.MAIL_STATIONERY_GM); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_KILL, (...args) => OnPlayerKill(...args)); +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => OnLogin(...args)); +``` + +In this example, when a player kills the specified rare spawn, it checks if they already have the special item. If not, it sets the login flag `1` on the player. + +Then, when the player logs in, it checks if they have the login flag `1` set. If so, it removes the flag and sends them the special item via in-game mail. + +This showcases how login flags can be used to trigger actions across play sessions, such as granting rewards for accomplishments in the previous session. + +## SetBindPoint +Sets the player's home location to the specified coordinates, map, and area. This is the location where the player will respawn after death. + +### Parameters +* x: number - The X coordinate of the bind location +* y: number - The Y coordinate of the bind location +* z: number - The Z coordinate of the bind location +* mapId: number - The map ID of the bind location +* areaId: number - The area ID of the bind location + +### Example Usage +Set the player's bind point to a custom location based on their class: +```typescript +const CLASS_BIND_LOCATIONS = { + [Classes.CLASS_WARRIOR]: { x: -8799.14, y: 328.206, z: 102.673, mapId: 0, areaId: 1519 }, + [Classes.CLASS_PALADIN]: { x: -8519.64, y: 852.499, z: 109.61, mapId: 0, areaId: 1537 }, + [Classes.CLASS_HUNTER]: { x: -5062.26, y: -1261.89, z: 510.475, mapId: 1, areaId: 400 }, + [Classes.CLASS_ROGUE]: { x: -8753.11, y: 367.625, z: 101.056, mapId: 0, areaId: 1519 }, + [Classes.CLASS_PRIEST]: { x: -8517.21, y: 848.877, z: 109.61, mapId: 0, areaId: 1537 }, + [Classes.CLASS_DEATH_KNIGHT]: { x: 2280.12, y: -5275.32, z: 82.1443, mapId: 609, areaId: 4298 }, + [Classes.CLASS_SHAMAN]: { x: -2916.61, y: -257.138, z: 53.0241, mapId: 1, areaId: 406 }, + [Classes.CLASS_MAGE]: { x: -9018.52, y: 874.28, z: 129.682, mapId: 0, areaId: 1519 }, + [Classes.CLASS_WARLOCK]: { x: -8960.51, y: 1027.67, z: 101.302, mapId: 0, areaId: 1519 }, + [Classes.CLASS_DRUID]: { x: 7865.78, y: -2493.64, z: 487.838, mapId: 1, areaId: 493 } +}; + +const OnFirstLogin: player_event_on_first_login = (event: number, player: Player) => { + const classBindLocation = CLASS_BIND_LOCATIONS[player.GetClass()]; + + if (classBindLocation) { + const { x, y, z, mapId, areaId } = classBindLocation; + player.SetBindPoint(x, y, z, mapId, areaId); + player.SendBroadcastMessage(`Your home location has been set to the ${player.GetClassAsString()} bind point.`); + } else { + player.SendBroadcastMessage("No class-specific bind point found. Using default bind location."); + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_FIRST_LOGIN, (...args) => OnFirstLogin(...args)); +``` + +In this example, we define a `CLASS_BIND_LOCATIONS` object that maps each class to a specific bind location. When a player logs in for the first time, we retrieve their class using `player.GetClass()` and check if a corresponding bind location exists in the `CLASS_BIND_LOCATIONS` object. + +If a class-specific bind location is found, we extract the coordinates, map ID, and area ID from the object and pass them to `player.SetBindPoint()` to set the player's home location. We also send a broadcast message to the player informing them that their home location has been set to the class-specific bind point. + +If no class-specific bind location is found, we send a message to the player indicating that the default bind location will be used. + +By using this script, players of different classes will have their bind points automatically set to predefined locations based on their class when they log in for the first time. + +## SetCoinage +This method sets the player's total amount of money to the specified amount in copper. The amount can be a combination of gold, silver, and copper, but the method takes the total amount in copper as the argument. + +### Parameters +* copperAmt: number - The total amount of money in copper to set for the player. + +### Example Usage +In this example, we will create a script that rewards players with a specific amount of money based on their level when they complete a particular quest. The reward amount will be calculated based on the player's level and the base reward amount. + +```typescript +const QUEST_ENTRY = 1234; // Replace with the actual quest entry ID +const BASE_REWARD_COPPER = 10000; // 1 gold + +const QuestComplete: player_event_on_quest_complete = (event: number, player: Player, quest: number) => { + if (quest === QUEST_ENTRY) { + const playerLevel = player.GetLevel(); + const rewardMultiplier = playerLevel * 0.5; // Adjust the multiplier as needed + const totalReward = BASE_REWARD_COPPER * rewardMultiplier; + + const currentCoinage = player.GetCoinage(); + const newCoinage = currentCoinage + totalReward; + + player.SetCoinage(newCoinage); + + player.SendBroadcastMessage(`You have been rewarded with ${totalReward / 100} silver for completing the quest at level ${playerLevel}!`); + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_QUEST_COMPLETE, (...args) => QuestComplete(...args)); +``` + +In this script: +1. We define the `QUEST_ENTRY` constant with the entry ID of the quest we want to track and the `BASE_REWARD_COPPER` constant with the base reward amount in copper (1 gold = 10000 copper). + +2. We create a function called `QuestComplete` that will be triggered when a player completes a quest. + +3. Inside the function, we check if the completed quest's entry ID matches the `QUEST_ENTRY` we are interested in. + +4. If there is a match, we calculate the reward amount based on the player's level. In this example, we multiply the player's level by a reward multiplier (0.5) and then multiply the result by the base reward amount. Adjust the multiplier as needed to balance the rewards. + +5. We retrieve the player's current coinage using `player.GetCoinage()` and add the calculated reward amount to it to determine the new coinage. + +6. We use `player.SetCoinage(newCoinage)` to set the player's money to the new coinage amount. + +7. Finally, we send a broadcast message to the player, informing them about the reward they received for completing the quest at their current level. + +8. We register the `QuestComplete` function to be triggered whenever a player completes a quest using `RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_QUEST_COMPLETE, (...args) => QuestComplete(...args))`. + +This script demonstrates how to use the `SetCoinage` method to modify a player's money based on quest completion and their level, providing a more dynamic and level-based reward system. + +## SetDrunkValue +Set the player's intoxication level to a specific value. The drunk value is used to determine the visual effects and behavior changes associated with being intoxicated in the game. + +### Parameters +* drunkValue: number - The desired intoxication level for the player. Valid range is from 0 to 100. + +### Example Usage +This example demonstrates how to create a custom item that, when used by the player, will set their intoxication level based on the item's quality. + +```typescript +const ITEM_ENTRY = 123456; + +const ItemUse: player_event_on_item_use = (event: number, player: Player, item: Item, target: GameObject | Item | Player | Unit) => { + if (item.GetEntry() === ITEM_ENTRY) { + let quality = item.GetQuality(); + let drunkValue = 0; + + switch (quality) { + case 0: // Poor + drunkValue = 10; + break; + case 1: // Common + drunkValue = 30; + break; + case 2: // Uncommon + drunkValue = 50; + break; + case 3: // Rare + drunkValue = 70; + break; + case 4: // Epic + drunkValue = 90; + break; + case 5: // Legendary + drunkValue = 100; + break; + } + + player.SetDrunkValue(drunkValue); + player.SendBroadcastMessage(`You consume the ${item.GetName()} and feel your intoxication level rise.`); + + if (drunkValue >= 50) { + player.CastSpell(player, 32959, true); // Cast the "Intoxicated" visual effect on the player + } + + player.DestroyItemCount(ITEM_ENTRY, 1, true); // Remove one item from the player's inventory + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_ITEM_USE, (...args) => ItemUse(...args)); +``` + +In this example: +1. We define a custom item entry (`ITEM_ENTRY`) that will trigger the script when used by the player. +2. In the `ItemUse` event handler, we check if the used item matches our custom item entry. +3. We determine the drunk value based on the item's quality, with higher quality items resulting in higher intoxication levels. +4. We set the player's intoxication level using `player.SetDrunkValue(drunkValue)`. +5. We send a broadcast message to the player, informing them about the effect of consuming the item. +6. If the drunk value is greater than or equal to 50, we cast the "Intoxicated" visual effect on the player using `player.CastSpell()`. +7. Finally, we remove one instance of the custom item from the player's inventory using `player.DestroyItemCount()`. + +This script showcases how the `SetDrunkValue` method can be used in combination with other player methods and game events to create a custom item with intoxication effects. + +## SetFFA +This method allows you to toggle the FFA (Free-for-All) flag for a player. When the FFA flag is enabled, the player can attack and be attacked by other players regardless of their faction or party status. This is commonly used in custom PvP scenarios or events. + +### Parameters +* applyFFA (optional): boolean - Determines whether to apply or remove the FFA flag. If set to 'true', the FFA flag will be enabled. If set to 'false', the FFA flag will be disabled. If not provided, the default value is 'true'. + +### Example Usage: +Create a custom PvP event where players can toggle their FFA status. +```typescript +const FFA_ZONE_ID = 1234; // Replace with the desired zone ID + +const OnEnterWorld: player_event_on_enter_world = (event: number, player: Player) => { + // Check if the player is in the designated FFA zone + if (player.GetZoneId() === FFA_ZONE_ID) { + // Enable FFA for the player + player.SetFFA(true); + player.SendBroadcastMessage("You have entered the FFA zone. Be prepared for combat!"); + } +}; + +const OnUpdateZone: player_event_on_update_zone = (event: number, player: Player, newZone: number, newArea: number) => { + // Check if the player is leaving the FFA zone + if (player.GetZoneId() !== FFA_ZONE_ID && player.HasFlag(PlayerFlags.FREE_FOR_ALL_PVP)) { + // Disable FFA for the player + player.SetFFA(false); + player.SendBroadcastMessage("You have left the FFA zone. PvP restrictions are now in effect."); + } +}; + +const OnChat: player_event_on_chat = (event: number, player: Player, msg: string, type: number, lang: number) => { + // Check if the player types the command to toggle FFA + if (msg === "!ffa") { + // Toggle the player's FFA status + const isFFA = player.HasFlag(PlayerFlags.FREE_FOR_ALL_PVP); + player.SetFFA(!isFFA); + + if (!isFFA) { + player.SendBroadcastMessage("FFA mode enabled. You can now attack and be attacked by other players!"); + } else { + player.SendBroadcastMessage("FFA mode disabled. PvP restrictions are now in effect."); + } + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_ENTER_WORLD, (...args) => OnEnterWorld(...args)); +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_UPDATE_ZONE, (...args) => OnUpdateZone(...args)); +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_CHAT, (...args) => OnChat(...args)); +``` +In this example: +1. When a player enters the designated FFA zone (identified by `FFA_ZONE_ID`), their FFA flag is automatically enabled using `player.SetFFA(true)`. They receive a message indicating that they have entered the FFA zone. +2. When a player leaves the FFA zone, their FFA flag is automatically disabled using `player.SetFFA(false)`. They receive a message indicating that they have left the FFA zone and PvP restrictions are back in effect. +3. Players can manually toggle their FFA status by typing the command "!ffa" in the chat. The script checks for this command in the `OnChat` event and toggles the player's FFA flag accordingly using `player.SetFFA(!isFFA)`. The player receives a message confirming the change in their FFA status. + +This script provides a dynamic FFA system where players can engage in unrestricted PvP combat within designated zones or by manually toggling their FFA status. + +## SetFactionForRace +Sets the player's faction standing to match that of the specified race. This can be useful for changing a player's faction standing to match a different race, such as changing a Blood Elf to have the same faction standing as an Orc. + +### Parameters +* raceId: number - The ID of the race to set the faction standing to. You can find race IDs in the DBC files or in the [TC/AC Wiki - Races](https://www.azerothcore.org/wiki/race). + +### Example Usage +Change a player's faction standing to match a different race when they equip a specific item. +```typescript +const RACE_BLOODELF = 10; +const RACE_ORC = 2; +const ITEM_ENTRY_FACTION_CHANGER = 123456; + +const OnEquipItem: player_event_on_equip_item = (event: number, player: Player, item: Item) => { + if (item.GetEntry() === ITEM_ENTRY_FACTION_CHANGER) { + if (player.GetRace() === RACE_BLOODELF) { + player.SetFactionForRace(RACE_ORC); + player.SendBroadcastMessage("Your faction standing has been changed to match that of an Orc!"); + } else { + player.SendBroadcastMessage("This item can only be used by Blood Elves."); + player.RemoveItem(item.GetEntry(), 1); + } + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_EQUIP_ITEM, (...args) => OnEquipItem(...args)); +``` + +In this example, when a player equips an item with the entry `ITEM_ENTRY_FACTION_CHANGER`, the script checks if the player is a Blood Elf. If they are, it changes their faction standing to match that of an Orc using `SetFactionForRace(RACE_ORC)` and sends them a message indicating the change. If the player is not a Blood Elf, it sends them a message saying the item can only be used by Blood Elves and removes the item from their inventory. + +This script showcases how `SetFactionForRace` can be used in combination with other player methods and events to create interesting gameplay mechanics and interactions based on a player's race and faction standing. + +## SetFreeTalentPoints +This method sets the player's free talent points to the specified amount for their current talent specialization. This allows the player to reallocate their talent points and customize their character build. + +### Parameters +* talentPointAmt: number - The number of free talent points to set for the player's current specialization. + +### Example Usage +In this example, we create a script that rewards players with bonus talent points based on their level when they complete a specific quest. The script listens for the `PLAYER_EVENT_ON_QUEST_COMPLETE` event and checks if the completed quest ID matches the desired quest. If the player's level is above a certain threshold, they are granted additional talent points using the `SetFreeTalentPoints` method. + +```typescript +const QUEST_ID = 12345; // Replace with the desired quest ID +const LEVEL_THRESHOLD = 60; // Minimum level required for bonus talent points +const BONUS_TALENT_POINTS = 5; // Number of bonus talent points to grant + +const onQuestComplete: player_event_on_quest_complete = (event: number, player: Player, quest: Quest) => { + if (quest.GetId() === QUEST_ID) { + const playerLevel = player.GetLevel(); + if (playerLevel >= LEVEL_THRESHOLD) { + const currentTalentPoints = player.GetFreeTalentPoints(); + const newTalentPoints = currentTalentPoints + BONUS_TALENT_POINTS; + player.SetFreeTalentPoints(newTalentPoints); + player.SendBroadcastMessage(`You have been granted ${BONUS_TALENT_POINTS} bonus talent points for completing the quest at level ${playerLevel}!`); + } else { + player.SendBroadcastMessage(`Complete the quest at level ${LEVEL_THRESHOLD} or higher to receive bonus talent points.`); + } + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_QUEST_COMPLETE, (...args) => onQuestComplete(...args)); +``` + +In this script: +1. We define constants for the quest ID (`QUEST_ID`), the minimum level required for bonus talent points (`LEVEL_THRESHOLD`), and the number of bonus talent points to grant (`BONUS_TALENT_POINTS`). +2. We register the `onQuestComplete` function to handle the `PLAYER_EVENT_ON_QUEST_COMPLETE` event. +3. When a player completes a quest, the `onQuestComplete` function is triggered. +4. We check if the completed quest ID matches the desired quest ID (`QUEST_ID`). +5. If the quest ID matches, we check if the player's level is greater than or equal to the `LEVEL_THRESHOLD`. +6. If the player meets the level requirement, we retrieve their current free talent points using `GetFreeTalentPoints()`. +7. We calculate the new number of talent points by adding the `BONUS_TALENT_POINTS` to the current talent points. +8. We set the player's free talent points to the new value using `SetFreeTalentPoints(newTalentPoints)`. +9. We send a broadcast message to the player informing them about the bonus talent points they received. +10. If the player does not meet the level requirement, we send a broadcast message informing them about the level requirement to receive bonus talent points. + +This script demonstrates how the `SetFreeTalentPoints` method can be used to dynamically adjust a player's talent points based on certain conditions or achievements, such as completing a specific quest at a certain level. + +## SetGMChat +Toggle the visibility of the GM tag for the player. When enabled, the player's chat messages will have the "Blizz" tag prepended to them, indicating they are a GM. This is useful for identifying GM characters from normal players. + +### Parameters +* on?: boolean - Optional parameter to enable or disable GM chat tag. If not provided, the state will be toggled. + +### Example Usage +This example demonstrates how to enable or disable the GM chat tag based on the player's GM rank. It assumes there is a custom GMRank command that allows changing the player's GM rank. + +```typescript +const GMRankCommand: player_event_on_command = (event: number, player: Player, command: string, args: string[]) => { + const rank = parseInt(args[0]); + + if (isNaN(rank) || rank < 0 || rank > 3) { + player.SendBroadcastMessage("Invalid GM rank. Usage: .gmrank <0-3>"); + return; + } + + player.SetGMRank(rank); + + if (rank > 0) { + player.SetGMChat(true); + player.SendBroadcastMessage(`GM chat tag enabled. Your rank is now ${rank}.`); + } else { + player.SetGMChat(false); + player.SendBroadcastMessage("GM chat tag disabled. You are now a normal player."); + } + + player.SaveToDB(); +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_COMMAND, (...args) => GMRankCommand(...args), "gmrank"); +``` + +In this example: +1. The script listens for the "gmrank" command using the `PLAYER_EVENT_ON_COMMAND` event. +2. It extracts the rank argument from the command and validates it. If the rank is invalid, an error message is sent to the player. +3. If the rank is valid, it sets the player's GM rank using `player.SetGMRank(rank)`. +4. If the rank is greater than 0, it enables the GM chat tag using `player.SetGMChat(true)` and sends a confirmation message to the player. +5. If the rank is 0, it disables the GM chat tag using `player.SetGMChat(false)` and sends a message to the player indicating they are now a normal player. +6. Finally, it saves the player's changes to the database using `player.SaveToDB()`. + +This script allows GMs to easily toggle their GM chat tag based on their assigned rank, providing clear identification in chat channels. + +## SetGMVisible +Toggles the visibility of the player to other players and creatures in the world. When GM visibility is off, the player will be invisible to other players and creatures, unless they are in the same group or raid. + +### Parameters +gmVisible?: boolean - (Optional) Sets the player's visibility on or off. If not provided, it will toggle the current state. +- `true`: The player becomes visible to other players and creatures. +- `false`: The player becomes invisible to other players and creatures. + +### Example Usage +Here's an example of how to use the `SetGMVisible` method to create a simple GM invisibility toggle command: + +```typescript +// GM command to toggle invisibility +const GMInvisibilityCommand: player_event_on_command = (event: number, player: Player, command: string) => { + if (command === "gminvis") { + if (!player.IsGM()) { + player.SendBroadcastMessage("You do not have permission to use this command."); + return; + } + + player.SetGMVisible(!player.IsGMVisible()); + + if (player.IsGMVisible()) { + player.SendBroadcastMessage("GM invisibility disabled. You are now visible to other players."); + } else { + player.SendBroadcastMessage("GM invisibility enabled. You are now invisible to other players."); + } + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_COMMAND, (...args) => GMInvisibilityCommand(...args)); +``` + +In this example, we create a custom GM command "gminvis" that toggles the player's GM visibility when executed. Here's how it works: + +1. We check if the command entered by the player is "gminvis". +2. We verify if the player has GM permissions using the `IsGM()` method. If not, we send an error message and return. +3. We call the `SetGMVisible` method, passing the opposite of the player's current visibility state using `!player.IsGMVisible()`. This toggles the visibility. +4. Depending on the new visibility state, we send a corresponding message to the player using `SendBroadcastMessage` to confirm the action. + +With this script, when a GM player types the command "gminvis", their visibility will be toggled on or off, and they will receive a message indicating the current state of their invisibility. + +Note: Make sure to grant the appropriate GM permissions to the desired player accounts for this command to work as intended. + +## SetGameMaster +This method allows you to toggle the player's GM mode on or off. When a player is in GM mode, they have access to special commands and abilities that are not available to regular players. This can be useful for testing and debugging purposes, or for administering the game. + +### Parameters +* setGmMode: boolean (optional) - If set to true, the player will be put into GM mode. If set to false, the player will be taken out of GM mode. If not specified, the player's GM mode will be toggled (if currently in GM mode, it will be turned off, and vice versa). + +### Example Usage +Here's an example of how you might use the SetGameMaster method in a script: + +```typescript +const OnPlayerChat: player_event_on_chat = (event: number, player: Player, msg: string, Type: number, lang: Language): void => { + if (msg === '!gm') { + if (player.GetGMRank() >= 3) { // Check if the player has a GM rank of 3 or higher + player.SetGameMaster(); // Toggle the player's GM mode + if (player.IsGameMaster()) { + player.SendBroadcastMessage('You are now a Game Master.'); + player.LearnSpell(27683); // Teach the player the "GM" spell + player.LearnSpell(1908); // Teach the player the "Uber Heal Over Time" spell + player.SetMaxHealth(player.GetMaxHealth() * 10); // Increase the player's max health by 10 times + player.SetMaxPower(player.GetPowerType(), player.GetMaxPower(player.GetPowerType()) * 10); // Increase the player's max power by 10 times + } else { + player.SendBroadcastMessage('You are no longer a Game Master.'); + player.RemoveSpell(27683); // Remove the "GM" spell from the player + player.RemoveSpell(1908); // Remove the "Uber Heal Over Time" spell from the player + player.SetMaxHealth(player.GetMaxHealth() / 10); // Reduce the player's max health back to normal + player.SetMaxPower(player.GetPowerType(), player.GetMaxPower(player.GetPowerType()) / 10); // Reduce the player's max power back to normal + } + } else { + player.SendBroadcastMessage('You do not have permission to use this command.'); + } + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_CHAT, (...args) => OnPlayerChat(...args)); +``` + +In this example, when a player types '!gm' in the chat, the script checks if the player has a GM rank of 3 or higher. If they do, it toggles their GM mode using the SetGameMaster method. If the player is put into GM mode, the script teaches them the "GM" and "Uber Heal Over Time" spells, and increases their max health and power by 10 times. If the player is taken out of GM mode, the script removes the spells and reduces their max health and power back to normal. If the player does not have a GM rank of 3 or higher, they are sent a message telling them they do not have permission to use the command. + +## SetGender +This method sets the gender of the player. The gender can be either male or female, represented by the following constants: +- GENDER_MALE = 0 +- GENDER_FEMALE = 1 + +### Parameters +- gender: number - The gender to set for the player. It should be either GENDER_MALE or GENDER_FEMALE. + +### Example Usage +This example demonstrates how to create a command that allows players to change their gender based on their input. + +```typescript +// Constants for gender +const GENDER_MALE = 0; +const GENDER_FEMALE = 1; + +// Function to handle the gender change command +function handleGenderChangeCommand(player: Player, args: string[]): boolean { + if (args.length === 0) { + player.SendBroadcastMessage("Usage: .changegender [male|female]"); + return false; + } + + const genderInput = args[0].toLowerCase(); + let gender: number; + + if (genderInput === "male") { + gender = GENDER_MALE; + } else if (genderInput === "female") { + gender = GENDER_FEMALE; + } else { + player.SendBroadcastMessage("Invalid gender. Please specify either 'male' or 'female'."); + return false; + } + + player.SetGender(gender); + player.SendBroadcastMessage(`Your gender has been changed to ${genderInput}.`); + return true; +} + +// Register the gender change command +RegisterPlayerCommand("changegender", "Allows you to change your character's gender.", handleGenderChangeCommand); +``` + +In this example: +1. We define constants `GENDER_MALE` and `GENDER_FEMALE` to represent the gender values. +2. We create a function `handleGenderChangeCommand` that takes the player and command arguments as parameters. +3. We check if the player provided a gender argument. If not, we send a usage message and return `false` to indicate an invalid command. +4. We convert the gender input to lowercase for case-insensitive comparison. +5. Based on the gender input, we set the `gender` variable to either `GENDER_MALE` or `GENDER_FEMALE`. If an invalid gender is provided, we send an error message and return `false`. +6. We call `player.SetGender(gender)` to set the player's gender to the specified value. +7. We send a confirmation message to the player indicating that their gender has been changed. +8. Finally, we register the "changegender" command with the `RegisterPlayerCommand` function, providing a description and the `handleGenderChangeCommand` function as the command handler. + +This example showcases how to create a custom command that allows players to change their gender using the `SetGender` method of the `Player` class. The command validates the player's input and sets the gender accordingly, providing appropriate feedback to the player. + +## SetGuildRank +This method allows you to set the guild rank of a player. The rank is specified by a number that corresponds to the rank index in the guild_rank table of the characters database. For more information about guild ranks, you can refer to the AzerothCore wiki: https://www.azerothcore.org/wiki/guild_rank + +### Parameters +- rank: number - The index of the guild rank to set for the player. + +### Example Usage +This example demonstrates how to set a player's guild rank based on their total playtime. + +```typescript +const RANK_INITIATE = 1; +const RANK_MEMBER = 2; +const RANK_VETERAN = 3; +const RANK_OFFICER = 4; +const RANK_LEADER = 5; + +const UpdateGuildRank: player_event_on_login = (event: number, player: Player) => { + const totalPlayTime = player.GetTotalPlayedTime(); + let newRank = RANK_INITIATE; + + if (totalPlayTime >= 604800) { // 7 days in seconds + newRank = RANK_MEMBER; + } + + if (totalPlayTime >= 2592000) { // 30 days in seconds + newRank = RANK_VETERAN; + } + + if (totalPlayTime >= 7776000) { // 90 days in seconds + newRank = RANK_OFFICER; + } + + if (player.GetGuildId() == 0) { + // Player is not in a guild, do nothing + return; + } + + if (player.GetGuildRank() != newRank) { + player.SetGuildRank(newRank); + player.SendBroadcastMessage(`Your guild rank has been updated to ${player.GetGuildRank()} based on your total playtime.`); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => UpdateGuildRank(...args)); +``` + +In this example: +1. We define constants for each guild rank index to improve code readability. +2. We register a player event handler for the `PLAYER_EVENT_ON_LOGIN` event. +3. When a player logs in, we retrieve their total playtime using the `GetTotalPlayedTime()` method. +4. We determine the new guild rank based on the total playtime using a series of conditional statements. +5. We check if the player is in a guild using the `GetGuildId()` method. If the player is not in a guild, we exit the function. +6. If the player's current guild rank (retrieved using `GetGuildRank()`) is different from the new rank, we update their rank using the `SetGuildRank()` method. +7. Finally, we send a message to the player informing them that their guild rank has been updated based on their total playtime. + +This script ensures that players' guild ranks are automatically updated based on their dedication and time spent playing the game, providing a sense of progression within the guild hierarchy. + +## SetHonorLastWeekStandingPos +Sets the player's honor standing position from the previous week. This method is useful for restoring a player's previous week's honor standing position, or for manually adjusting it for custom features or rewards. + +### Parameters +* standingPos: number - The standing position to set for the previous week. + +### Example Usage +In this example, we will create a script that rewards players based on their previous week's honor standing position. Players who finished in the top 10 positions will receive a special reward. + +```typescript +const REWARD_ITEM_ENTRY = 12345; // Replace with your desired item entry +const REWARD_ITEM_COUNT = 1; + +const OnLogin: player_event_on_login = (event: number, player: Player) => { + // Get the player's previous week's honor standing position + const standingPos = player.GetHonorLastWeekStandingPos(); + + // Check if the player finished in the top 10 positions + if (standingPos > 0 && standingPos <= 10) { + // Reward the player with a special item + const rewardItem = player.AddItem(REWARD_ITEM_ENTRY, REWARD_ITEM_COUNT); + + if (rewardItem) { + // Send a message to the player + player.SendBroadcastMessage(`Congratulations on finishing in the top 10 last week! You have been rewarded with a special item.`); + } else { + // If the item couldn't be added (e.g., inventory full), send an error message + player.SendBroadcastMessage(`Error: Unable to receive the reward item. Please make sure you have enough inventory space.`); + } + } + + // Set the player's previous week's honor standing position to their current position + const currentStandingPos = player.GetHonorStandingPos(); + player.SetHonorLastWeekStandingPos(currentStandingPos); +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, OnLogin); +``` + +In this script: +1. We define the reward item entry and the number of items to be given as constants. +2. We register the `OnLogin` event to trigger when a player logs in. +3. Inside the event handler, we retrieve the player's previous week's honor standing position using `GetHonorLastWeekStandingPos()`. +4. We check if the player finished in the top 10 positions (standing position greater than 0 and less than or equal to 10). +5. If the player is eligible for the reward, we add the reward item to their inventory using `AddItem()`. + - If the item is successfully added, we send a congratulatory message to the player. + - If the item couldn't be added (e.g., inventory is full), we send an error message to the player. +6. Finally, we update the player's previous week's honor standing position to their current position using `SetHonorLastWeekStandingPos()`. + +This script ensures that players who performed well in the previous week's honor standings receive a special reward upon logging in. It also updates their previous week's standing position to their current position, so the reward is only given once per week. + +## SetHonorPoints +This method allows you to set the player's honor points to a specific value. Honor points are a currency earned through PvP activities and can be used to purchase various rewards from the Honor vendor. + +### Parameters +* honorPoints: number - The amount of honor points to set for the player. + +### Example Usage +In this example, we'll create a script that rewards players with bonus honor points based on their lifetime honorable kills when they log in. + +```typescript +const HONOR_POINTS_PER_KILL = 10; +const HONOR_POINTS_BONUS_THRESHOLD = 100; +const HONOR_POINTS_BONUS = 1000; + +const OnLogin: player_event_on_login = (event: number, player: Player) => { + // Get the player's lifetime honorable kills + const lifetimeHonorableKills = player.GetUInt32Value(PlayerFields.PLAYER_FIELD_LIFETIME_HONORABLE_KILLS); + + // Calculate the bonus honor points based on lifetime kills + const bonusHonorPoints = lifetimeHonorableKills * HONOR_POINTS_PER_KILL; + + // Get the player's current honor points + const currentHonorPoints = player.GetHonorPoints(); + + // Set the player's new honor points + player.SetHonorPoints(currentHonorPoints + bonusHonorPoints); + + // Send a message to the player about their bonus honor points + player.SendBroadcastMessage(`You have been awarded ${bonusHonorPoints} bonus honor points for your lifetime honorable kills!`); + + // If the player's lifetime kills exceed the bonus threshold, give them an additional bonus + if (lifetimeHonorableKills >= HONOR_POINTS_BONUS_THRESHOLD) { + player.SetHonorPoints(currentHonorPoints + bonusHonorPoints + HONOR_POINTS_BONUS); + player.SendBroadcastMessage(`You have also been awarded an additional ${HONOR_POINTS_BONUS} honor points for reaching ${HONOR_POINTS_BONUS_THRESHOLD} lifetime honorable kills!`); + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => OnLogin(...args)); +``` + +In this script: +1. We define constants for the number of honor points awarded per lifetime kill, the bonus threshold, and the bonus amount. +2. When a player logs in, we retrieve their lifetime honorable kills using `GetUInt32Value(PlayerFields.PLAYER_FIELD_LIFETIME_HONORABLE_KILLS)`. +3. We calculate the bonus honor points by multiplying the lifetime kills by the honor points per kill. +4. We get the player's current honor points using `GetHonorPoints()`. +5. We set the player's new honor points using `SetHonorPoints()`, adding the bonus honor points to their current honor points. +6. We send a message to the player informing them about their bonus honor points. +7. If the player's lifetime kills exceed the bonus threshold, we give them an additional bonus using `SetHonorPoints()` and send another message. + +This script encourages players to engage in PvP activities by rewarding them with bonus honor points based on their lifetime honorable kills, with an additional bonus for reaching a certain threshold. + +## SetHonorStoredKills +This method sets the player's stored honor kills, which can be used for various purposes such as rewards, achievements, or rankings. The kills can be set as honorable or dishonorable based on the second parameter. + +### Parameters +* kills: number - The number of kills to set. +* honorable: boolean (optional) - Determines whether the kills are honorable or dishonorable. If not provided, the default value is 'true'. + +### Example Usage +In this example, we'll create a script that rewards players with bonus honor kills based on their total playtime. The script will be triggered when a player logs in. + +```typescript +const BONUS_HONOR_KILLS_PER_HOUR = 5; + +const OnLogin: player_event_on_login = (event: number, player: Player) => { + // Get the player's total playtime in seconds + const totalPlaytime = player.GetTotalPlayedTime(); + + // Convert playtime to hours + const playtimeHours = Math.floor(totalPlaytime / 3600); + + // Calculate bonus honor kills based on playtime + const bonusHonorKills = playtimeHours * BONUS_HONOR_KILLS_PER_HOUR; + + // Get the player's current honor kills + const currentHonorKills = player.GetHonorStoredKills(true); + + // Set the new total honor kills + const newTotalHonorKills = currentHonorKills + bonusHonorKills; + player.SetHonorStoredKills(newTotalHonorKills, true); + + // Send a message to the player + player.SendBroadcastMessage(`You have been awarded ${bonusHonorKills} bonus honor kills based on your total playtime!`); + player.SendBroadcastMessage(`Your new total honorable kills: ${newTotalHonorKills}`); +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => OnLogin(...args)); +``` + +In this script: +1. We define a constant `BONUS_HONOR_KILLS_PER_HOUR` to set the number of bonus honor kills awarded per hour of playtime. +2. We create an event handler function `OnLogin` that triggers when a player logs in. +3. We retrieve the player's total playtime in seconds using `GetTotalPlayedTime()` and convert it to hours. +4. We calculate the bonus honor kills by multiplying the playtime hours by the `BONUS_HONOR_KILLS_PER_HOUR`. +5. We get the player's current honorable kills using `GetHonorStoredKills(true)`. +6. We calculate the new total honor kills by adding the bonus honor kills to the current honor kills. +7. We set the new total honorable kills using `SetHonorStoredKills(newTotalHonorKills, true)`. +8. Finally, we send a broadcast message to the player informing them about the bonus honor kills and their new total honorable kills. + +This script encourages players to spend more time playing the game by rewarding them with bonus honor kills based on their playtime. + +## SetKnownTitle +This method adds a specified title to the player's list of known titles. These titles can be referenced in the CharTitles DBC file. For more information about titles, you can find more details here: https://www.azerothcore.org/wiki/dbc_chartitles + +### Parameters +- titleId: number - The ID of the title from the CharTitles DBC file. + +### Example Usage +In this example, we'll create a script that rewards players with a special title when they complete a specific quest. We'll assume the quest ID is 12345 and the title ID is 123. + +```typescript +const QUEST_ID = 12345; +const TITLE_ID = 123; + +const OnQuestComplete: player_event_on_quest_complete = (event: number, player: Player, quest: number) => { + if (quest === QUEST_ID) { + if (!player.HasTitle(TITLE_ID)) { + player.SetKnownTitle(TITLE_ID); + player.SendNotification("Congratulations! You have earned the title for completing this quest."); + } else { + player.SendNotification("You have already earned this title."); + } + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_QUEST_COMPLETE, (...args) => OnQuestComplete(...args)); +``` + +In this script: +1. We define constants for the quest ID and title ID for better readability and maintainability. +2. We create a function called `OnQuestComplete` that will be triggered when a player completes a quest. +3. Inside the function, we check if the completed quest ID matches the one we're interested in (12345). +4. If it does, we then check if the player already has the title using the `HasTitle` method. +5. If the player doesn't have the title, we add it to their list of known titles using `SetKnownTitle` and send them a congratulatory notification. +6. If the player already has the title, we send them a different notification letting them know they've already earned it. +7. Finally, we register the `OnQuestComplete` function to be triggered whenever a player completes a quest using `RegisterPlayerEvent`. + +This script demonstrates how to use the `SetKnownTitle` method in a practical scenario, rewarding players with a special title for completing a specific quest. It also showcases additional methods like `HasTitle` and `SendNotification` to enhance the functionality and user experience. + +## SetLifetimeKills +Sets the player's total number of lifetime honorable kills to the specified value. This can be useful for custom PvP systems or achievements that track a player's PvP progress over time. + +### Parameters +* honorableKills: number - The number of lifetime honorable kills to set for the player. + +### Example Usage +In this example, we'll create a custom PvP system where players can earn special titles based on their lifetime honorable kills. When a player reaches certain milestones, they'll receive a title and a bonus item. + +```typescript +const KILLS_NOVICE = 50; +const KILLS_ADEPT = 100; +const KILLS_EXPERT = 250; +const KILLS_MASTER = 500; +const KILLS_GRANDMASTER = 1000; + +const TITLE_NOVICE = 1; +const TITLE_ADEPT = 2; +const TITLE_EXPERT = 3; +const TITLE_MASTER = 4; +const TITLE_GRANDMASTER = 5; + +const BONUS_ITEM_ENTRY = 12345; + +const CheckPvPProgress: player_event_on_kill_player = (event: number, killer: Player, killed: Player) => { + const lifetimeKills = killer.GetLifetimeKills(); + + if (lifetimeKills >= KILLS_GRANDMASTER && !killer.HasTitle(TITLE_GRANDMASTER)) { + killer.SetLifetimeKills(KILLS_GRANDMASTER); + killer.SetKnownTitle(TITLE_GRANDMASTER); + killer.AddItem(BONUS_ITEM_ENTRY, 1); + killer.SendBroadcastMessage("You have earned the title of PvP Grandmaster!"); + } else if (lifetimeKills >= KILLS_MASTER && !killer.HasTitle(TITLE_MASTER)) { + killer.SetLifetimeKills(KILLS_MASTER); + killer.SetKnownTitle(TITLE_MASTER); + killer.AddItem(BONUS_ITEM_ENTRY, 1); + killer.SendBroadcastMessage("You have earned the title of PvP Master!"); + } else if (lifetimeKills >= KILLS_EXPERT && !killer.HasTitle(TITLE_EXPERT)) { + killer.SetLifetimeKills(KILLS_EXPERT); + killer.SetKnownTitle(TITLE_EXPERT); + killer.AddItem(BONUS_ITEM_ENTRY, 1); + killer.SendBroadcastMessage("You have earned the title of PvP Expert!"); + } else if (lifetimeKills >= KILLS_ADEPT && !killer.HasTitle(TITLE_ADEPT)) { + killer.SetLifetimeKills(KILLS_ADEPT); + killer.SetKnownTitle(TITLE_ADEPT); + killer.AddItem(BONUS_ITEM_ENTRY, 1); + killer.SendBroadcastMessage("You have earned the title of PvP Adept!"); + } else if (lifetimeKills >= KILLS_NOVICE && !killer.HasTitle(TITLE_NOVICE)) { + killer.SetLifetimeKills(KILLS_NOVICE); + killer.SetKnownTitle(TITLE_NOVICE); + killer.AddItem(BONUS_ITEM_ENTRY, 1); + killer.SendBroadcastMessage("You have earned the title of PvP Novice!"); + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_KILL_PLAYER, (...args) => CheckPvPProgress(...args)); +``` + +In this script, we define constants for the number of kills required for each title and the corresponding title IDs. When a player kills another player, we check their lifetime honorable kills and grant them the appropriate title and bonus item if they've reached a new milestone. We use `SetLifetimeKills()` to ensure that their kill count is set to the exact milestone value. + +## SetPlayerLock +This method allows you to lock or unlock the player's controls, preventing or allowing movement and casting. + +### Parameters +- `apply`: boolean (optional) - If set to `true`, the player will be locked. If set to `false`, the player will be unlocked. If not provided, the default value is `true`. + +### Example Usage +Here's an example of how to use `SetPlayerLock` in a script that freezes the player in place for a certain duration when they enter a specific area: + +```typescript +const AREA_ID = 1234; // Replace with the desired area ID +const LOCK_DURATION = 5000; // Lock duration in milliseconds (5 seconds) + +const OnAreaTrigger: player_event_on_area_trigger = (event: number, player: Player, areaId: number) => { + if (areaId === AREA_ID) { + // Lock the player controls + player.SetPlayerLock(true); + + // Send a message to the player + player.SendBroadcastMessage("You have been frozen in place!"); + + // Set a timer to unlock the player after the specified duration + let timerId = 0; + timerId = CreateTimer(LOCK_DURATION, () => { + // Unlock the player controls + player.SetPlayerLock(false); + + // Send a message to the player + player.SendBroadcastMessage("You are now free to move!"); + + // Despawn the timer + DestroyTimer(timerId); + }); + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_AREA_TRIGGER, (...args) => OnAreaTrigger(...args)); +``` + +In this example: +1. When the player enters a specific area (identified by `AREA_ID`), the `OnAreaTrigger` event is triggered. +2. Inside the event handler, we check if the triggered area ID matches the desired area ID. +3. If it matches, we lock the player's controls using `SetPlayerLock(true)`. +4. We send a message to the player indicating that they have been frozen in place. +5. We create a timer using `CreateTimer` that will unlock the player after a specified duration (`LOCK_DURATION`). +6. Inside the timer callback, we unlock the player's controls using `SetPlayerLock(false)`. +7. We send a message to the player indicating that they are now free to move. +8. Finally, we destroy the timer using `DestroyTimer` to prevent memory leaks. + +This script demonstrates how to use `SetPlayerLock` to temporarily restrict the player's movement and casting abilities when they enter a specific area, and then unlock them after a certain duration. + +Remember to replace `AREA_ID` with the actual area ID you want to trigger the lock, and adjust the `LOCK_DURATION` to the desired duration in milliseconds. + +## SetPvPDeath +This method allows you to toggle PvP death for a player. When PvP death is enabled, the player will lose durability and drop items on death during PvP combat. If PvP death is disabled, the player will not suffer these penalties. + +### Parameters +* on: boolean (optional) - Determines whether to enable or disable PvP death. If not provided, the method will toggle the current state. + +### Example Usage +In this example, we will create a custom PvP event where players can opt-in to participate. If they choose to participate, PvP death will be enabled for them, increasing the risk and reward of the event. + +```typescript +// Event constants +const EVENT_AREA_ID = 1234; // The area ID where the event takes place +const EVENT_DURATION = 3600; // Event duration in seconds (1 hour) +const EVENT_MIN_LEVEL = 60; // Minimum level required to participate + +// Event state +let eventActive = false; +let eventParticipants: Player[] = []; + +// Event start function +function startPvPEvent() { + eventActive = true; + SendWorldMessage("The PvP event has begun! Players can now opt-in to participate."); + CreateLuaEvent(() => { + endPvPEvent(); + }, EVENT_DURATION * 1000, 1); +} + +// Event end function +function endPvPEvent() { + eventActive = false; + SendWorldMessage("The PvP event has ended. Thank you for participating!"); + for (const participant of eventParticipants) { + participant.SetPvPDeath(false); + } + eventParticipants = []; +} + +// Player login event +const OnLogin: player_event_on_login = (event: number, player: Player) => { + if (eventActive && player.GetLevel() >= EVENT_MIN_LEVEL) { + player.SendBroadcastMessage("A PvP event is currently active! Type '.joinevent' to participate."); + } +}; + +// Player chat event +const OnChat: player_event_on_chat = (event: number, player: Player, msg: string, Type: number, lang: number) => { + if (msg === ".joinevent" && eventActive) { + if (player.GetLevel() < EVENT_MIN_LEVEL) { + player.SendBroadcastMessage(`You must be at least level ${EVENT_MIN_LEVEL} to participate in the PvP event.`); + return; + } + + if (player.GetAreaId() !== EVENT_AREA_ID) { + player.SendBroadcastMessage(`You must be in the event area to join the PvP event.`); + return; + } + + player.SetPvPDeath(true); + eventParticipants.push(player); + player.SendBroadcastMessage("You have joined the PvP event! PvP death is now enabled for you."); + } +}; + +// Register events +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => OnLogin(...args)); +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_CHAT, (...args) => OnChat(...args)); + +// Start the event +startPvPEvent(); +``` + +In this example, players can join the PvP event by typing ".joinevent" in the chat while they are in the designated event area and meet the minimum level requirement. When they join, PvP death is enabled for them using the `SetPvPDeath` method. At the end of the event, PvP death is disabled for all participants. + +## SetQuestStatus +Sets the state of a quest for the player. The quest state determines the player's progress and completion status for a specific quest. + +### Parameters +* entry: number - The ID of the quest to set the status for. Quest IDs can be found in the `quest_template` table in the world database. +* status: number - The status to set for the quest. Valid status values are: + - 0 - QUEST_STATUS_NONE + - 1 - QUEST_STATUS_COMPLETE + - 2 - QUEST_STATUS_UNAVAILABLE + - 3 - QUEST_STATUS_INCOMPLETE + - 4 - QUEST_STATUS_AVAILABLE + - 5 - QUEST_STATUS_FAILED + +### Example Usage +In this example, we'll create a script that allows players to reset a daily quest by talking to an NPC. The script will check if the player has already completed the quest for the day and reset it if necessary. + +```typescript +const DAILY_QUEST_ENTRY = 12345; +const QUEST_RESET_NPC_ENTRY = 54321; + +const OnGossipHello: on_gossip_event = (event: number, player: Player, object: WorldObject) => { + if (object.GetEntry() === QUEST_RESET_NPC_ENTRY) { + if (player.GetQuestStatus(DAILY_QUEST_ENTRY) === QuestStatus.QUEST_STATUS_COMPLETE) { + player.SetQuestStatus(DAILY_QUEST_ENTRY, QuestStatus.QUEST_STATUS_NONE); + player.SendBroadcastMessage("Your daily quest has been reset. You can now accept it again!"); + } else { + player.SendBroadcastMessage("You have not completed the daily quest yet. Come back after you've finished it!"); + } + + player.GossipComplete(); + } +}; + +RegisterServerEvent(ServerEvents.EVENT_ON_GOSSIP_HELLO, (...args) => OnGossipHello(...args)); +``` + +In this script: +1. We define constants for the daily quest entry and the NPC entry that will reset the quest. +2. We register a server event for `EVENT_ON_GOSSIP_HELLO`, which triggers when a player interacts with an NPC. +3. Inside the event handler, we check if the interacted object's entry matches the quest reset NPC entry. +4. If the player has already completed the daily quest (status is `QUEST_STATUS_COMPLETE`), we use `SetQuestStatus` to reset the quest status to `QUEST_STATUS_NONE`, effectively allowing the player to accept and complete the quest again. +5. We send a broadcast message to the player informing them that the quest has been reset or that they need to complete it first. +6. Finally, we call `GossipComplete` to close the gossip window. + +This script provides a convenient way for players to reset a daily quest by interacting with a specific NPC, saving them time and effort in case they need to repeat the quest. + +## SetRankPoints +This method sets the rank points for the player in the PvP ranking system. Rank points are used to determine the player's PvP rank and can be earned through various PvP activities such as battlegrounds and arenas. + +### Parameters +- `rankPoints`: number - The amount of rank points to set for the player. + +### Example Usage +Here's an example of how to use the `SetRankPoints` method to implement a custom PvP reward system: + +```typescript +const PVP_KILL_RP_REWARD = 10; // Reward 10 rank points per PvP kill +const RP_THRESHOLD_RANK_1 = 100; // Threshold for reaching rank 1 +const RP_THRESHOLD_RANK_2 = 500; // Threshold for reaching rank 2 +const RP_THRESHOLD_RANK_3 = 1000; // Threshold for reaching rank 3 + +const OnPvPKill: player_event_On_Kill_Player = (event: number, killer: Player, killed: Player) => { + const currentRP = killer.GetRankPoints(); + killer.SetRankPoints(currentRP + PVP_KILL_RP_REWARD); + + const newRP = killer.GetRankPoints(); + if (newRP >= RP_THRESHOLD_RANK_3 && currentRP < RP_THRESHOLD_RANK_3) { + // Player reached rank 3 + killer.SendBroadcastMessage("Congratulations! You have reached PvP Rank 3!"); + killer.AddItem(RANK_3_REWARD_ITEM, 1); // Reward for reaching rank 3 + } else if (newRP >= RP_THRESHOLD_RANK_2 && currentRP < RP_THRESHOLD_RANK_2) { + // Player reached rank 2 + killer.SendBroadcastMessage("Congratulations! You have reached PvP Rank 2!"); + killer.AddItem(RANK_2_REWARD_ITEM, 1); // Reward for reaching rank 2 + } else if (newRP >= RP_THRESHOLD_RANK_1 && currentRP < RP_THRESHOLD_RANK_1) { + // Player reached rank 1 + killer.SendBroadcastMessage("Congratulations! You have reached PvP Rank 1!"); + killer.AddItem(RANK_1_REWARD_ITEM, 1); // Reward for reaching rank 1 + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_KILL_PLAYER, (...args) => OnPvPKill(...args)); +``` + +In this example: +1. We define constants for the rank point reward per PvP kill and the rank point thresholds for reaching different PvP ranks. +2. In the `OnPvPKill` event handler, we retrieve the current rank points of the killer player using `GetRankPoints()`. +3. We call `SetRankPoints()` to add the PvP kill reward to the player's current rank points. +4. We check if the player has reached a new PvP rank based on the updated rank points. +5. If the player reaches a new rank, we send a congratulatory message using `SendBroadcastMessage()` and reward them with a specific item using `AddItem()`. + +This script demonstrates how the `SetRankPoints` method can be used in combination with other methods to create a custom PvP ranking and reward system on an Azerothcore server with the mod-eluna platform. + +## SetReputation +Sets the player's reputation amount for the specified faction. The reputation value is an integer value that represents the player's standing with the faction. Reputation values can be negative or positive, with higher positive values indicating a better standing with the faction. + +### Parameters +* factionId: number - The ID of the faction to set the reputation for. Faction IDs can be found in the `Faction` table in the world database. +* reputationValue: number - The reputation value to set for the specified faction. This value can be negative or positive. + +### Example Usage +Example script to set a player's reputation with the Argent Dawn faction based on their level when they kill a specific creature. + +```typescript +const CREATURE_ENTRY = 1234; // Replace with the actual creature entry ID +const ARGENT_DAWN_FACTION_ID = 529; // Argent Dawn faction ID + +const onCreatureKill: creature_event_on_creature_kill = (event: number, creature: Creature, killer: Unit) => { + if (creature.GetEntry() === CREATURE_ENTRY && killer instanceof Player) { + const player = killer as Player; + const playerLevel = player.GetLevel(); + + let reputationValue = 0; + if (playerLevel >= 60) { + reputationValue = 2500; // Exalted + } else if (playerLevel >= 50) { + reputationValue = 1500; // Revered + } else if (playerLevel >= 40) { + reputationValue = 500; // Honored + } else if (playerLevel >= 30) { + reputationValue = 100; // Friendly + } else { + reputationValue = 0; // Neutral + } + + const currentReputation = player.GetReputation(ARGENT_DAWN_FACTION_ID); + const newReputation = currentReputation + reputationValue; + + player.SetReputation(ARGENT_DAWN_FACTION_ID, newReputation); + player.SendBroadcastMessage(`Your reputation with the Argent Dawn has increased by ${reputationValue}!`); + } +}; + +RegisterCreatureEvent(CREATURE_ENTRY, CreatureEvents.CREATURE_EVENT_ON_CREATURE_KILL, onCreatureKill); +``` + +In this example: +1. We define the creature entry ID and the Argent Dawn faction ID as constants. +2. We register a creature event handler for the `CREATURE_EVENT_ON_CREATURE_KILL` event. +3. When the specified creature is killed by a player, we determine the reputation value to be added based on the player's level. +4. We retrieve the player's current reputation with the Argent Dawn faction using `player.GetReputation()`. +5. We calculate the new reputation value by adding the determined reputation value to the current reputation. +6. We set the player's reputation with the Argent Dawn faction to the new value using `player.SetReputation()`. +7. We send a broadcast message to the player informing them of the reputation increase. + +This script demonstrates how to use the `SetReputation()` method to modify a player's reputation with a specific faction based on certain conditions, such as the player's level and the creature they have killed. + +## SetRestBonus +This method sets the player's rest bonus to the specified amount. The rest bonus is a mechanic in World of Warcraft that allows players to accumulate extra experience points while logged out in an inn or a city. When the player logs back in, they receive a percentage of bonus experience based on their rest bonus amount. + +### Parameters +* restBonus: number - The amount of rest bonus to set for the player. This value is represented as a percentage, where 100 means 100% rest bonus. + +### Example Usage +Here's an example of how to use the `SetRestBonus` method to grant players a rest bonus based on their level and the time they spent offline: + +```typescript +const MINUTE = 60; +const HOUR = 60 * MINUTE; +const DAY = 24 * HOUR; + +const GrantRestBonus: player_event_on_login = (event: number, player: Player) => { + const timeOffline = player.GetTotalPlayedTime() - player.GetLevelPlayedTime(); + const level = player.GetLevel(); + let restBonus = 0; + + if (level < 60) { + restBonus = (timeOffline / (8 * HOUR)) * 100; + } else if (level < 70) { + restBonus = (timeOffline / (12 * HOUR)) * 100; + } else { + restBonus = (timeOffline / DAY) * 100; + } + + // Clamp the rest bonus between 0 and 150 + restBonus = Math.max(0, Math.min(restBonus, 150)); + + player.SetRestBonus(restBonus); + + // Notify the player about their rest bonus + player.SendBroadcastMessage(`Welcome back! You have accumulated ${restBonus.toFixed(2)}% rest bonus while offline.`); +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, GrantRestBonus); +``` + +In this example, we calculate the rest bonus based on the player's time spent offline and their level. Lower level players accumulate rest bonus faster than higher level players. We use different formulas to calculate the rest bonus for players below level 60, between level 60 and 70, and above level 70. + +We then clamp the rest bonus value between 0 and 150 to ensure it stays within the valid range. Finally, we call the `SetRestBonus` method to set the player's rest bonus and send them a message informing them about their accumulated rest bonus. + +This script showcases how you can use the `SetRestBonus` method in combination with other player-related methods and events to create a more immersive and rewarding experience for players who take breaks from the game. + +## SetSheath +Sets the sheathe state of the player's equipped weapons. The sheathe state determines whether the weapons are visibly carried on the player's character model. + +### Parameters +* sheatheState: number - The desired sheathe state. Valid values are: + * 0 - No sheathe state (weapons are not visible) + * 1 - Melee sheathe state (melee weapons are visible) + * 2 - Ranged sheathe state (ranged weapons are visible) + +### Example Usage +This example demonstrates how to set the player's sheathe state based on their class and the weapons they have equipped. + +```typescript +const SHEATHE_STATE_NONE = 0; +const SHEATHE_STATE_MELEE = 1; +const SHEATHE_STATE_RANGED = 2; + +const UpdateSheatheState: player_event_on_equip = (event: number, player: Player, item: Item, bag: number, slot: number) => { + const classId = player.GetClass(); + const hasRangedWeapon = player.HasRangedWeapon(); + const hasMeleeWeapon = player.HasMeleeWeapon(); + + let sheatheState = SHEATHE_STATE_NONE; + + if (classId === Classes.CLASS_HUNTER && hasRangedWeapon) { + sheatheState = SHEATHE_STATE_RANGED; + } else if (hasMeleeWeapon) { + sheatheState = SHEATHE_STATE_MELEE; + } + + player.SetSheath(sheatheState); +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_EQUIP, (...args) => UpdateSheatheState(...args)); +``` + +In this example, we define constants for the different sheathe states: `SHEATHE_STATE_NONE`, `SHEATHE_STATE_MELEE`, and `SHEATHE_STATE_RANGED`. + +We register a player event handler for the `PLAYER_EVENT_ON_EQUIP` event, which is triggered whenever a player equips an item. Inside the event handler, we retrieve the player's class using `player.GetClass()` and check if the player has a ranged weapon or a melee weapon equipped using `player.HasRangedWeapon()` and `player.HasMeleeWeapon()`, respectively. + +Based on the player's class and equipped weapons, we determine the appropriate sheathe state. If the player is a hunter and has a ranged weapon equipped, we set the sheathe state to `SHEATHE_STATE_RANGED`. Otherwise, if the player has a melee weapon equipped, we set the sheathe state to `SHEATHE_STATE_MELEE`. If neither condition is met, the sheathe state remains as `SHEATHE_STATE_NONE`. + +Finally, we call `player.SetSheath(sheatheState)` to set the player's sheathe state to the determined value. + +This script ensures that the player's sheathe state is automatically updated whenever they equip or unequip weapons, providing a visually accurate representation of their equipped weapons on their character model. + +## SetSkill +This method allows you to set or increase a specific skill for the player. You can specify the skill ID, the amount to increase the skill by, the current value of the skill, and the maximum value of the skill. + +### Parameters +* id: number - The ID of the skill to set or increase. Skill IDs can be found in the `SkillLine.dbc` file. +* step: number - The amount to increase the skill by. +* currVal: number - The current value of the skill. +* maxVal: number - The maximum value of the skill. + +### Example Usage +Here's an example of how to use the `SetSkill` method to increase a player's mining skill when they successfully mine a ore node: + +```typescript +const MINING_SKILL_ID = 186; +const COPPER_ORE_ENTRY = 2770; +const COPPER_ORE_SKILL_STEP = 1; + +const OnOpenGo: player_event_on_go_use = (event: number, player: Player, gameobject: GameObject) => { + const goEntry = gameobject.GetEntry(); + + if (goEntry === COPPER_ORE_ENTRY) { + const miningSkill = player.GetSkillValue(MINING_SKILL_ID); + const maxSkillLevel = player.GetMaxSkillValue(MINING_SKILL_ID); + + if (miningSkill < maxSkillLevel) { + player.SetSkill(MINING_SKILL_ID, COPPER_ORE_SKILL_STEP, miningSkill, maxSkillLevel); + player.SendBroadcastMessage("Your mining skill has increased!"); + } + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_GO_USE, (...args) => OnOpenGo(...args)); +``` + +In this example: +1. We define constants for the mining skill ID, copper ore entry ID, and the amount to increase the skill by when mining copper ore. +2. We register the `PLAYER_EVENT_ON_GO_USE` event to trigger the `OnOpenGo` function whenever a player uses a game object. +3. Inside the `OnOpenGo` function, we check if the game object entry matches the copper ore entry. +4. If it does, we get the player's current mining skill value and maximum skill value using the `GetSkillValue` and `GetMaxSkillValue` methods. +5. If the current skill value is less than the maximum skill value, we use the `SetSkill` method to increase the mining skill by the specified step amount. +6. Finally, we send a broadcast message to the player informing them that their mining skill has increased. + +This script ensures that the player's mining skill increases gradually as they mine copper ore nodes, until they reach the maximum skill level for mining. + +Note: Make sure to replace the skill ID, ore entry, and skill step values with the appropriate values for your server and the specific skill you want to increase. + +## SetTaxiCheat +Toggles whether the player has taxi cheat enabled or not. When taxi cheat is enabled, the player can instantly teleport to any taxi node without the need to discover it first or pay for the travel cost. + +### Parameters +* taxiCheat?: boolean - (Optional) Set to `true` to enable taxi cheat, `false` to disable it. If not provided, it will toggle the current state. + +### Example Usage +In this example, we create a command `.taxicheat` that allows players to toggle their taxi cheat status. We also store the player's original taxi cheat state in a table to restore it when they log out. + +```typescript +const playerTaxiCheatState: { [playerGuid: number]: boolean } = {}; + +const onCommand: player_event_on_command = (event: PlayerEvents.PLAYER_EVENT_ON_COMMAND, player: Player, command: string, args: string[]): void => { + if (command === 'taxicheat') { + const currentState = player.GetTaxiCheat(); + player.SetTaxiCheat(!currentState); + + if (currentState) { + player.SendBroadcastMessage('Taxi cheat disabled.'); + } else { + player.SendBroadcastMessage('Taxi cheat enabled.'); + } + + playerTaxiCheatState[player.GetGUIDLow()] = !currentState; + } +}; + +const onLogin: player_event_on_login = (event: PlayerEvents.PLAYER_EVENT_ON_LOGIN, player: Player): void => { + const playerGuid = player.GetGUIDLow(); + if (playerGuid in playerTaxiCheatState) { + const taxiCheatState = playerTaxiCheatState[playerGuid]; + player.SetTaxiCheat(taxiCheatState); + + if (taxiCheatState) { + player.SendBroadcastMessage('Taxi cheat is currently enabled for your character.'); + } + } +}; + +const onLogout: player_event_on_logout = (event: PlayerEvents.PLAYER_EVENT_ON_LOGOUT, player: Player): void => { + const playerGuid = player.GetGUIDLow(); + delete playerTaxiCheatState[playerGuid]; +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_COMMAND, (...args) => onCommand(...args)); +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => onLogin(...args)); +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGOUT, (...args) => onLogout(...args)); +``` + +In this script: +1. We define an object `playerTaxiCheatState` to store the taxi cheat state for each player using their GUID as the key. +2. In the `onCommand` event, we check if the player used the `.taxicheat` command. If so, we toggle their taxi cheat state using `SetTaxiCheat()`, send them a message indicating the current state, and store the updated state in `playerTaxiCheatState`. +3. In the `onLogin` event, we check if the player's GUID exists in `playerTaxiCheatState`. If it does, we set their taxi cheat state to the stored value and send them a message if taxi cheat is enabled. +4. In the `onLogout` event, we remove the player's entry from `playerTaxiCheatState` to avoid storing unnecessary data. + +This script allows players to use the `.taxicheat` command to toggle their taxi cheat status, which persists across logouts. The script also informs players about their current taxi cheat state when they log in. + +## SpawnBones +This method will convert the player's corpse into bones. This can be useful for quickly removing a player's corpse from the game world or for creating custom death mechanics. + +### Parameters +This method does not take any parameters. + +### Returns +This method does not return any values. + +### Example Usage +In this example, we will create a custom death system where players who die in a specific area will have their corpses automatically converted to bones after 5 minutes. This can be used to create a sense of urgency for players to recover their corpses in dangerous areas. + +```typescript +const CUSTOM_AREA_ID = 1234; +const CORPSE_DESPAWN_DELAY = 5 * MINUTE * IN_MILLISECONDS; + +const OnPlayerDeath: player_event_on_death = (event: number, player: Player, killer: Unit) => { + if (player.GetAreaId() === CUSTOM_AREA_ID) { + player.CreateCorpse(); + + // Schedule the corpse to be converted to bones after the specified delay + player.RegisterTimedEvent(CORPSE_DESPAWN_DELAY, (eventId: number, delay: number, repeats: number, player: Player) => { + const corpse = player.GetCorpse(); + if (corpse) { + corpse.SetCorpseType(CorpseType.CORPSE_BONES); + corpse.DeleteBonesFromWorld(); + } + }, CORPSE_DESPAWN_DELAY); + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_DEATH, (...args) => OnPlayerDeath(...args)); +``` + +In this script: +1. We define a constant `CUSTOM_AREA_ID` to represent the area ID where we want to apply our custom death mechanics. +2. We define a constant `CORPSE_DESPAWN_DELAY` to specify the delay (in milliseconds) before the corpse is converted to bones. +3. In the `OnPlayerDeath` event handler, we check if the player died in the specified area using `player.GetAreaId()`. +4. If the player died in the custom area, we create a corpse for the player using `player.CreateCorpse()`. +5. We then schedule a timed event using `player.RegisterTimedEvent()` to be executed after the specified delay. +6. In the timed event callback, we retrieve the player's corpse using `player.GetCorpse()`. +7. If the corpse exists, we convert it to bones using `corpse.SetCorpseType(CorpseType.CORPSE_BONES)`. +8. Finally, we remove the bones from the world using `corpse.DeleteBonesFromWorld()`. + +This script showcases how the `SpawnBones()` method can be used in combination with other methods and events to create a custom death system in specific areas of the game world. + +Remember to register the event handler using `RegisterPlayerEvent()` with the appropriate event type (`PlayerEvents.PLAYER_EVENT_ON_DEATH` in this case) to ensure that the script is executed when a player dies. + +## StartTaxi +This method attempts to start a taxi or flying mount travel for the player to the specified path. The pathId corresponds to the path entry in the DBC files. If the player does not meet the requirements for the taxi path, such as not having the necessary flight points discovered or not being at a flight master, the method will fail silently. + +### Parameters +- pathId: number - The ID of the taxi path to start. You can find these IDs in the DBC files or by consulting the TaxiPath.dbc file. + +### Example Usage +Here's an example of how to use the StartTaxi method to send a player on a taxi ride when they interact with a specific game object: + +```typescript +const OBJECT_ENTRY = 12345; // Replace with the actual game object entry ID +const TAXI_PATH_ID = 678; // Replace with the actual taxi path ID + +const OnGameObjectUse: gameobject_scripts = (go: GameObject, player: Player) => { + if (go.GetEntry() === OBJECT_ENTRY) { + // Check if the player is eligible for the taxi ride + if (player.GetTeam() === TeamId.TEAM_HORDE && player.GetReputationRank(942) >= ReputationRank.REVERED) { + // Horde players need to be Revered with the Cenarion Expedition (faction ID 942) + player.StartTaxi(TAXI_PATH_ID); + } else if (player.GetTeam() === TeamId.TEAM_ALLIANCE && player.GetQuestRewardStatus(12345)) { + // Alliance players need to have completed a specific quest (replace 12345 with the actual quest ID) + player.StartTaxi(TAXI_PATH_ID); + } else { + // Player does not meet the requirements + player.SendBroadcastMessage("You do not meet the requirements to use this taxi service."); + } + } +}; + +RegisterGameObjectEvent(OBJECT_ENTRY, GameObjectEvents.GAMEOBJECT_EVENT_ON_USE, OnGameObjectUse); +``` + +In this example: +1. We define the entry ID of the game object that will trigger the taxi ride (replace `OBJECT_ENTRY` with the actual entry ID). +2. We specify the taxi path ID that the player will be sent on (replace `TAXI_PATH_ID` with the actual path ID). +3. In the `OnGameObjectUse` event handler, we check if the interacted game object matches the desired entry ID. +4. We then check if the player meets the requirements for the taxi ride based on their team and other conditions. + - For Horde players, we check if they have reached the Revered reputation rank with the Cenarion Expedition faction. + - For Alliance players, we check if they have completed a specific quest (replace `12345` with the actual quest ID). +5. If the player meets the requirements, we call `player.StartTaxi(TAXI_PATH_ID)` to send them on the taxi ride. +6. If the player does not meet the requirements, we send them a broadcast message informing them that they cannot use the taxi service. +7. Finally, we register the `OnGameObjectUse` event handler for the specific game object entry using `RegisterGameObjectEvent`. + +Make sure to replace `OBJECT_ENTRY`, `TAXI_PATH_ID`, and any other placeholder values with the actual entry IDs and path IDs relevant to your scenario. + +## SummonPlayer +Sends a summon request to the player from the given summoner. This can be used to request the player to join a group, raid, or to teleport to the summoner's location. The player must accept the summon request to complete the summon. + +### Parameters +- summoner: [Unit](./unit.md) - The unit that is summoning the player. + +### Example Usage +Here's an example of how to use the `SummonPlayer` method to summon a player to a raid boss encounter when they enter the raid dungeon: + +```typescript +const RAID_DUNGEON_MAP_ID = 532; +const RAID_BOSS_CREATURE_ENTRY = 24723; + +const OnPlayerEnterWorld: player_event_on_login = (event: number, player: Player) => { + const map = player.GetMap(); + + if (map && map.GetMapId() === RAID_DUNGEON_MAP_ID) { + const creatures = map.GetCreaturesInRange(player.GetX(), player.GetY(), player.GetZ(), 100); + + for (const creature of creatures) { + if (creature.GetEntry() === RAID_BOSS_CREATURE_ENTRY) { + const raidBoss = creature as Unit; + + // Check if the player is already in a raid group + if (!player.IsInRaid()) { + // Create a new raid group and add the player to it + const raidGroup = player.GetMap().CreateRaid(player); + player.AddToRaid(raidGroup); + } + + // Send a summon request to the player from the raid boss + raidBoss.SummonPlayer(player); + + // Announce the summon request to the player + player.SendBroadcastMessage(`You have been summoned by ${raidBoss.GetName()} to join the raid!`); + + break; + } + } + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => OnPlayerEnterWorld(...args)); +``` + +In this example, when a player enters a specific raid dungeon (identified by the `RAID_DUNGEON_MAP_ID`), the script searches for a raid boss creature (identified by the `RAID_BOSS_CREATURE_ENTRY`) within a certain range of the player's location. + +If the raid boss is found and the player is not already in a raid group, the script creates a new raid group and adds the player to it. Then, it sends a summon request to the player from the raid boss using the `SummonPlayer` method. + +Finally, the script sends a broadcast message to the player informing them about the summon request from the raid boss. + +This example demonstrates how the `SummonPlayer` method can be used in combination with other methods and game events to create a more complex and interactive gameplay experience for the player. + +## TalkedToCreature +This method is used to give credit to the player for talking to a creature as part of a quest requirement. It marks the specified creature as "talked to" for the player in the context of the quest. + +### Parameters +* entry: number - The entry ID of the quest that requires talking to the creature. +* creature: [Creature](./creature.md) - The creature object representing the NPC that the player talked to. + +### Example Usage +In this example, we have a quest that requires the player to talk to a specific NPC to gather information. Once the player interacts with the NPC, the `TalkedToCreature` method is called to give the player credit for talking to the creature. + +```typescript +const QUEST_ENTRY = 1234; +const NPC_ENTRY = 5678; + +const OnGossipHello: player_event_on_gossip_hello = (event: number, player: Player, creature: Creature) => { + if (creature.GetEntry() === NPC_ENTRY) { + if (player.HasQuest(QUEST_ENTRY)) { + player.TalkedToCreature(QUEST_ENTRY, creature); + creature.SendUnitWhisper("Thank you for taking the time to talk to me. I have marked your quest as complete.", 0, player); + player.CompleteQuest(QUEST_ENTRY); + } else { + creature.SendUnitWhisper("Hello there! I have some important information, but it seems you don't have the right quest yet.", 0, player); + } + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_GOSSIP_HELLO, (...args) => OnGossipHello(...args)); +``` + +In this script: +1. We define constants for the quest entry and the NPC entry for clarity and maintainability. +2. We register the `PLAYER_EVENT_ON_GOSSIP_HELLO` event to trigger the script when the player interacts with an NPC. +3. Inside the event handler, we check if the interacted creature matches the desired NPC entry. +4. If the player has the specific quest, we call `TalkedToCreature` to give credit for talking to the creature. +5. We send a whisper message to the player indicating that the quest has been marked as complete. +6. We call `CompleteQuest` to mark the quest as completed for the player. +7. If the player doesn't have the quest, we send a different whisper message indicating that they don't have the right quest yet. + +This script ensures that the player receives credit for talking to the specific NPC only if they have the corresponding quest. It provides a more immersive experience by sending appropriate whisper messages based on the player's quest status. + +Note: Make sure to replace `QUEST_ENTRY` and `NPC_ENTRY` with the actual entry IDs from your database for the specific quest and NPC involved in the script. + +## Teleport +Instantly moves the player to the specified location on the given map. + +### Parameters +* mapId: number - The ID of the map to teleport the player to. Map IDs can be found in the `Map.dbc` file. +* xCoord: number - The x-coordinate of the destination on the specified map. +* yCoord: number - The y-coordinate of the destination on the specified map. +* zCoord: number - The z-coordinate (height) of the destination on the specified map. +* orientation: number - The orientation (facing direction) of the player at the destination, in radians. + +### Example Usage +Teleport the player to the top of Stormwind's Wizard's Sanctum when they use the `.tele` command: + +```typescript +const WIZARD_SANCTUM_MAP = 0; // Eastern Kingdoms +const WIZARD_SANCTUM_X = -9015.8; +const WIZARD_SANCTUM_Y = 874.7; +const WIZARD_SANCTUM_Z = 148.6; +const WIZARD_SANCTUM_O = 3.5; + +const onChatMessage: player_event_on_chat = (event: number, player: Player, msg: string, Type: ChatMsg, lang: Language): void => { + if (msg === '.tele') { + player.Teleport(WIZARD_SANCTUM_MAP, WIZARD_SANCTUM_X, WIZARD_SANCTUM_Y, WIZARD_SANCTUM_Z, WIZARD_SANCTUM_O); + player.SendBroadcastMessage('You have been teleported to the Wizard\'s Sanctum.'); + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_CHAT, (...args) => onChatMessage(...args)); +``` + +Create a teleportation matrix for GMs to quickly move between major cities: + +```typescript +const CITY_TELEPORT_LOCATIONS = [ + { name: 'Stormwind', map: 0, x: -8842.1, y: 626.4, z: 94.1, o: 3.6 }, + { name: 'Ironforge', map: 0, x: -4918.9, y: -940.4, z: 501.6, o: 5.4 }, + { name: 'Darnassus', map: 1, x: 9947.5, y: 2482.7, z: 1316.2, o: 0 }, + { name: 'Exodar', map: 530, x: -3965.7, y: -11653.6, z: -138.8, o: 0.5 }, + { name: 'Orgrimmar', map: 1, x: 1424.1, y: -4419.3, z: 25.1, o: 0.1 }, + { name: 'Thunder Bluff', map: 1, x: -1282.3, y: 114.8, z: 131.3, o: 5.1 }, + { name: 'Undercity', map: 0, x: 1586.5, y: 239.6, z: -52.1, o: 0.6 }, + { name: 'Silvermoon', map: 530, x: 9487.7, y: -7279.3, z: 14.2, o: 0 }, + { name: 'Shattrath', map: 530, x: -1838.2, y: 5301.8, z: -12.4, o: 5.9 }, + { name: 'Dalaran', map: 571, x: 5804.1, y: 624.7, z: 647.8, o: 1.6 } +]; + +const onChatMessage: player_event_on_chat = (event: number, player: Player, msg: string, Type: ChatMsg, lang: Language): void => { + if (msg.startsWith('.tele ')) { + const cityName = msg.substring(6); + const city = CITY_TELEPORT_LOCATIONS.find(c => c.name.toLowerCase() === cityName.toLowerCase()); + + if (city) { + player.Teleport(city.map, city.x, city.y, city.z, city.o); + player.SendBroadcastMessage(`You have been teleported to ${city.name}.`); + } else { + player.SendBroadcastMessage(`Unknown city: ${cityName}. Valid cities are: ${CITY_TELEPORT_LOCATIONS.map(c => c.name).join(', ')}`); + } + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_CHAT, (...args) => onChatMessage(...args)); +``` + +## TextEmote +Send a text emote message from the player to nearby players in chat. This allows the player to express visible emotions or actions to other players. + +### Parameters +* emoteText: string - The text to display as the emote message + +### Example Usage: +Create a script to allow players to perform special emotes after killing a creature based on the creature's name. +```typescript +const MURLOC_EMOTE = "makes a gurgling sound."; +const WOLF_EMOTE = "lets out a loud howl!"; +const DRAGON_EMOTE = "roars triumphantly!"; + +const onCreatureKill: player_event_on_kill_creature = (event: number, player: Player, creature: Creature) => { + switch(creature.GetName()) { + case "Murloc": + player.TextEmote(MURLOC_EMOTE); + break; + case "Wolf": + player.TextEmote(WOLF_EMOTE); + break; + case "Dragon": + player.TextEmote(DRAGON_EMOTE); + creature.CastSpell(player, 10, true); + break; + default: + player.TextEmote("celebrates their victory!"); + break; + } + + const nearbyPlayers = player.GetPlayersInRange(10, true); + nearbyPlayers.forEach((nearbyPlayer: Player) => { + nearbyPlayer.SendBroadcastMessage(`${player.GetName()} has slain ${creature.GetName()}!`); + }); +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_KILL_CREATURE, (...args) => onCreatureKill(...args)); +``` +In this example, when a player kills specific types of creatures, they will perform a special emote related to that creature. Additionally, nearby players within 10 yards will receive a broadcast message informing them of the player's victory over the slain creature. If the defeated creature is a dragon, it will also cast a spell on the player with ID 10. + +## ToggleAFK +This method allows you to toggle the 'Away From Keyboard' (AFK) flag for the player. When a player is marked as AFK, their character will not be logged out due to inactivity and will display the 'Away' status. + +### Parameters +This method does not take any parameters. + +### Returns +This method does not return any values. + +### Example Usage +Here's an example of how to use the `ToggleAFK` method to automatically set a player's AFK status based on their current zone: + +```typescript +const MAJOR_CITY_ZONES = [ + 1519, // Stormwind City + 1537, // Ironforge + 1637, // Orgrimmar + 1638, // Thunder Bluff + 1657, // Darnassus + 3487, // Silvermoon City + 3703, // Shattrath City + 4395, // Dalaran +]; + +const HandlePlayerUpdateZone: player_event_on_update_zone = (event: number, player: Player, newZone: number, newArea: number) => { + const playerZoneId = player.GetZoneId(); + + if (MAJOR_CITY_ZONES.includes(playerZoneId)) { + // If the player is in a major city, mark them as AFK + if (!player.IsAFK()) { + player.ToggleAFK(); + player.SendBroadcastMessage("You have been marked as Away because you are in a major city."); + } + } else { + // If the player is not in a major city, remove the AFK status + if (player.IsAFK()) { + player.ToggleAFK(); + player.SendBroadcastMessage("Your Away status has been removed because you left a major city."); + } + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_UPDATE_ZONE, (...args) => HandlePlayerUpdateZone(...args)); +``` + +In this example, we define an array of zone IDs that correspond to major cities in the game. Whenever a player enters a new zone (`PLAYER_EVENT_ON_UPDATE_ZONE` event), we check if the new zone is a major city. + +If the player is in a major city and not already marked as AFK, we toggle their AFK status using `player.ToggleAFK()` and send them a message indicating why they were marked as AFK. + +If the player leaves a major city and their AFK status is currently set, we remove the AFK status using `player.ToggleAFK()` and send them a message notifying them of the change. + +This script demonstrates how you can use the `ToggleAFK` method in combination with other player methods and events to create a practical feature for your server. + +## ToggleDND +This method allows you to toggle the 'Do Not Disturb' (DND) flag for the player. When the DND flag is enabled, the player will not receive any messages from other players, including whispers, guild messages, and channel messages. This can be useful for players who want to focus on their gameplay without being interrupted by chat messages. + +### Parameters +This method does not take any parameters. + +### Returns +This method does not return any value. + +### Example Usage +Here's an example of how to use the `ToggleDND` method to create a command that allows players to toggle their DND status: + +```typescript +const DND_COMMAND = "dnd"; + +const HandleCommand: player_event_on_chat = (event: number, player: Player, msg: string, type: number, lang: number) => { + if (msg === DND_COMMAND) { + player.ToggleDND(); + + if (player.GetDNDStatus()) { + player.SendBroadcastMessage("Do Not Disturb mode enabled. You will not receive any messages from other players."); + } else { + player.SendBroadcastMessage("Do Not Disturb mode disabled. You will now receive messages from other players."); + } + + return 0; + } + + return 1; +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_CHAT, (...args) => HandleCommand(...args)); +``` + +In this example, we define a constant `DND_COMMAND` that represents the command players can use to toggle their DND status. When a player types this command in the chat, the `HandleCommand` function is called. + +Inside the function, we first check if the entered message matches the `DND_COMMAND`. If it does, we call the `ToggleDND` method to toggle the player's DND status. + +After toggling the DND status, we use the `GetDNDStatus` method (assuming it exists) to check the current DND status of the player. If the DND status is enabled, we send a broadcast message to the player indicating that they will not receive any messages from other players. If the DND status is disabled, we send a broadcast message indicating that they will now receive messages from other players. + +Finally, we return 0 to indicate that the command has been handled and no further processing is needed. If the entered message does not match the `DND_COMMAND`, we return 1 to allow other command handlers to process the message. + +By registering the `HandleCommand` function with the `PLAYER_EVENT_ON_CHAT` event, this command will be triggered whenever a player sends a chat message. + +## UnbindAllInstances +This method unbinds the player from all instances they are saved to, except the instance they are currently in. This can be useful for managing player saved instances, such as removing them from older instances they no longer need to be saved to. + +### Parameters +None + +### Returns +None + +### Example Usage +This example script listens for the player login event, and if the player is level 80, it will unbind them from all heroic instances that are not Icecrown Citadel, since that is the latest level 80 heroic raid instance. + +```typescript +const ICECROWN_CITADEL_MAP_ID = 631; + +const OnLogin: player_event_on_login = (event: number, player: Player) => { + if (player.GetLevel() == 80) { + const instanceIds = player.GetBoundInstances(); + + instanceIds.forEach(id => { + const instance = player.GetInstance(id); + + // If the instance is a heroic difficulty, and not ICC + if (instance.Is25ManRaid() && instance.GetMapId() !== ICECROWN_CITADEL_MAP_ID) { + player.UnbindInstance(instance); + } + }); + + // Unbind any remaining non-ICC instances + player.UnbindAllInstances(); + + // Inform the player + player.SendBroadcastMessage("You have been unbound from all old heroic instances."); + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => OnLogin(...args)); +``` + +In this example: +1. We listen for the `PLAYER_EVENT_ON_LOGIN` event. +2. If the player is level 80, we get a list of their bound instance IDs using `player.GetBoundInstances()`. +3. We loop through each instance ID, get the actual instance using `player.GetInstance(id)`, and check if it's a heroic 25-man raid (using `instance.Is25ManRaid()`) and not Icecrown Citadel (by checking the map ID). +4. If the instance meets these criteria, we unbind the player from it using `player.UnbindInstance(instance)`. +5. After the loop, we call `player.UnbindAllInstances()` to unbind the player from any remaining non-ICC instances (such as 10-man raids or non-heroic difficulties). +6. Finally, we inform the player that they have been unbound from old instances using `player.SendBroadcastMessage()`. + +This script helps keep the player's saved instance list clean and relevant as they progress to newer content. + +## UnbindInstance +Unbinds the player from all instances they are bound to except for the instance they are currently in. When a player enters an instance, they become bound to it, which means they cannot enter a new instance of the same map. This method allows unbinding the player from instances they are bound to, allowing them to enter new instances. + +### Parameters +* map (optional): number - The ID of the map to unbind the player from. If not provided, the player will be unbound from all instances except the one they are currently in. +* difficulty (optional): number - The difficulty of the instance to unbind the player from. This parameter is not used in WoW Classic. + +### Example Usage +Unbind the player from all instances of a specific map when they leave a group: +```typescript +const GROUP_DISBANDED_EVENT = 1; +const DEADMINES_MAP_ID = 36; + +const onGroupDisbanded: group_event_on_disband = (event: number, group: Group, player: Player) => { + const instanceSave = player.GetInstanceSave(); + + if (instanceSave) { + const mapId = instanceSave.GetMapId(); + + if (mapId === DEADMINES_MAP_ID) { + player.UnbindInstance(DEADMINES_MAP_ID); + player.SendBroadcastMessage("You have been unbound from the Deadmines instance."); + } + } +}; + +RegisterGroupEvent(GroupEvents.GROUP_EVENT_ON_DISBAND, (...args) => onGroupDisbanded(...args)); +``` + +In this example, when a player's group is disbanded (event GROUP_EVENT_ON_DISBAND), the script checks if the player is saved to an instance. If the player is saved to an instance of the Deadmines (map ID 36), the script unbinds the player from that instance using the `UnbindInstance` method, allowing them to enter a new Deadmines instance. The player is then sent a broadcast message informing them that they have been unbound from the instance. + +This can be useful in situations where players want to reset an instance and start fresh, or if they need to join a different group to complete the instance. By unbinding the player from the instance, they can enter a new instance of the same map without any restrictions. + +Note that this script assumes the player is saved to a Deadmines instance. You can modify the script to handle other instances by checking for different map IDs and adjusting the broadcast message accordingly. + +## UnsetKnownTitle +Removes a title by ID from the player's list of known titles. This can be useful for removing titles that are no longer available or for implementing custom title systems. + +### Parameters +* titleId: number - The ID of the title to remove from the player's known titles. + +### Example Usage +Suppose you want to create an event where players can lose titles based on certain conditions. In this example, we'll remove a title from a player if they die in a specific area. + +```typescript +const AREA_ID = 1234; // Replace with the actual area ID +const TITLE_ID = 5678; // Replace with the actual title ID + +const OnPlayerDeath: player_event_on_death = (event: number, player: Player, killer: WorldObject) => { + const playerMap = player.GetMapId(); + const playerArea = player.GetAreaId(); + + if (playerMap === 0 && playerArea === AREA_ID) { + if (player.HasTitle(TITLE_ID)) { + player.UnsetKnownTitle(TITLE_ID); + player.SendBroadcastMessage("You have lost the title due to your defeat in this area."); + } + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_DEATH, (...args) => OnPlayerDeath(...args)); +``` + +In this script: +1. We define the `AREA_ID` and `TITLE_ID` constants to represent the specific area and title we're interested in. +2. We register the `PLAYER_EVENT_ON_DEATH` event to trigger our custom function `OnPlayerDeath` whenever a player dies. +3. Inside the `OnPlayerDeath` function, we retrieve the player's current map and area IDs using `GetMapId()` and `GetAreaId()` methods. +4. We check if the player is in the desired map (in this case, map 0) and specific area using the `AREA_ID` constant. +5. If the player is in the correct map and area, we check if they have the specified title using the `HasTitle()` method. +6. If the player has the title, we remove it using the `UnsetKnownTitle()` method and send a broadcast message to inform them about the title loss. + +This script ensures that players lose the specified title when they die in the designated area. You can customize the conditions and actions based on your specific requirements. + +Remember to replace `AREA_ID` and `TITLE_ID` with the actual IDs relevant to your game world and title system. + +Note: Make sure to have the necessary permissions and consider any potential balance implications when removing titles from players programmatically. + +## UpdateHonor +Updates the player's weekly honor status, calculating their standing ranks and honor points for the current week. + +### Parameters +None + +### Returns +None + +### Example Usage +This example script will update the player's weekly honor status when they kill an enemy player, and then reward them with additional honor points based on their standing rank. + +```typescript +const KILL_HONOR_BONUS = 100; + +const OnPVPKill: player_event_on_kill_player = (event: number, killer: Player, killed: Player) => { + // Update the killer's weekly honor status + killer.UpdateHonor(); + + // Get the killer's current honor points and standing rank + const honorPoints = killer.GetHonorPoints(); + const standingRank = killer.GetHonorStandingRank(); + + // Calculate the bonus honor points based on the standing rank + let bonusHonor = 0; + if (standingRank === 1) { + bonusHonor = KILL_HONOR_BONUS * 3; + } else if (standingRank <= 5) { + bonusHonor = KILL_HONOR_BONUS * 2; + } else if (standingRank <= 10) { + bonusHonor = KILL_HONOR_BONUS; + } + + // Add the bonus honor points to the killer + if (bonusHonor > 0) { + killer.ModifyHonorPoints(bonusHonor); + killer.SendBroadcastMessage(`You have been awarded ${bonusHonor} bonus honor points for your outstanding performance!`); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_KILL_PLAYER, (...args) => OnPVPKill(...args)); +``` + +In this example: +1. When a player kills another player, the `OnPVPKill` event is triggered. +2. The script calls `UpdateHonor()` to update the killer's weekly honor status. +3. It retrieves the killer's current honor points and standing rank using `GetHonorPoints()` and `GetHonorStandingRank()`. +4. Based on the standing rank, it calculates the bonus honor points to be awarded. + - Rank 1 players receive a 3x bonus + - Ranks 2-5 players receive a 2x bonus + - Ranks 6-10 players receive a 1x bonus + - Players below rank 10 receive no bonus +5. If bonus honor points are to be awarded, the script calls `ModifyHonorPoints()` to add the bonus to the killer's honor points. +6. Finally, it sends a broadcast message to the killer informing them of the bonus honor points awarded. + +This script encourages players to strive for higher standing ranks by rewarding them with bonus honor points for kills, proportional to their current rank. It adds an extra layer of motivation and competition to the PvP system. + +## Whisper +Sends a whisper message from the player to another player. + +### Parameters +* text: string - The content of the whisper message +* lang: number - The language of the message (can be found in Language.h) +* receiver: [Player](./player.md) - The player to receive the whisper message +* guid: number - The GUID of the receiver player + +### Example Usage: +Script that allows a player to whisper another player with a specific keyword and receive an automated response. +```typescript +const KEYWORD = "help"; +const RESPONSE = "Sure, I can help you! What do you need assistance with?"; +const LANG_UNIVERSAL = 0; + +const HandleWhisper: player_event_on_whisper = (event: number, player: Player, msg: string, lang: Language, receiver: Player): void => { + if (msg.toLowerCase() === KEYWORD) { + const receiverGuid = receiver.GetGUID(); + player.Whisper(RESPONSE, LANG_UNIVERSAL, receiver, receiverGuid); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_WHISPER, (...args) => HandleWhisper(...args)); +``` + +In this example: +1. We define constants for the keyword that triggers the automated response, the response message itself, and the language of the message (in this case, Universal). +2. We create a function `HandleWhisper` that handles the `PLAYER_EVENT_ON_WHISPER` event. +3. Inside the function, we check if the received message (`msg`) matches the defined `KEYWORD`. The comparison is done in lowercase to make it case-insensitive. +4. If the keyword matches, we retrieve the GUID of the receiver player using `receiver.GetGUID()`. +5. We then use the `Whisper` method of the `player` object to send the `RESPONSE` message to the `receiver` player, specifying the language as `LANG_UNIVERSAL` and providing the receiver's GUID. +6. Finally, we register the `HandleWhisper` function to be called whenever the `PLAYER_EVENT_ON_WHISPER` event occurs using `RegisterPlayerEvent`. + +With this script, whenever a player whispers the keyword "help" to another player, the script will automatically respond with the message "Sure, I can help you! What do you need assistance with?" in the Universal language. + +This example demonstrates how the `Whisper` method can be used in combination with player events to create interactive functionality based on player communication. + +## Yell +Send a yell message from the player to nearby players. These messages will appear in the chat window for other players that are nearby. You can also specify a language to yell the text. + +### Parameters +* text: string - The text to send as the yell message +* lang: [Language](../Enums/Language.md) - The language to send the text as + +### Example Usage: +Have the player yell when they die with the number of their lifetime kills + +```typescript +const YELL_RANGE = 100; + +const OnPlayerDeath: player_event_on_player_kill = (event: number, killer: Player, killed: Player) => { + if(killer.GetGUID() == killed.GetGUID()) { + // Player killed themselves, don't yell + return; + } + + // Get lifetime kills + const lifetimeKills = killed.GetUInt32Value(UnitFields.PLAYER_FIELD_LIFETIME_HONORABLE_KILLS); + + // Create yell message with lifetime kills + const yellMessage = `I have been slain with ${lifetimeKills} lifetime kills!`; + + // Yell in common language + killed.Yell(yellMessage, Language.LANG_UNIVERSAL); + + // Get nearby players + const nearbyPlayers = killed.GetPlayersInRange(YELL_RANGE); + + // Send a whisper to all nearby players with the same message + nearbyPlayers.forEach((player: Player) => { + if(player.GetGUID() != killed.GetGUID()) { + killed.Whisper(yellMessage, Language.LANG_UNIVERSAL, player); + } + }) +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_KILLED_BY_PLAYER, (...args) => OnPlayerDeath(...args)); +``` + +In this example: +1. When a player is killed by another player the `OnPlayerDeath` function will be called. +2. It will check if the killer and killed players are the same (suicide) and if so it will return early +3. The players lifetime kills will be retrieved +4. A yell message will be constructed with the lifetime kills included +5. The `Yell` method will be called with the message and the `LANG_UNIVERSAL` language (common tongue) +6. All players within `YELL_RANGE` of the killed player will be found +7. A whisper will be sent from the killed player to each nearby player with the same message. + +This will allow you to broadcast a message not only to the nearby players, but also whisper that same message to them as well. + diff --git a/docs/classes/Quest.md b/docs/classes/Quest.md new file mode 100644 index 0000000..0b03d15 --- /dev/null +++ b/docs/classes/Quest.md @@ -0,0 +1,156 @@ +## GetFlags +Returns the flags associated with a quest. These flags provide additional information about the quest, such as whether it is repeatable, Epic, or is an Escort quest. + +### Parameters +This method does not take any parameters. + +### Returns +[QuestFlags](../Types/questflags.md): The flags associated with the quest. + +### Example Usage +This example demonstrates how to check if a quest is repeatable and award bonus reputation if it is. + +```typescript +const QUEST_ENTRY = 1234; +const FACTION_ID = 69; +const BONUS_REPUTATION = 500; + +const OnQuestComplete: player_event_on_quest_complete = (event: number, player: Player, quest: number) => { + const questTemplate = GetQuest(quest); + + if (!questTemplate) { + return; + } + + const questFlags = questTemplate.GetFlags(); + + if (questFlags & QuestFlags.QUEST_FLAG_REPEATABLE) { + player.ModifyReputation(FACTION_ID, BONUS_REPUTATION); + player.SendBroadcastMessage("Thank you for your continued efforts! Here's a bonus to your reputation."); + } + + // Additional rewards or actions for other quest flags can be handled here. + if (questFlags & QuestFlags.QUEST_FLAG_EPIC) { + // Award special items or titles for completing an Epic quest. + } + + if (questFlags & QuestFlags.QUEST_FLAG_ESCORT) { + // Grant a temporary buff or special currency for completing an Escort quest. + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_QUEST_COMPLETE, (...args) => OnQuestComplete(...args)); +``` + +In this example: +1. We define constants for the quest entry, faction ID, and the amount of bonus reputation to award. +2. In the `OnQuestComplete` event handler, we retrieve the quest template using the `GetQuest` function. +3. We then get the quest flags using the `GetFlags` method of the quest template. +4. We check if the `QUEST_FLAG_REPEATABLE` flag is set using a bitwise AND operation. If it is, we award bonus reputation to the player using `ModifyReputation` and send a broadcast message to the player. +5. We also demonstrate how to handle other quest flags, such as `QUEST_FLAG_EPIC` and `QUEST_FLAG_ESCORT`, by adding comments for awarding special items, titles, buffs, or currencies. + +This example showcases how to use the `GetFlags` method to retrieve quest flags and make decisions based on them, such as awarding bonus rewards or triggering special actions for specific types of quests. + +## GetId +Returns the entry ID of the quest. This ID is unique to each quest and can be used to identify and look up the quest in the database or perform other actions based on the specific quest. + +### Parameters +This method does not take any parameters. + +### Returns +questId: number - The unique identifier of the quest. + +### Example Usage +Create a script that rewards players with bonus gold and experience when they complete specific quests. + +```typescript +const QUEST_GNOMEREGAN = 2904; +const QUEST_DEADMINES = 36; +const BONUS_GOLD = 500; +const BONUS_XP = 1000; + +const onQuestComplete: player_event_on_quest_complete = (event: number, player: Player, quest: Quest): void => { + const questId = quest.GetId(); + + switch (questId) { + case QUEST_GNOMEREGAN: + player.ModifyMoney(BONUS_GOLD); + player.GiveXP(BONUS_XP); + player.SendBroadcastMessage(`Congratulations on completing Gnomeregan! You have been awarded ${BONUS_GOLD} gold and ${BONUS_XP} experience.`); + break; + case QUEST_DEADMINES: + player.ModifyMoney(BONUS_GOLD); + player.GiveXP(BONUS_XP); + player.SendBroadcastMessage(`Well done on clearing the Deadmines! You have been granted ${BONUS_GOLD} gold and ${BONUS_XP} experience.`); + break; + default: + // No bonus for other quests + break; + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_QUEST_COMPLETE, (...args) => onQuestComplete(...args)); +``` + +In this example, we define constants for the specific quest IDs we want to reward (`QUEST_GNOMEREGAN` and `QUEST_DEADMINES`) and the bonus amounts for gold and experience. + +Inside the `onQuestComplete` event handler, we retrieve the quest ID using `quest.GetId()`. We then use a switch statement to check if the completed quest matches any of the specified quest IDs. + +If the quest ID matches `QUEST_GNOMEREGAN` or `QUEST_DEADMINES`, we reward the player with bonus gold using `player.ModifyMoney(BONUS_GOLD)` and bonus experience using `player.GiveXP(BONUS_XP)`. We also send a broadcast message to the player informing them of the bonus rewards they received. + +If the completed quest does not match any of the specified IDs, no bonus rewards are given. + +Finally, we register the `onQuestComplete` event handler to the `PLAYER_EVENT_ON_QUEST_COMPLETE` event using `RegisterPlayerEvent`. + +This script demonstrates how you can use the `GetId()` method to identify specific quests and perform actions based on the quest ID, such as granting bonus rewards to players who complete certain quests. + +## GetLevel +Returns the level of the quest. This is the level that is required to be able to accept the quest. + +### Parameters +This method does not take any parameters. + +### Returns +number - The level of the quest. + +### Example Usage +This example checks if the player is high enough level to accept a quest, and if not, it will send a message to the player and not allow them to accept the quest. + +```typescript +const QUEST_ENTRY = 1234; +const MIN_LEVEL = 10; + +const OnQuestAccept: player_event_on_quest_accept = (event: number, player: Player, quest: Quest) => { + if (quest.GetEntry() == QUEST_ENTRY) { + const questLevel = quest.GetLevel(); + const playerLevel = player.GetLevel(); + + if (playerLevel < questLevel) { + player.SendBroadcastMessage(`You must be at least level ${MIN_LEVEL} to accept this quest.`); + player.RemoveQuest(QUEST_ENTRY); + } else { + // Additional logic for when the player is high enough level to accept the quest. + // This could include sending a message to the player, granting items, or setting flags. + player.SendBroadcastMessage(`You have accepted the quest!`); + + // Example of granting an item to the player when they accept the quest. + const ITEM_ENTRY = 5678; + player.AddItem(ITEM_ENTRY, 1); + + // Example of setting a flag when the player accepts the quest. + player.SetFlag(PlayerFlags.PLAYER_FLAGS_HIDE_HELM, 1); + } + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_QUEST_ACCEPT, (...args) => OnQuestAccept(...args)); +``` + +In this example, when the player accepts a quest with the entry `QUEST_ENTRY`, it first checks the level of the quest using `quest.GetLevel()`. It then compares this level to the player's level using `player.GetLevel()`. + +If the player's level is below the quest level, it sends a message to the player using `player.SendBroadcastMessage()` and removes the quest from the player using `player.RemoveQuest()`. + +If the player's level is high enough, it sends a different message to the player, grants them an item using `player.AddItem()`, and sets a flag on the player using `player.SetFlag()`. + +This example demonstrates how you can use the `GetLevel()` method of the `Quest` class to create more complex quest acceptance logic based on the player's level and the quest's level requirement. + diff --git a/docs/classes/WorldObject.md b/docs/classes/WorldObject.md index 6976df1..ae6f356 100644 --- a/docs/classes/WorldObject.md +++ b/docs/classes/WorldObject.md @@ -287,3 +287,1629 @@ RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_MOVE, (...args) => onPlayerMove These examples depict how mod-eluna and AzerothCore can utilize the `GetExactDistance2d` method to enhance gameplay experiences by incorporating distance-based mechanics or triggers into custom scripts or quests. +## GetGameObjectsInRange + +Find game objects within a specified range from the current WorldObject. This can be further filtered by providing an optional game object entry ID and hostility flag. Useful for scripts that need to interact with or check for the presence of nearby game objects in the world. + +### Parameters +- **range**: number (optional) - The maximum distance to search for game objects. If not specified, a default range is used. +- **entryId**: number (optional) - The entry ID of the game objects to search for. If not provided, all game objects within range are considered. +- **hostile**: number (optional) - A flag indicating whether to include hostile (1), friendly (0), or all (undefined) game objects in the results. + +### Returns +- **gameObjects**: [GameObject](./gameobject.md)[] - An array of game objects within the specified range and, optionally, with the specified entry ID and hostility flag. + +### Example Usage: +Script to find and interact with a specific type of game object near the player. This example searches for all friendly game objects of entry ID 190000 within 50 yards of the player to simulate a quest interaction or area effect. + +```typescript +const GO_ENTRY_ID = 190000; // Example game object entry ID +const SEARCH_RANGE = 50; // Search within 50 yards + +const onPlayerInteract: player_event_on_custom_event = (event: number, player: Player) => { + const nearbyObjects = player.GetGameObjectsInRange(SEARCH_RANGE, GO_ENTRY_ID, 0); + + if(nearbyObjects && nearbyObjects.length > 0) { + nearbyObjects.forEach((gameObject) => { + // Perform an action with each game object, such as triggering a quest event + console.log(`Found a game object with entry ID ${GO_ENTRY_ID} within ${SEARCH_RANGE} yards.`); + // Trigger custom interaction here + }); + } else { + console.log("No suitable game objects found within the specified range."); + } +} +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_CUSTOM_EVENT, (...args) => onPlayerInteract(...args)); +``` +This script demonstrates how to search for specific game objects near the player character, check for their presence, and then execute a block of code to interact with each found object. It's a fundamental pattern for creating immersive and interactive environments in mods built on Azerothcore with mod-eluna. + +## GetInstanceId +Retrieves the instance ID of the WorldObject. This can be used in scenarios where identifying or differentiating among instances is necessary -- for example, in managing instance-specific data or behaviors. + +### Returns +number - The instance ID of the WorldObject. + +### Example Usage: +Suppose we want to create a greeting for players entering different instances of a dungeon. For example, when players enter the first instance of the dungeon, they receive one message, and when they enter a new instance, they receive a different message. This requires tracking the instance IDs to provide the appropriate greeting. + +```typescript +// Assume we have a function that fetches a greeting message based on the instance ID +function getDungeonGreeting(instanceId: number): string { + const greetings = { + 1: "Welcome to the first instance of the dungeon. Good luck!", + 2: "This is the second instance. Hope you're prepared!", + // Add more instance-specific greetings as needed + }; + + return greetings[instanceId] || "Welcome to the dungeon. Brave adventurers, beware!"; +} + +const onPlayerEnterDungeon: player_event_on_map_enter = (event: number, player: Player, mapId: number): void => { + // Check if the map is a dungeon (pseudo code, replace with actual condition) + if (isDungeonMap(mapId)) { + const instanceId = player.GetInstanceId(); + const greeting = getDungeonGreeting(instanceId); + + // Send the greeting to the player entering the dungeon + player.SendBroadcastMessage(greeting); + } +} + +// Register the event to handle player entering a map/dungeon +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_MAP_ENTER, (...args) => onPlayerEnterDungeon(...args)); +``` + +In this example, `GetInstanceId` is crucial for determining the correct greeting to display based on the instance ID. It enables a more dynamic and instance-specific interaction, enhancing the gameplay experience within modifiable environments like those in AzerothCore with mod-eluna. + +## GetLocation +This method returns the exact geographical coordinates and orientation of the `WorldObject` within the game world. This is particularly useful for scripts or mods that need to interact with objects based on their location. + +### Returns +A Lua multi-return value comprising four numbers: +- **`X` Coordinate** (`number`): The horizontal position on the map. +- **`Y` Coordinate** (`number`): The vertical position on the map. +- **`Z` Coordinate** (`number`): The height or altitude at the position. +- **`Orientation`** (`number`): The direction the object is facing, represented in radians. + +### Example Usage: +The following script can be used to teleport a player to the location of a specific world object, such as an NPC or a game object. It captures the `WorldObject`'s location and applies it to the player's position. This can be particularly useful for custom quests or events where a player needs to be moved to a specific location. + +```typescript +const TELEPORT_NPC_ENTRY = 12345; // Example NPC entry ID + +// Event handler for when a player interacts with a specific NPC +const OnNPCInteract: player_event_on_gossip_hello = (event: number, player: Player, npc: Creature): void => { + if (npc.GetEntry() === TELEPORT_NPC_ENTRY) { + const [x, y, z, orientation] = npc.GetLocation(); + + // Teleporting player to the NPC's location + player.Teleport(player.GetMapId(), x, y, z, orientation); + + // Optional: Send a chat message to the player confirming the teleport + player.SendAreaTriggerMessage("You have been teleported!"); + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_GOSSIP_HELLO, (...args) => OnNPCInteract(...args)); +``` + +In this example, the script listens for an interaction event with an NPC. If the interacted NPC matches the specified entry ID, it retrieves the NPC's location using `GetLocation()` and teleports the player to that exact location. Optionally, it sends a chat message to the player, confirming the action. This script can be modified to accommodate various scenarios, like teleporting a player to different NPCs or objects based on certain conditions. + +# GetMap + +Retrieve the current [Map](./map.md) object that the [WorldObject](./worldobject.md) is located in. + +### Returns +- **EMap** - The map object in which the WorldObject is currently present. + +### Example Usage: + +In this scenario, we want to execute an action specific to a map when a player interacts with a WorldObject, such as a custom teleporter or an interactive lore object. This script checks the map ID of the object when a player interacts with it. If the object is in a specific map, a unique message is displayed or a specific action is taken. + +```typescript +const TARGET_MAP_ID = 571; // Example map ID, for Northrend (WotLK) + +const onObjectInteract: worldobject_event_on_go_use = (event: number, player: Player, worldObject: WorldObject): void => { + const objectMap = worldObject.GetMap(); + + if(objectMap.GetMapId() === TARGET_MAP_ID) { + // Perform actions specific to the object being in Northrend + player.SendBroadcastMessage("This mystical object pulses with energy from Northrend."); + // Additional action, such as teleportation or initiation of a custom quest/event + } else { + player.SendBroadcastMessage("This object seems dormant in this land."); + } +} + +RegisterWorldObjectEvent(WorldObjectEvents.WORLDOBJECT_EVENT_ON_GO_USE, (...args) => onObjectInteract(...args)); +``` + +This script makes use of the `GetMap` method to obtain the current map of the WorldObject. Checking the map ID allows for context-specific interactions, adding depth to player experiences in different world zones. This can be particularly useful for creating dynamic world events, custom quests, or unique player interactions based on the location of objects within the game world. + +For more detailed information on map methods and properties, please refer to the [Map documentation](./map.md). + +## GetMapId +This method retrieves the current map ID where the WorldObject is located. Maps in AzerothCore are essentially different zones or instances within the game world. Each map has a unique ID which is used internally to manage locations, spawns, and events within the game. Knowing the map ID of a `WorldObject` can be crucial for scripts that need to operate differently based on the location of an object, player, or NPC. + +### Returns +mapId: number - The numeric ID of the map where the WorldObject is located. + +### Example Usage: +Let's say we want to create a custom script that congratulates players whenever they enter a specific zone, for demonstration purposes we'll use Stormwind City with a map ID of 0. This script will check the player's map ID upon movement and send a congratulation message if they've just arrived in Stormwind City. + +```typescript +const STORMWIND_CITY_MAP_ID = 0; +const WELCOME_MESSAGE = "Welcome to Stormwind City, the heart of the Alliance!"; + +const onPlayerMove: player_event_on_movement = (event: number, player: Player): void => { + // Check if the player's current map ID matches Stormwind City's ID. + if(player.GetMapId() === STORMWIND_CITY_MAP_ID) { + // Send a welcome message to the player. + player.SendBroadcastMessage(WELCOME_MESSAGE); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_MOVEMENT, (...args) => onPlayerMove(...args)); +``` + +In this example, the `RegisterPlayerEvent` function hooks into the player movement event. The callback `onPlayerMove` is executed whenever a player moves, and it uses the `GetMapId()` method of the `player` object to check if the player is in Stormwind City by comparing the current map ID with `STORMWIND_CITY_MAP_ID`. If the condition is met, a welcoming message is sent to the player using the `SendBroadcastMessage` method. + +This script can be tailored further based on requirements, such as adding checks to ensure the message is only sent once upon entering the city or adapting it for other map zones. + +Notice: The example code and constants (e.g., `STORMWIND_CITY_MAP_ID` and `WELCOME_MESSAGE`) are created for demonstration purposes. Always refer to your project's documentation or source code for accurate map IDs and API usage. + +# GetName + +Retrieve the name of the [WorldObject]. This can be useful for identification purposes in various scripts, such as identifying NPCs or objects in the world. + +### Returns +name: string - The name of the WorldObject. + +### Example Usage: +Efficiently checking if a player is interacting with a specific NPC and responding with a custom message. + +```typescript +const NPC_TO_FIND = "Thrall"; +const WELCOME_MESSAGE = "Lok'tar Ogar, champion! What brings you to me today?"; + +const onGossipHello: gossip_hello = (event: number, player: Player, unit: WorldObject): void => { + + // Check if the target NPC's name matches the one we're looking for + if(unit.GetName() === NPC_TO_FIND) { + // Send a custom welcome message to the player + player.SendBroadcastMessage(WELCOME_MESSAGE); + } +} + +RegisterPlayerGossipEvent(GossipEvents.GOSSIP_EVENT_ON_HELLO, (...args) => onGossipHello(...args)); +``` + +This script demonstrates how to utilize the `GetName` method to personalize player-NPC interactions. Upon a gossip event (usually a right-click interaction), it checks if the WorldObject's name matches "Thrall". If it does, a custom welcome message is broadcasted to the player. This implementation can enhance immersion and open up possibilities for dynamic questing, NPC interactions, or server events. + +## GetNearObject +Returns the nearest `WorldObject` in sight of the calling `WorldObject` that matches the specified criteria. This can be useful for scripts that need to interact with or check the presence of nearby objects, such as NPCs, players, or game objects. The search criteria include range, type, entry, hostility, and whether the object is dead or alive. + +### Parameters +- `range`: number (optional) - The maximum distance to search for the object. Defaults to checking within the entire visible area if not specified. +- `type`: number (optional) - The type of the object to search for. Use constants defined for object types, such as `GameObjectTypes` or `CreatureTypes`. +- `entry`: number (optional) - The specific entry ID of the object to search for. Useful for finding objects of a specific kind, such as a quest NPC or a specific kind of game object. +- `hostile`: number (optional) - Specifies whether to search for hostile (`1`), friendly (`0`), or any (`-1`) objects relative to the WorldObject. Defaults to `-1` if not specified. +- `dead`: number (optional) - Specifies whether to include dead (`1`), alive (`0`), or both types of entities (`-1`) in the search. Useful for abilities or mechanics that affect or detect dead entities. + +### Returns +- `WorldObject` - The nearest `WorldObject` that matches the given criteria. Returns `null` if no matching object is found. + +### Example Usage +The following script demonstrates how to use `GetNearObject` to find nearby hostile NPCs within a range of 50 units. If a matching hostile NPC is found, it prints the NPC's entry ID and name to the server log. This can be useful for creating custom NPC interactions or for scripts that need to monitor the presence of certain NPCs. + +```typescript +const HOSTILE_NPC_TYPE = 4; // Assuming 4 represents the NPC type +const SEARCH_RANGE = 50; +const HOSTILE_SEARCH = 1; +const ALIVE_ONLY = 0; + +// Custom event handler for when a specific event occurs +const OnCustomEvent: custom_event_handler = (player: Player) => { + // Use GetNearObject to search for a nearby hostile NPC within 50 units + const nearestHostileNPC = player.GetNearObject(SEARCH_RANGE, HOSTILE_NPC_TYPE, undefined, HOSTILE_SEARCH, ALIVE_ONLY); + + if (nearestHostileNPC) { + // If a hostile NPC is found, log its entry ID and name + console.log(`Found hostile NPC with Entry ID: ${nearestHostileNPC.GetEntry()}, Name: ${nearestHostileNPC.GetName()}`); + } else { + // If no hostile NPC is found within range + console.log(`No hostile NPCs found within ${SEARCH_RANGE} units.`); + } +}; + +RegisterCustomEvent(customEventId, (...args) => OnCustomEvent(...args)); +``` + +In this example, `custom_event_handler` and `RegisterCustomEvent` are placeholders meant to represent how you might hook this functionality into an appropriate event within your mod or script. Adjust these parts according to your actual event handling system. + +## GetNearObjects + +This method returns an array of [WorldObject](./worldobject.md) IDs that are within sight of the calling [WorldObject], based on various filters such as range, type, entry ID, hostility, and whether the object is dead or alive. + +### Parameters +- `range` (optional): number - Search radius in game units. If omitted, a default range is used. +- `type` (optional): number - Type of WorldObjects to search for. This could be specific values like NPCs, players, etc. If omitted, all types are considered. +- `entry` (optional): number - Entry ID of the WorldObject to search for. Useful for finding objects of a specific kind, like a certain NPC. If omitted, all entry IDs are considered. +- `hostile` (optional): number - Specifies whether to look for hostile (1), friendly (0), or both types of WorldObjects towards the caller. If omitted, both are considered. +- `dead` (optional): number - Specifies whether to include dead (1) or alive (0) WorldObjects. If omitted, both states are considered. + +### Returns +- `objectIds`: number[] - An array of WorldObject IDs that match the criteria. + +### Example Usage: +The example script demonstrates finding all nearby hostile NPCs within a 50-unit range and printing their IDs to the server console. This could be useful for a custom event where a player or NPC must interact with or avoid specific other NPCs within their vicinity. + +```typescript +const FindHostileNpcsInRange: worldobject_event_on_update = (event: number, obj: WorldObject): void => { + // Assuming '1' represents NPCs in the 'type' filter, and '1' also signifies 'hostile' + const hostileNpcs = obj.GetNearObjects(50, 1, undefined, 1); + + // Logging the count of found NPCs + console.log(`Found ${hostileNpcs.length} hostile NPCs within range.`); + + // Assuming there is a method to get WorldObject by ID for detailed operations + hostileNpcs.forEach(npcId => { + const npc = GetWorldObjectById(npcId); + console.log(`Hostile NPC ID: ${npcId}, Name: ${npc.GetName()}`); + }); +} + +RegisterWorldObjectEvent(WorldObjectEvents.WORLDOBJECT_EVENT_ON_UPDATE, (...args) => FindHostileNpcsInRange(...args)); +``` + +This script utilizes the hypothetical method `GetWorldObjectById` to further interact with each found NPC, such as retrieving their name. The constants and method names used, like the event types and `GetWorldObjectById`, are for illustrative purposes and should be replaced with the actual implementations available in your modding environment. + +## GetNearestCreature +Finds and returns the nearest creature in sight of the WorldObject based on specified criteria. This can include range, creature entry ID, hostile status, and whether the creature is alive or dead. + +### Parameters
+- `range?`: number (optional) - The maximum distance to search for a nearby creature. If not specified, the default search range is used. +- `entryId?`: number (optional) - The entry ID of the creature to search for. If not specified, any nearby creature can be returned. +- `hostile?`: number (optional) - Specifies whether to search for hostile creatures (`1` = yes, `0` = no). If not specified, both hostile and friendly creatures are considered. +- `dead?`: number (optional) - Specifies whether to include dead creatures in the search (`1` = yes, `0` = no). If not specified, only living creatures are considered. + +### Returns +- `creature`: [Creature](./creature.md) - The nearest creature that matches the specified criteria. + +### Example Usage: +Script to check for nearby hostile creatures within a 30-yard range and alert the player if any are found. + +```typescript + +// Define a custom event for players entering a specific area +const onPlayerEnterArea: player_event_on_update_zone = (event: number, player: Player, newZone: number, newArea: number): void => { + + // Specify the search criteria + const HOSTILE_CREATURE_ENTRY_ID = 12345; // Example creature entry ID + const SEARCH_RANGE = 30; // 30-yard search range + const HOSTILE_STATUS = 1; // Search for hostile creatures + const INCLUDE_DEAD = 0; // Exclude dead creatures from search + + // Find the nearest hostile creature within the range + const nearestHostileCreature = player.GetNearestCreature(SEARCH_RANGE, HOSTILE_CREATURE_ENTRY_ID, HOSTILE_STATUS, INCLUDE_DEAD); + + if (nearestHostileCreature) { + player.SendBroadcastMessage(`Beware! A hostile creature lurks nearby.`); + } + else { + player.SendBroadcastMessage(`The area is clear. No immediate threats detected.`); + } +}; + +// Registers the event to be triggered upon player zone update +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_UPDATE_ZONE, (...args) => onPlayerEnterArea(...args)); +``` +In this example, a custom event is created to execute whenever a player updates their zone (which could be upon entering a new area, for example). The script searches for the nearest hostile creature within a 30-yard radius. If a matching creature is found, the player is alerted of a nearby threat. This can be particularly useful for custom quests or zones where player awareness of potential dangers is crucial. + +## GetNearestGameObject +Retrieves the nearest [GameObject](./gameobject.md) within the sight of the [WorldObject], allowing for optional filtering based on range, entry ID, and hostility. + +### Parameters
+* `range`: number (Optional) - The maximum distance to search for the GameObject. +* `entryId`: number (Optional) - Specific entry ID of the GameObject to find. +* `hostile`: number (Optional) - Hostility flag, where applicable, to filter GameObjects based on their hostility status. + +### Returns +* gameObject: [GameObject](./gameobject.md) - The nearest GameObject found based on the provided criteria. Returns `null` if no suitable GameObject is found. + +### Example Usage: +Script for a custom event where players must find a specific object within a range. This could be part of a scavenger hunt quest where players have to find hidden objects around them. + +```typescript +const SCAVENGER_HUNT_OBJECT_ENTRY_ID = 190000; // Example entry ID for the scavenger hunt object +const SEARCH_RANGE = 50; // The search range in game units + +// Handler for when a player triggers the custom scavenger hunt quest +const StartScavengerHunt: player_event_on_custom = (event: number, player: Player): void => { + // Attempt to find the nearest scavenger hunt object within range + const nearestObject = player.GetNearestGameObject(SEARCH_RANGE, SCAVENGER_HUNT_OBJECT_ENTRY_ID); + + if(nearestObject) { + player.SendBroadcastMessage(`You have found the object: ${nearestObject.GetGUID()}! Return to the quest giver.`); + // Implement additional logic for when the player finds the object + // For example, updating a quest status, giving a reward, etc. + } else { + player.SendBroadcastMessage(`No scavenger hunt objects found within range. Keep looking!`); + } +}; + +// Register the custom event with a hypothetical event handler for when a player starts the scavenger hunt quest +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_CUSTOM, (...args) => StartScavengerHunt(...args)); +``` +In this example, when a player engages with the scavenger hunt quest, they are tasked with finding a specific GameObject within a predefined range. The script uses the `GetNearestGameObject` method to find the nearest object that matches the criteria (in this case, an object with a specific entry ID within a certain range). If such an object is found, the player is notified of their success; otherwise, they are encouraged to continue searching. + +## GetNearestPlayer +Find the nearest player to the `WorldObject`, optionally filtering based on range, hostility, and life status. + +### Parameters +- `range?`: number (optional) - The maximum distance to look for the player. If not specified, uses default sight range. +- `hostile?`: number (optional) - If set to 1, only searches for hostile players. If set to 0, ignores hostility. If not specified, includes all players regardless of hostility. +- `dead?`: number (optional) - If set to 1, includes dead players in the search. If set to 0 or not specified, only searches for alive players. + +### Returns +- `player`: [Player](./player.md) - The nearest [Player] object found within the criteria or `null` if no suitable player was found. + +### Example Usage: +Script to notify a player when they come close to an enemy player, potentially triggering a PvP scenario. + +```typescript +const onWorldObjectUpdate: world_object_event_on_update = (event: number, worldObject: WorldObject): void => { + // Try to find a nearby hostile player within 20 yards + const nearestHostilePlayer = worldObject.GetNearestPlayer(20, 1, 0); + + if (nearestHostilePlayer != null) { + // Inform the player about the nearby hostile + nearestHostilePlayer.SendMessage("[Warning]: You are close to an enemy player!"); + } +} + +RegisterWorldObjectEvent(WorldObjectEvents.WORLD_OBJECT_EVENT_ON_UPDATE, (...args) => onWorldObjectUpdate(...args)); +``` + +This script attaches to the world object update event. It uses the `GetNearestPlayer` method to search for the nearest player within a 20-yard range who is hostile and alive. If such a player is found, it sends a warning message to the player, alerting them of the nearby enemy. This could be used in custom PvP encounters, questing areas with PvP-enabled objectives, or simply to enhance the world's interactiveness in PvP-enabled zones. + +## GetO +Retrieve the current orientation of the WorldObject in the game world. This method will provide the direction where the object is facing in terms of radians. Orientation is measured clockwise from the north direction, and can be used to position or rotate objects correctly within the game environment. + +### Returns +orientation: number - The current orientation of the WorldObject in radians. + +### Example Usage: +This script sets an NPC to face towards a specific orientation when a player interacts with it, creating a dynamic interaction where the NPC appears to turn towards a point of interest based on the player's action. + +```typescript +const NPC_ENTRY = 12345; // Example NPC Entry ID from creature_template +const SPECIFIC_ORIENTATION = 4.71239; // 270 degrees in radians; West + +const OnNPCInteract: npc_event_on_gossip_hello = (event: number, player: Player, npc: Creature) => { + if (npc.GetEntry() == NPC_ENTRY) { + npc.SetOrientation(SPECIFIC_ORIENTATION); + player.SendBroadcastMessage("The NPC turns to face West."); + } +} + +RegisterCreatureGossipEvent(NPC_ENTRY, NpcEvents.NPC_EVENT_ON_GOSSIP_HELLO, (...args) => OnNPCInteract(...args)); +``` +In this example, the `SetOrientation` method is hypothetically used to change the NPC's facing direction and is not part of the original class definitions provided. However, this showcases how to utilize the `GetO` method in a practical scenario, ensuring the NPC faces a predetermined direction when a player interacts with it. This can enhance gameplay by adding a level of interaction and realism to NPC behaviors. + +## GetPhaseMask +This method retrieves the current phase mask of the WorldObject. In AzerothCore, phases are a way to control the visibility and interaction of objects, NPCs, and players within the world. Depending on the phase mask a player is in, they might see different NPCs, objects, or even complete different versions of quests. This method is particularly useful for scripting events or quests that require phase changes or checks. + +### Returns +`phaseMask`: number - The phase mask assigned to the WorldObject. The phase mask is a bitmask with each bit representing a different phase. A phase mask of 1 represents the base phase that all players are in by default. Higher numbers represent custom phases. + +### Example Usage +In this example, we're scripting a custom quest that teleports the player to a different phase once they reach a certain area, and we want to make sure they're not already in that phase to avoid unnecessary teleportation or phase changes. + +```typescript +const PHASE_QUEST_AREA = 2; // Assume this is the phase for the special quest area + +const OnPlayerMove: player_event_on_update_zone = (event: number, player: Player, newZone: number, newArea: number): void => { + // Assuming 1000 is the area ID of interest + if (newArea === 1000) { + const currentPhase = player.GetPhaseMask(); + + // Check if player is not already in the quest phase + if (currentPhase !== PHASE_QUEST_AREA) { + player.SetPhaseMask(PHASE_QUEST_AREA, true); // This hypothetical method sets the player's phase + player.SendMessage("You feel the world around you change..."); + } + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_UPDATE_ZONE, (...args) => OnPlayerMove(...args)); +``` + +In this script, when players move into the area with the ID of 1000, the game checks their current phase. If they're not already in the quest phase (designated with a phase mask of `2`), it changes their phase to match the quest requirements. A message is broadcasted to the player to notify them of this change, enhancing the immersive experience. + +This is a crucial tool for developers when working with phased content, allowing for dynamic and engaging player experiences based on their progression and actions within the game world. + +## GetPlayersInRange +This method retrieves a list of [Player](./player.md) objects that are within a certain range of the [WorldObject]. The method can further filter the players based on whether they are hostile or not, and whether they include dead players. + +### Parameters +- `range`: number (optional) - Specifies the range in yards within which players should be detected. If not specified, uses the default visibility range. +- `hostile`: number (optional) - Specifies whether to include hostile (`1`), friendly (`0`), or both types of players (`2`). If not specified, it defaults to include both. +- `dead`: number (optional) - Specifies whether to include dead players (`1`) in the result. Alive players are always included. If not specified, dead players are not included. + +### Returns +- `players`: Array of [Player](./player.md) - A list of player objects found within the specified range and under the specified conditions. + +### Example Usage: +Script to send a warning message to all nearby hostile players when an important NPC is attacked. +```typescript +const NPC_ENTRY_ID = 12345; // Example NPC entry ID +const WARNING_RANGE = 50; // Yards + +const OnNPCAttacked: npc_event_on_receive_damage = (event: number, creature: Creature, attacker: Unit): void => { + if(creature.GetEntry() === NPC_ENTRY_ID) { + const nearbyHostilePlayers = creature.GetPlayersInRange(WARNING_RANGE, 1, 0); + + nearbyHostilePlayers.forEach(player => { + player.SendAreaTriggerMessage("You dare to attack our leader? Guards, to me!"); + }); + } +} + +RegisterCreatureEvent(NPC_ENTRY_ID, CreatureEvents.CREATURE_EVENT_ON_JUST_TOOK_DAMAGE, (...args) => OnNPCAttacked(...args)); +``` +In this example, when a specific NPC (identified by `NPC_ENTRY_ID`) is attacked, it triggers a search for hostile players within a 50-yard range (`WARNING_RANGE`). For each hostile player found, a warning message is sent. This scenario can enhance the immersion and interaction within the game, setting up potential PvP encounters or alerting players to the presence of an important NPC under attack. + +Based on the provided Player class examples, here is how the documentation for the WorldObject's `GetRelativePoint` method could be formatted into a consistent markdown documentation style for modding with mod-eluna on AzerothCore. + +## GetRelativePoint +Calculates the coordinates `(x, y, z)` of a point that is a certain distance away from the `[WorldObject]`, taking into account the provided angle. This is especially useful for positioning objects or characters in the world relative to an existing WorldObject, such as spawning NPCs in a circle around a central point. + +### Parameters
+* `distance`: number - The distance from the `[WorldObject]` to the desired point. +* `angle`: number - The angle (in radians) at which to project the point from the `[WorldObject]`. + +### Returns +* `(x, y, z)`: LuaMultiReturn<[number, number, number]> - A tuple containing the x, y, and z coordinates of the calculated point. + +### Example Usage: +Let's say you want to create a script that spawns guardians in a circle around a player when they enter a specific zone. Here's how you might use `GetRelativePoint` to calculate the spawn points for these guardians. + +```typescript +const ZONE_ID = 123; // Example zone ID +const GUARDIAN_ENTRY_ID = 98765; // NPC Entry ID of the guardian +const NUM_GUARDIANS = 8; // Number of guardians to spawn +const SPAWN_DISTANCE = 5; // Distance from the player at which to spawn the guardians + +const onPlayerZone: player_event_on_zone = (event: number, player: Player, newZoneId: number, newAreaId: number): void => { + if (newZoneId === ZONE_ID) { + const angleStep = 2 * Math.PI / NUM_GUARDIANS; // Divide a circle into equal parts based on the number of guardians + for (let i = 0; i < NUM_GUARDIANS; i++) { + const angle = i * angleStep; + const [x, y, z] = player.GetRelativePoint(SPAWN_DISTANCE, angle); + // Here, you would spawn the guardian at the calculated coordinates + // This is a conceptual example, actual NPC spawning code would depend on your server's API + console.log(`Spawn guardian ${i + 1} at (${x}, ${y}, ${z})`); + } + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_ZONE, (...args) => onPlayerZone(...args)); +``` + +In this example, when a player enters the specified zone, the script calculates points in a circle around the player to spawn guardians evenly distributed. `GetRelativePoint` is used to find each point's coordinates, ensuring guardians are placed at the correct distance and angle from the player. + +## GetX +Retrieves the current X coordinate position of the WorldObject within the game world. This can be valuable for numerous calculations such as distance checks, location validation, and more within custom scripts or modules. + +### Returns +X: number - The current X coordinate of the WorldObject. + +### Example Usage: +In the example below, we illustrate how to use the `GetX` method within a custom event handling function to determine a player's current location when they enter combat. This might be useful for scenarios where player position is crucial, such as initiating specific world events based on player coordinates, custom battleground mechanisms, or simply for gathering data on player movement across zones for analysis. + +```typescript +const onPlayerEnterCombat: player_event_on_enter_combat = (event: number, player: Player, enemy: Unit): void => { + const playerX = player.GetX(); + console.log(`Player entered combat at X coordinate: ${playerX}`); + + // Example: Trigger a custom event if the player is within a specific X coordinate range + if (playerX > 1000 && playerX < 2000) { + console.log("Player is within the event zone!"); + // Trigger a custom event or function based on player location + // triggerCustomEventBasedOnLocation(player); + } else { + console.log("Player is outside the event zone."); + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_ENTER_COMBAT, (...args) => onPlayerEnterCombat(...args)); +``` + +In this script, when a player enters combat, it logs their current X position and checks if they are within a specified range (X coordinates 1000 to 2000). If the player is within this range, a custom log message is printed, potentially triggering other custom events or functions tailored to this location. Such precise handling enables developers to create immersive and dynamic content responsive to player actions and locations. + +## GetY + +This method allows you to obtain the current Y coordinate of the [WorldObject]. This can be particularly useful when you need to perform actions based on the object's location in the world. + +### Returns + +number: The Y coordinate of the [WorldObject] + +### Example Usage: + +In this example, we will create a simple script that broadcasts a message in the world chat, informing players of the Y coordinate of a particular [WorldObject]. This could be particularly useful for custom events or quests where the location of an object or NPC matters. + +```typescript +const BroadcastObjectYCoordinate: world_event_on_chat = (event: number, player: Player, msg: string, type: number, lang: number, receiver: Player) => { + // Assuming there's a WorldObject of interest, like a unique NPC or object in the game + let worldObject: WorldObject; // This would be obtained through some other means in a real script + + let yCoordinate = worldObject.GetY(); + let broadcastMessage = `The Y coordinate of the special object is: ${yCoordinate}. Hurry up and find it!`; + + // Broadcasts the Y coordinate in the world chat + ChatHandler.SendGlobalSysMessage(broadcastMessage); +} + +RegisterWorldEvent(WorldEvents.WORLD_EVENT_ON_CHAT, (...args) => BroadcastObjectYCoordinate(...args)); +``` + +In this script: +- We assume there is a specific `WorldObject` we're interested in. This object could be anything from an NPC to a unique object in the game world. +- We obtain the Y coordinate of this object by using the `GetY()` method. +- We then construct a message that includes this Y coordinate. +- Finally, we broadcast this message to all players in the server using `ChatHandler.SendGlobalSysMessage()`, encouraging them to find the special object based on its Y coordinate. + +This script illustrates how you can use the `GetY()` method in a practical scenario to enhance gameplay or event participation, by guiding players towards a specific in-game location. + +## GetZ +Retrieves the current Z coordinate (height/altitude) of the WorldObject. This can be particularly useful for determining the position of a player, NPC, or object within the game world, especially when working with height-related functionalities such as flying or jumping. + +### Returns +number: The Z coordinate of the WorldObject. + +### Example Usage: +This script shows how to use the GetZ method to check if a player is above a certain height before allowing them to engage in a scripted event. It demonstrates handling player altitude in custom script events. + +```typescript +const PLAYER_EVENT_ON_CUSTOM_SCRIPT = 1; // Custom event ID for demonstration +const REQUIRED_ALTITUDE = 100; // Example required altitude to trigger the event + +const checkPlayerAltitude: player_script_event = (eventId: number, player: Player): void => { + const playerAltitude = player.GetZ(); + + if(playerAltitude > REQUIRED_ALTITUDE) { + // Player is above the required altitude + player.SendBroadcastMessage("You are high enough!"); + // Trigger event or action based on altitude + // For example, enable access to a special flying challenge or area + } else { + // Player is not high enough + player.SendBroadcastMessage("You need to be higher to start this challenge!"); + } +} + +RegisterPlayerEvent(PLAYER_EVENT_ON_CUSTOM_SCRIPT, (...args) => checkPlayerAltitude(...args)); +``` + +This example uses a custom player event to check the player's altitude when the event is triggered. Depending on the player's Z coordinate (`GetZ()`), it either allows them to proceed with an action/event or notifies them that they need to be at a higher altitude. Use cases include creating altitude-based triggers or conditions within custom scripts and mods for AzerothCore. + +## GetZoneId +Retrieve the current zone ID where the [WorldObject] is located. This can be especially useful when writing scripts that require behavior changes based on the zone a player or another world object is in. For example, triggering specific events only in certain zones. + +### Returns +zoneId: number - The ID of the zone. Zone IDs can be mapped to their respective names and details by consulting the `area_table` in the AzerothCore database. + +### Example Usage: + +A simple script to warn players entering a specific zone (e.g., a zone with ID 1234) that they are entering a dangerous area. + +```typescript +const ZONE_DANGEROUS_AREA = 1234; +const WARNING_MESSAGE = "You are entering a dangerous area! Be prepared for tough battles."; + +const onPlayerEnterZone: world_object_event_on_update_zone = (event: number, player: Player): void => { + // Check if the WorldObject is a Player and in the dangerous zone + if (player.GetZoneId() == ZONE_DANGEROUS_AREA) { + player.SendBroadcastMessage(WARNING_MESSAGE); // Send a warning message to the player + } +} + +// Register event to check each time a player changes zones +RegisterWorldObjectEvent(WorldObjectEvents.WORLD_OBJECT_EVENT_ON_UPDATE_ZONE, (...args) => onPlayerEnterZone(...args)); +``` + +This script utilizes the `GetZoneId` method to get the current zone of the player. When a player enters the zone with ID 1234, it sends a broadcast message warning them about the upcoming challenges. This is a simple yet effective way of dynamically interacting with players based on their location within the game world. + +## IsInBack +Determines if the target is within a specified arc behind the [WorldObject]. This method is useful for implementing mechanics that require positional awareness, such as backstab attacks in combat scenarios. + +### Parameters +* target: [WorldObject](./worldobject.md) - The target object to check the position of. +* arc: number (optional) - The arc angle in degrees to consider as "behind". If not specified, a default value defined by the implementation might be used. + +### Returns +* boolean: Returns `true` if the target is in the specified arc behind the WorldObject, `false` otherwise. + +### Example Usage: + +In this example, a rogue character is implementing a backstab attack that can only be executed if the target is within a 90-degree arc behind the character. The specific arc value can be adjusted based on game mechanics or skill descriptions. + +```typescript +const rogueBackstab: player_event_on_spell_cast = (event: number, player: Player, spellId: number, target: WorldObject): void => { + // Assuming 1787 is the Spell ID for "Backstab" + if (spellId === 1787) { + // Check if the target is within a 90-degree arc behind the player + if (player.IsInBack(target, 90)) { + // Proceed with backstab mechanics, possibly including damage calculations + console.log(`Backstab success! Target is in the required position.`); + // Implement additional backstab logic here + } else { + console.log(`Backstab failed: Target needs to be behind the player.`); + // Handle the case where the player cannot backstab due to positioning + // This might involve cancelling the spell cast, notifying the player, etc. + } + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_SPELL_CAST, (...args) => rogueBackstab(...args)); +``` +In this scenario, the `IsInBack` method is crucial for determining the positional validity of executing certain abilities such as a rogue's backstab. The example demonstrates how one might check for positional requirements before allowing specific combat actions to proceed. This increases the depth and strategy involved in combat encounters within the game. + +# IsInFront + +This method checks if a target is within a specified arc in front of the `WorldObject`. This can be particularly useful for determining if an entity is facing another before performing an action, such as casting a spell or initiating combat. + +### Parameters +- `target`: [WorldObject](./worldobject.md) - The target to check against. +- `arc`: number (optional) - The arc angle in radians. If not specified, a default value is used. + +### Returns +- `boolean`: Returns `true` if the target is within the specified arc in front of the `WorldObject`, otherwise returns `false`. + +### Example Usage + +Let's create a scenario where a caster checks if their target is in front of them within a 180-degree arc before casting a spell. This ensures the caster only performs the action if facing the target, adding a layer of strategy and realism to the encounter. + +```typescript +const SPELL_CAST_EVENT = (caster: WorldObject, target: WorldObject): void => { + // Define the arc as Pi radians (180 degrees) + const arcInRadians = Math.PI; + + // Check if the target is in front within the 180-degree arc + if(caster.IsInFront(target, arcInRadians)) { + // Cast the spell or perform the action here + console.log(`Casting spell on target: ${target.GetGUID()}`); + } else { + console.log(`Target is not in front within the specified arc. Cannot cast spell.`); + } +} + +// Example registration for the event, depending on how your mod handles events +RegisterSomeEvent(SOME_EVENT_ID, (...args) => SPELL_CAST_EVENT(...args)); +``` + +In this example, `SPELL_CAST_EVENT` is a function designed to take in a caster and a target `WorldObject`. Before performing the spell cast, it uses `IsInFront` to determine if the target is within a 180-degree arc in front of the caster. This approach can be particularly useful in mods where facing direction and positioning play critical roles in gameplay mechanics. + +# IsInMap +Determines if two WorldObjects are located within the same map. This method is essential for checking spatial relations without needing the exact positions of the objects. Known applications include verifying if two characters can interact based on their current maps or triggering map-specific events based on player locations. + +### Parameters +- `worldobject`: [WorldObject](./worldobject.md) - Another WorldObject to check against. + +### Returns +- `boolean` - Returns `true` if both WorldObjects are on the same map, `false` otherwise. + +### Example Usage: +Suppose there's a scenario where a special event should be triggered only if a certain NPC (Non-Player Character) and a player are in the same map. The following scripted event demonstrates how `IsInMap` could be utilized to check for this condition and initiate a quest or a dialogue accordingly. + +```typescript +// Assuming there's an NPC with a known GUID (Global Unique Identifier) +const SPECIAL_NPC_GUID: number = 123456789; + +const TriggerSpecialEvent: player_event_on_update_zone = (event: number, player: Player): void => { + const npc: WorldObject = GetWorldObjectByGUID(SPECIAL_NPC_GUID); + + // Check if player and NPC are in the same map + if (player.IsInMap(npc)) { + console.log("Both player and the special NPC are in the same map. Triggering event..."); + + // Trigger a special quest or dialogue + StartSpecialQuest(player); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_UPDATE_ZONE, (...args) => TriggerSpecialEvent(...args)); + +function StartSpecialQuest(player: Player): void { + // Code to start a quest or interaction + console.log(`Starting special event for ${player.GetName()}`); +} +``` + +In this example, the `TriggerSpecialEvent` function is called every time a player changes zones (including moving to a different map). It retrieves a `WorldObject` for a specific NPC using a simulated `GetWorldObjectByGUID` function (Pseudocode, as accessing NPCs directly is not part of the provided API). It then checks whether the player and the NPC are on the same map using the `IsInMap` method of the `Player` class, which inherits from `WorldObject`. If they are on the same map, a special event is initialized for that player. + +## IsInRange +This method checks if the target `WorldObject` is within a specific range from the caller `WorldObject`. The option to measure distance in two or three dimensions provides versatility in determining proximity for various gameplay elements. + +### Parameters +- `target`: [WorldObject](./worldobject.md) - The WorldObject to check the distance to. +- `minrange`: number - The minimum distance from the caller WorldObject. The target is considered in range if it is further than this. +- `maxrange`: number - The maximum distance from the caller WorldObject. The target is considered in range if it is closer than this. +- `is3D`: boolean (optional) - If true, the distance is measured considering all three dimensions (x, y, z). Otherwise, only the horizontal distance (x, y) is considered. + +### Returns +- `boolean` - Returns `true` if the target is within the specified range, `false` otherwise. + +### Example Usage: +Check if a player needs to be closer to an NPC to start a quest interaction, considering only horizontal distance. +```typescript +const NPC_ENTRY_FOR_QUEST = 12345; +const INTERACTION_RANGE_MIN = 0; +const INTERACTION_RANGE_MAX = 5; + +// This event is triggered when a player moves. +const OnPlayerMovement: player_event_on_movement = (event: number, player: Player): void => { + const nearbyNpcs = player.GetNearbyCreatures(INTERACTION_RANGE_MAX, NPC_ENTRY_FOR_QUEST); + nearbyNpcs.forEach(npc => { + // Check if the NPC is within interaction range + if (player.IsInRange(npc, INTERACTION_RANGE_MIN, INTERACTION_RANGE_MAX, false)) { + // Proceed with quest interaction + console.log(`Player ${player.GetName()} is in range with NPC for quest.`); + // Add any interaction logic here... + } + }); +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_MOVEMENT, (...args) => OnPlayerMovement(...args)); +``` +In this example, when a player moves, it checks for nearby NPCs within 5 meters (ignoring vertical distance) that are relevant to a quest. If the player is within the specified range of the NPC, a message is logged to the console, and any intended interaction logic could be implemented at that point. This demonstrates a simple way to trigger quest interactions based on proximity. + + +## IsInRange2d + +Determines if a given point in 2D space is within a specified range from the WorldObject. The distance check accounts for the WorldObject's boundaries, ensuring the point is checked against the object's edge rather than its center. + +### Parameters +- `x`: number - The X coordinate of the point to check. +- `y`: number - The Y coordinate of the point to check. +- `minrange`: number - The minimum distance from the WorldObject for the point to be considered in range. +- `maxrange`: number - The maximum distance from the WorldObject for the point to be considered in range. + +### Returns +- `boolean` - Returns `true` if the point `(x, y)` is within the specified range (`minrange` to `maxrange`) of the WorldObject, otherwise returns `false`. + +### Example Usage: +Imagine a scenario where you want to trigger an event if a player is within a certain distance from a world object, such as entering a dangerous area or activating a trap. + +```typescript +const TRAP_X = 100.25; +const TRAP_Y = 50.75; +const MIN_DISTANCE_FOR_TRIGGER = 0; +const MAX_TRAP_TRIGGER_DISTANCE = 5; + +const onPlayerMove: player_event_on_move = (event: number, player: Player, newX: number, newY: number): void => { + let trap = getWorldObject(TRAP_X, TRAP_Y); // Custom function to retrieve the trap object + + if(trap.IsInRange2d(newX, newY, MIN_DISTANCE_FOR_TRIGGER, MAX_TRAP_TRIGGER_DISTANCE)) { + console.log("Player has triggered the trap!"); + // Additional logic to handle the trap activation + } else { + console.log("Player is safe from the trap... for now."); + } +}; + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_MOVE, (...args) => onPlayerMove(...args)); +``` + +### Detailed Explanation: + +This method is perfect for situations where you need to activate certain gameplay mechanics based on the player's or any other entity's position relative to an object in the game world. It accounts for the object's actual dimensions by measuring the distance from its edges, making it extremely useful for precision-based triggers or area-effect calculations within the modding environment of AzerothCore and mod-eluna. + +## IsInRange3d + +Checks whether a given point in 3D space is within a specified range from the edge of the WorldObject. This can be used to determine if entities or locations are within a certain distance, allowing for proximity-based logic in scripts. + +### Parameters + +* `x`: number - The x-coordinate of the point to check. +* `y`: number - The y-coordinate of the point to check. +* `z`: number - The z-coordinate of the point to check. +* `minrange`: number - The minimum range from the WorldObject's edge. The point must be further than this distance to return true. +* `maxrange`: number - The maximum range from the WorldObject's edge. The point cannot be further than this distance to return true. + +### Returns + +`true` if the point is within the specified range from the WorldObject, `false` otherwise. + +### Example Usage + +In this example, we will create an event where a custom spell triggers if an enemy player enters within a 5 to 30-yard radius of a game object (e.g., a trap). + +```typescript +const TRAP_SPELL_ENTRY = 12345; // Example spell entry +const MIN_RANGE = 5; +const MAX_RANGE = 30; + +const OnMoveOrSpawn: worldobject_event_on_update = (event: number, worldObject: WorldObject, enemy: Player) => { + + // Retrieve enemy player position + const enemyX = enemy.GetX(); + const enemyY = enemy.GetY(); + const enemyZ = enemy.GetZ(); + + // Check if enemy player is within specified range of the trap + if(worldObject.IsInRange3d(enemyX, enemyY, enemyZ, MIN_RANGE, MAX_RANGE)) { + // Cast spell if in range + worldObject.CastSpell(enemy, TRAP_SPELL_ENTRY); + console.log(`Trap activated for player at (${enemyX}, ${enemyY}, ${enemyZ})`); + } +} + +// Assuming we register this pseudocode function to fire on every movement update or spawn of a WorldObject and enemy player +RegisterWorldObjectEvent(WorldObjectEvents.WORLD_OBJECT_EVENT_ON_UPDATE, (...args) => OnMoveOrSpawn(...args)); +``` + +In this example, `OnMoveOrSpawn` is invoked whenever there is an update event for any `WorldObject`. It checks if an enemy `Player` is within a specified range using `IsInRange3d`. If the condition is met, a spell (trap) is activated, affecting the player. This can be tailored for specific scenarios like setting traps around strategic locations in a custom PvP battleground or creating dynamic events based on player proximity to objects or NPCs. + + +## IsWithinDist + +This method determines whether a target WorldObject is within a specified distance from the calling WorldObject. It accounts for the physical boundaries of both objects and can consider either 2D (ignoring elevation differences) or 3D distances based on the `is3D` parameter. + +### Parameters +- `target`: [WorldObject](./worldobject.md) - The WorldObject to check the distance against. +- `distance`: number - The maximum distance to check. This is measured from the edges of both WorldObjects. +- `is3D`: boolean (optional) - If `true`, the method considers the 3D distance (taking height differences into account). If `false` or omitted, only the 2D distance (ignoring elevation) is considered. + +### Returns +- `boolean` - Returns `true` if the target WorldObject is within the specified distance; otherwise, `false`. + +### Example Usage: +The following example demonstrates a scripted event where a player's proximity to a special NPC triggers a custom greeting if they are within 10 units distance in a 2D plane. + +```typescript +const SPECIAL_NPC_ENTRY = 12345; +const PROXIMITY_DISTANCE = 10; + +const OnPlayerMove: player_event_on_movement = (event: number, player: Player) => { + // Assuming GetClosestCreatureOfEntry is a helper function that retrieves the closest NPC of a given entry to the player + const specialNpc = GetClosestCreatureOfEntry(player, SPECIAL_NPC_ENTRY); + + if(specialNpc && player.IsWithinDist(specialNpc, PROXIMITY_DISTANCE, false)) { + player.SendBroadcastMessage("You've approached the mysterious figure. It eyes you curiously."); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_MOVE, (...args) => OnPlayerMove(...args)); +``` + +In this example, we use the `IsWithinDist` function to check if the player has moved within a 10-unit radius of a 'Special NPC'. If the condition is met, the player receives a custom broadcast message. This can be adapted for various use cases, such as triggering quests, spawning enemies, or creating proximity-based puzzles in a mod for AzerothCore. + +## IsWithinDist2d +This method checks if a given point in two-dimensional space is within a specific distance from the [WorldObject]. It's particularly useful for situations where you need to check spatial relationships on a plane, ignoring vertical displacement. The method measures distance from the object's edge, enhancing precision in positioning-related checks. + +### Parameters
+- `x`: number - The X coordinate of the point to check against. +- `y`: number - The Y coordinate of the point to check against. +- `distance`: number - The radius within which the point must lie from the [WorldObject]. + +### Returns +- `boolean`: Returns `true` if the point (`x`, `y`) is within the specified `distance` from the [WorldObject], taking into account only the X and Y coordinates. Returns `false` otherwise. + +### Example Usage: + +Assuming you have a quest that requires a player to reach a specific location on the map, you may want to check if the player is close enough to a quest item or point of interest. This example demonstrates how you could use `IsWithinDist2d` to verify the player's position relative to an objective marked by its `x` and `y` coordinates on a two-dimensional plane. + +```typescript +// Quest Objective Location +const QUEST_TARGET_X = 2567.5; +const QUEST_TARGET_Y = 5422.3; +const QUEST_RADIUS = 10; // 10 units distance considered "reached" + +// This function could be called whenever a player moves, to check if they've reached the objective +function checkQuestObjectiveReached(player: Player) { + const playerPosition = player.GetPosition(); // Assuming GetPosition returns an object with x, y properties + + if(player.IsWithinDist2d(QUEST_TARGET_X, QUEST_TARGET_Y, QUEST_RADIUS)) { + console.log("Quest objective reached! Congratulations."); + // Further code to handle quest completion or update + } else { + console.log("Keep searching, you're not there yet."); + } +} + +// Hypothetical event registration for when a player moves +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_MOVE, (player: Player) => { + checkQuestObjectiveReached(player); +}); +``` + +In this script, when the player moves, `checkQuestObjectiveReached` is called to determine if the player has reached within 10 units of the quest target location, considering only the x and y coordinates for simplicity. If the player is close enough, a message is logged (or any other quest-related logic could be executed), and if not, a different message offers encouragement to continue. + +# IsWithinDist3d + +Determines if a specified point in three-dimensional space is within a given distance from the `WorldObject`, measured from the object's edge. This can be particularly useful for measuring proximity between players, NPCs, or any other world entities in custom scripts or gameplay mechanics. + +### Parameters + +- `x`: number - The X-coordinate of the point to check. +- `y`: number - The Y-coordinate of the point to check. +- `z`: number - The Z-coordinate of the point to check. +- `distance`: number - The distance to check against. + +### Returns + +- `boolean` - Returns `true` if the specified point is within the designated distance from the [WorldObject](./worldobject.md), otherwise returns `false`. + +### Example Usage + +In this example, we create a custom event that checks if players are within a certain distance of a quest NPC to trigger a custom interaction, such as providing a hint or summoning a helper NPC. + +Given an NPC with coordinates `(npcX, npcY, npcZ)`, we want to check if players coming within 10 units of the NPC trigger the custom event. + +```typescript +// Coordinates for our NPC +const npcX = 1234.56; +const npcY = 6543.21; +const npcZ = 78.90; +const proximityTriggerDistance = 10; // The distance within which the event is triggered + +const npcProximityCheck: player_event_on_update_zone = (event: number, player: Player): void => { + // Gets player's current position + const playerX = player.GetPositionX(); + const playerY = player.GetPositionY(); + const playerZ = player.GetPositionZ(); + + // Checks if the player is within the specified distance of the NPC + if(player.IsWithinDist3d(npcX, npcY, npcZ, proximityTriggerDistance)) { + // Custom interaction goes here + player.SendBroadcastMessage("You sense a mysterious presence..."); + + // Optionally, summon a helper NPC or create other interactions + // This part of the script would depend on further API method calls + } +} + +// Registers our custom event to constantly check player's proximity to the NPC +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_UPDATE_ZONE, (...args) => npcProximityCheck(...args)); +``` + +This script effectively demonstrates how the `IsWithinDist3d` method can be employed to enhance the gameplay experience in AzerothCore by triggering events based on spatial conditions. + +## IsWithinDistInMap +Determines whether the current [WorldObject] is on the same map and within a specified distance from a target [WorldObject]. Unlike a straightforward distance check, this method takes into consideration the boundaries of each object, meaning it measures from their edges rather than their center points. An optional parameter allows for the specification of whether the distance calculation should be in three dimensions (considering height) or just two. + +### Parameters +- **target:** [WorldObject](./worldobject.md) - The target WorldObject to compare distance with. +- **distance:** number - The maximum distance allowed between the edges of the two WorldObjects. +- **is3D:** boolean (optional) - Whether to calculate distance in three dimensions. Defaults to `false` for two-dimensional distance. + +### Returns +- **boolean:** Returns `true` if the current WorldObject is within the specified distance of the target WorldObject on the same map, `false` otherwise. + +### Example Usage +Below is a sample script that could be used in a custom boss fight. This script checks whether players are within a certain distance from the boss to determine if they get hit by a specific ability. This could be used to encourage players to spread out or to gather close, depending on the boss mechanics. + +```typescript +const BOSS_ABILITY_DISTANCE = 30; // Distance within which players will be hit by the boss's ability. + +const onBossAbility: event_script_code = (event: number, boss: Creature, args: any): void => { + // Assuming 'boss' is a Creature derived from WorldObject and thus has access to IsWithinDistInMap + const players = GetPlayersInMap(boss.GetMapId()); + players.forEach(player => { + if (boss.IsWithinDistInMap(player, BOSS_ABILITY_DISTANCE)) { + // Apply effect to players within distance + // This could be a damaging spell, a debuff, etc., depending on the desired boss mechanic + console.log(`Player ${player.GetName()} is hit by the boss's ability!`); + } else { + console.log(`Player ${player.GetName()} is safe from the boss's ability.`); + } + }); +}; + +// Register this script to be called during the boss fight, perhaps as part of an AI event +RegisterCreatureEvent(MY_BOSS_ENTRY_ID, CreatureEvents.CREATURE_EVENT_ON_CUSTOM_EVENT_1, (...args) => onBossAbility(...args)); +``` + +In this example, the `IsWithinDistInMap` method facilitates a pivotal game mechanic by allowing the script to dynamically assess player positions relative to the boss, executing gameplay logic based on spatial relationships in the game world. + +## IsWithinLoS + +Determines if a given [WorldObject] or a set of coordinates (x, y, z) is within the line of sight of the calling [WorldObject]. Ensuring that spells, ranged attacks, or visual effects are not obstructed is a common use for this method. This can enhance NPC AI or player interaction within scripted events. + +### Parameters + +* `worldobject`: [WorldObject](./WorldObject.md) - The WorldObject to check line of sight against. *(Optional if coordinates are provided)* +* `x`: number - The x coordinate. *(Required if no WorldObject is provided)* +* `y`: number - The y coordinate. *(Required if no WorldObject is provided)* +* `z`: number - The z coordinate. *(Required if no WorldObject is provided)* + +### Returns + +* `boolean`: Returns `true` if the [WorldObject] or coordinates are within the line of sight, `false` otherwise. + +### Example Usage: + +Below is a sample script where an NPC checks if a player is within its line of sight before casting a spell. This can be particularly useful in custom quests or events where NPC behavior needs to be precise and realistic. + +```typescript +const NPC_ENTRY = 12345; +const SPELL_FIREBALL = 133; + +// Custom event for an NPC casting a spell on sight +const CastSpellOnSight: creature_event_on_ai_update = (event: number, creature: Creature, diff: number): void => { + // Assume 'player' is a globally accessible Player object in this context + if (creature.IsWithinLoS(player)) { + creature.CastSpell(player, SPELL_FIREBALL, true); + console.log("Casting Fireball!"); + } else { + console.log("Player is out of sight!"); + } +} + +// Register the AI update event for your NPC +RegisterCreatureEvent(NPC_ENTRY, CreatureEvents.CREATURE_EVENT_ON_AI_UPDATE, (...args) => CastSpellOnSight(...args)); +``` + +This script demonstrates how line of sight checks can be incorporated into NPC AI to make interactions more dynamic and engaging. In this case, the NPC will only cast a spell on the player if they are within line of sight, adding an element of strategy for players to consider during encounters. + +## PlayDirectSound + +This method allows a [WorldObject] to play a specific sound. If a [Player] is specified, the sound plays only for that player. If no player is specified, the sound is played for everyone within proximity. Unlike other sound methods, `PlayDirectSound` plays the sound immediately without interrupting any currently playing sound. + +### Parameters +- `sound`: number - The sound ID to play. Sound IDs can be obtained from data extracted from the game client. +- `player`: [Player](./player.md) (Optional) - The player to whom the sound should be played exclusively. If not provided, the sound plays for all nearby players. + +### Example Usage: + +Demonstrates playing a victory sound to a player when they defeat an enemy, and a different sound to all nearby players when an important NPC is defeated. + +```typescript +const VICTORY_SOUND = 12345; +const NPC_DEFEAT_SOUND = 54321; + +// Play victory sound for player upon defeating any enemy. +const OnPlayerKill: player_event_on_kill = (event: number, player: Player, victim: Unit): void => { + if (victim.GetType() === TypeId.TYPEID_UNIT) { + player.GetMap().PlayDirectSound(VICTORY_SOUND, player); + } +} + +// Play special sound for everyone nearby when a specific NPC is defeated. +const OnNPCDeath: creature_event_on_death = (event: number, creature: Creature, killer: Unit): void => { + if (creature.GetEntry() === SPECIAL_NPC_ENTRY) { + creature.PlayDirectSound(NPC_DEFEAT_SOUND); + } +} + +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_KILL, (...args) => OnPlayerKill(...args)); +RegisterCreatureEvent(CreatureEvents.CREATURE_EVENT_ON_DEATH, (...args) => OnNPCDeath(...args)); +``` + +In the example above, a victory sound is played directly to the player who kills an enemy, making their triumph feel more personal and immediate. Additionally, when a particular NPC, denoted by `SPECIAL_NPC_ENTRY`, is defeated, a unique sound plays to everyone in the vicinity, signaling the NPC's defeat to all nearby players. This method of sound playbacks enhances the immersive experience in gameplay, providing dynamic audio feedback based on in-game actions. + +## PlayDistanceSound + +This method allows a WorldObject to play a specific sound. If directed at a certain player, only they will hear it; otherwise, it's audible to everyone nearby. The volume decreases with distance from the source, creating an immersive experience. Unlike other methods, this immediately stops any currently playing sounds on the WorldObject. + +### Parameters +- sound: number - The ID of the sound to play. Sound IDs can be found in the game files or databases. +- player?: [Player](./player.md) (Optional) - The target player to hear the sound. If not specified, all players within range will hear the sound. + +### Example Usage: +In the following example, when a player interacts with a specific object (for instance, a quest item in the world), a unique sound will play. This could signify the item's activation or an atmospheric cue. + +```typescript +// Define a specific sound ID and WorldObject ID for demonstration +const MYSTICAL_OBJECT_ID = 12345; +const ACTIVATION_SOUND_ID = 54321; + +const OnObjectInteraction: world_object_event_on_go_use = (event: number, player: Player, gameObject: GameObject): void => { + if (gameObject.GetGUIDLow() == MYSTICAL_OBJECT_ID) { + // Play a unique sound when the mystical object is used + gameObject.PlayDistanceSound(ACTIVATION_SOUND_ID, player); + + // Optionally send a message to the player for feedback + player.SendBroadcastMessage(`You feel a strange energy as the object resonates with a deep hum.`); + } +} + +// Register the GameObject event for use interaction +RegisterGameObjectEvent(MYSTICAL_OBJECT_ID, GameObjectEvents.GO_EVENT_ON_USE, (...args) => OnObjectInteraction(...args)); +``` + +In this script, the sound will directly play to the player who interacts with the specified GameObject, enhancing their immersive experience in the game world. The sound's diminishing volume with distance can also indicate the source's location, adding depth to environmental storytelling and gameplay mechanics. + +## PlayMusic +Plays the specified music ID to a single player or everyone nearby the WorldObject without interrupting any previously played music. This function can enhance the atmosphere or highlight certain events in custom scripts. + +### Parameters +- **music**: number - The ID of the music to play. Music IDs can be found in the game's data files. +- **player**?: [Player](./player.md) (optional) - The player to whom the music should be played. If not specified, the music will be played to everyone nearby. + +### Example Usage: +Below is a script that plays a triumphant theme when a player completes a specific quest, enhancing the sense of achievement. If the player is not specified, this music is played to all nearby players, sharing the moment of celebration. + +```typescript +const QUEST_ID_FOR_CELEBRATION = 12345; // Example Quest ID +const TRIUMPHANT_THEME_MUSIC_ID = 123; // Example Music ID + +const onQuestComplete: quest_event_on_complete = (questId: number, player: Player): void => { + if (questId === QUEST_ID_FOR_CELEBRATION) { + // Retrieves the WorldObject (could be an NPC or any relevant object in the world) + const worldObject: WorldObject = GetRelevantWorldObject(); + + // Player specific + worldObject.PlayMusic(TRIUMPHANT_THEME_MUSIC_ID, player); + + // Alternatively, for a broader effect, omitting the player parameter + // worldObject.PlayMusic(TRIUMPHANT_THEME_MUSIC_ID); + + // Additional logic for the quest completion can be added here + } +} + +RegisterQuestEvent(QUEST_ID_FOR_CELEBRATION, QuestEvents.QUEST_EVENT_ON_COMPLETE, (...args) => onQuestComplete(...args)); + +function GetRelevantWorldObject(): WorldObject { + // This is a placeholder function. In a real scenario, you would fetch + // the WorldObject based on context, such as NPCs associated with the quest. + return new WorldObject(); // Placeholder return +} +``` + +This example showcases how the `PlayMusic` method can be used to provide auditory feedback for game events, making the game world feel more immersive and responsive to player actions. Note that in an actual implementation, the `GetRelevantWorldObject` function would need to be replaced with logic specific to how you retrieve or reference your WorldObject in the game environment. + +## RegisterEvent + +Registers a timed event to the [WorldObject], calling a specified function after a delay. The event can repeat multiple times or indefinitely until the [WorldObject] is destroyed. This function allows for dynamic event handling based on time for all WorldObject derivatives, such as Players, Creatures, and GameObjects. Timed event ticks for Creatures and GameObjects require visibility, and all events are cleared upon the object's destruction or player logout. + +### Parameters + +- `func`: `(delay: number | [number, number], repeats: number, worldobj: WorldObject) => any` - A callback function that executes when the event fires. Receives the parameters: delay, repeats, and the world object. +- `delay`: `number | [number, number]` - The delay before the event fires in milliseconds. A single number indicates a fixed delay; a tuple `[min, max]` specifies a random delay within the range. +- `repeats?`: `number` - The number of times the event repeats. `0` for indefinite repetition. + +### Returns + +`eventId`: `number` - An identifier for the registered event. This ID can be used to reference or cancel the event later. + +### Example Usage: + +Scheduling a simple greeting for any world object that repeats a few times, demonstrating the basic use case. + +```typescript +function GreetWorldObject(delay: number, repeats: number, worldObject: WorldObject): void { + console.log(`Hello from ${worldObject.GetName()}!`); +} + +const worldObject = /* assume this is a valid WorldObject derived instance, like Player or Creature */; +worldObject.RegisterEvent(GreetWorldObject, 5000, 3); // Greets after 5 seconds, repeats 3 times. +``` + +### Advanced Usage: + +Creating a dynamic event for a creature that performs an action based on visibility and repeats indefinitely, showcasing the use of random delay intervals and indefinite repetition. + +```typescript +function CheckVisibilityAndAct(delay: number, repeats: number, creature: Creature): void { + if (creature.IsVisibleToPlayers()) { + creature.Emote(1); // Performs an emote action when visible. + console.log(`Performing action for ${creature.GetName()}`); + } else { + console.log(`Waiting for visibility for ${creature.GetName()}`); + } +} + +const creature = /* assume this is a valid Creature instance that has been spawned in the world */; +creature.RegisterEvent(CheckVisibilityAndAct, [1000, 3000], 0); // Checks visibility and acts every 1 to 3 seconds, indefinitely. +``` + +This example demonstrates extensive use of the `RegisterEvent` method to create engaging and reactive world interactions within mod-eluna on Azerothcore, leveraging TypeScript's strong typing for clear and maintainable code. + + +## RegisterEvent + +This method allows you to register an event on a WorldObject with a specified function, delay, and repetition count. It can be particularly useful for implementing timers, random events, or any action that needs to be executed with a delay or at certain intervals for units. + +### Parameters +- **func**: (delay: number | [number, number], repeats: number, worldobj: Unit) => any - The function to be called when the event is triggered. This function can accept parameters for delay and repeats, as well as the WorldObject itself. +- **delay**: number | [number, number] - The delay before the event is first triggered. Can be a single number (for a specific delay in milliseconds) or a tuple of two numbers (for a random delay between the two specified values in milliseconds). +- **repeats**: number (optional) - The number of times the event should repeat after the first trigger. If not specified, the event will only trigger once. + +### Returns +- **eventID**: number - The ID of the created event, which can be used for event cancellation or management. + +### Example Usage: +Creating a simple script where a unit periodically says something to nearby players, and then after a certain number of repetitions, casts a spell. + +```typescript +const SAY_EVENT = 1; // Custom event IDs should start from 1 +const CAST_SPELL_EVENT = 2; + +function scheduleSayEvent(unit: Unit): void { + unit.RegisterEvent((delay, repeats, worldobj) => { + worldobj.SendUnitSay("I will cast a spell soon...", ChatType.CHAT_TYPE_SAY); + + // Decrease repeats left and check if it's time to cast the spell + if (repeats <= 1) { + worldobj.RegisterEvent(castSpell, 5000, 1); // Schedule spell cast in 5 seconds + } + }, [2000, 5000], 3); // Say something every 2-5 seconds, three times +} + +function castSpell(delay: number, repeats: number, worldobj: Unit): void { + worldobj.CastSpell(worldobj, SPELL_ID, true); + worldobj.SendUnitSay("Spell casting complete.", ChatType.CHAT_TYPE_SAY); +} + +RegisterWorldEvent(WORLD_EVENT_ON_INIT, () => { + const unit = GetUnitById(SOME_UNIT_ID); + if(unit) { + scheduleSayEvent(unit); + } +}); +``` +In this script, `scheduleSayEvent` makes the unit say something to nearby players three times at random intervals between 2 to 5 seconds. After saying the phrase three times, `castSpell` is scheduled to make the unit cast a spell. This example showcases the versatility of `RegisterEvent` in creating dynamic world interactions based on timers and conditional logic. + +# RegisterEvent + +Schedules a function to be called after a delay for WorldObject, specifically for Creature objects in this overload. Useful for creating dynamic events or triggers within the game world. + +### Parameters +- **func**: _function_ - The function to be called after the delay. The function signature takes a delay, repeats, and the world object (`Creature`) as parameters. +- **delay**: _number_ | _[number, number]_ - Time in milliseconds before the event is triggered. Can also be a tuple representing a range from which a random delay will be selected. +- **repeats**: _number_ (Optional) - The number of times the event will repeat. If not specified, defaults to no repeats. + +### Returns +- **eventId**: _number_ - A unique ID for the created event. Can be used to cancel the event before it's triggered. + +### Example Usage +In this example, we create a simple NPC behavior where a creature heals itself every 10 seconds for 5 times total. The heal effect and the chat message broadcast are scheduled using `RegisterEvent`. + +```typescript +const HEAL_AMOUNT = 50000; // Amount of health restored by the heal. +const HEAL_INTERVAL = 10000; // Time in milliseconds between heals. +const HEAL_REPEATS = 5; // Number of times the heal event repeats. + +function HealSelfAndBroadcast(creature: Creature): void { + creature.SetHealth(creature.GetHealth() + HEAL_AMOUNT); + creature.TextEmote("The creature's wounds begin to close!", null, true); +} + +const onCreatureSpawn: creature_event_on_spawn = (event: number, creature: Creature): void => { + creature.RegisterEvent((delay, repeats, self) => { + HealSelfAndBroadcast(self); + }, HEAL_INTERVAL, HEAL_REPEATS); +} + +// Assuming you have the creature's entry ID, replace `CREATURE_ENTRY` with the actual ID. +RegisterCreatureEvent(CREATURE_ENTRY, CreatureEvents.CREATURE_EVENT_ON_SPAWN, (...args) => onCreatureSpawn(...args)); +``` + +In this more advanced example, there's a creature that schedules an event to heal itself for a set amount multiple times. The schedule can be randomized using a tuple for the delay parameter, providing a more unpredictable behavior which can be more engaging in player vs environment (PvE) scenarios. + +# RegisterEvent + +Schedules a custom event to be executed for the `Player`. The custom event can be set to execute after a specified delay and can be configured to repeat a certain number of times. This method is particularly useful for creating timed events or actions tied to specific `Player` activities or conditions in the game. + +### Parameters +- **func**: (delay: number | [number, number], repeats: number, worldobj: Player) => any - The function to execute when the event triggers. The parameters of the function include `delay`, `repeats`, and the `Player` object itself. +- **delay**: number | [number, number] - The delay before the event is first triggered. Can be a single number (for a consistent delay) or a tuple with two numbers representing a random range ([minDelay, maxDelay]) from which the actual delay will be chosen. +- **repeats**?: number - Optional. The number of times the event should repeat. If not provided, the event will trigger only once. If set to a positive number, the event will repeat that many times at the specified delay interval. If set to -1, the event will repeat indefinitely until explicitly canceled. + +### Returns +- **eventId**: number - A unique identifier for the registered event. This can be used to cancel the event before it completes. + +### Example Usage: +In this example, we schedule an event for a `Player` that simulates the player finding an ancient relic in a dungeon. The event triggers after a random interval between 10 to 30 seconds, repeats 3 times to simulate the player finding a total of 3 relics, and each time gives the player a small experience boost and a relic item. + +```typescript +function findRelicEvent(delay: number, repeats: number, player: Player) { + if (repeats > 0) { + player.AddExperience(500); // Add some experience for finding a relic + player.AddItem(19019, 1); // Add an example relic item to the player's inventory + player.SendBroadcastMessage(`You've found an ancient relic! ${repeats} left to find.`); + } +} + +const RELIC_QUEST_START: player_event_hook = (playerEventId: number, player: Player) => { + // Trigger findRelicEvent with a random delay between 10 and 30 seconds, repeating 3 times. + player.RegisterEvent(findRelicEvent, [10000, 30000], 3); +} + +// Register the RELIC_QUEST_START function to the desired player event +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_CUSTOM_EVENT, (...args) => RELIC_QUEST_START(...args)); +``` + +In this script, when the custom event `PLAYER_EVENT_ON_CUSTOM_EVENT` triggers for the `Player`, the `findRelicEvent` function is scheduled with a delay randomly chosen between 10 and 30 seconds. The `findRelicEvent` function gives the player an experience boost and a relic item upon each execution, simulating the player finding relics in a dungeon. The event repeats 3 times before automatically discontinuing. + +Based on the provided examples and instructions, here’s how the documentation for `RegisterEvent` method might look like if included in a markdown doc for the `WorldObject` class in the context of mod-eluna on Azerothcore. + +## RegisterEvent +This method is used to register an event on a `WorldObject`, `Unit`, `Creature`, or `Player`. The event function will be called after the specified delay and can repeat multiple times depending on the parameters given. + +### Parameters +- **func**: `(delay: number | [number, number], repeats: number, worldObj: WorldObject | Unit | Creature | Player) => any` - The function that will be executed. The function will receive the parameters: delay, repeats, and worldObj, which represent the delay before the event is executed, number of times the event repeats, and the world object the event is bound to, respectively. +- **delay**: `number | [number, number]` - The delay in milliseconds before the event is triggered. This can be a single number or an array representing a range `[min, max]`, where a random delay is chosen from within the range for each repetition of the event. +- **repeats?**: `number` - (Optional) The number of times the event should repeat. If not specified, the event will trigger only once. If set to `-1`, the event will repeat indefinitely until explicitly removed. + +### Returns +- **eventId**: `number` - The ID of the created event. This ID can be used to cancel the event if needed. + +### Example Usage: +Creating a simple event to make a Creature speak a line of text after a delay of 3 seconds. This event will repeat 5 times, each with a delay randomly chosen between 3,000 ms (3 seconds) and 5,000 ms (5 seconds). + +```typescript +const SPEAK_EVENT: unit_event_on_speak = (delay: number, repeats: number, creature: Creature): void => { + creature.Say("The event system in mod-eluna is powerful!", 0); +}; + +let myCreature: Creature; // Assuming this is already defined elsewhere in your script + +const EVENT_ID: number = myCreature.RegisterEvent(SPEAK_EVENT, [3000, 5000], 5); + +// To cancel the event before it completes its run, you could use +// myCreature.RemoveEvent(EVENT_ID); +``` + +This example demonstrates how to use `RegisterEvent` to schedule a repeating event with a variable delay. The `SPEAK_EVENT` function makes the creature say a message, which is a practical example of how events can interact with game entities. This approach allows for a wide range of possibilities, such as scheduling buffs, initiating custom scripts, or controlling NPC behavior dynamically. + +## RemoveEventById +This method is used to cancel a timed event associated with a WorldObject using the specified event ID. Each timed event that is scheduled on a WorldObject is assigned a unique event ID which can be used to specifically target and remove the event before it finishes or triggers. This can be particularly useful for scripting dynamic encounters or events where the conditions may change before the event is supposed to be executed. + +### Parameters +- **eventId**: number - The unique identifier of the event to be removed. + +### Example Usage: +In this example, we schedule a timed event on an object that causes it to say something after 10 seconds. However, if a player interacts with the object before those 10 seconds are up, the event is canceled, and instead, the object says something immediately. + +```typescript +const SAY_EVENT_ID = 1; +const OBJECT_ENTRY = 12345; // Example WorldObject entry ID + +function SpawnHandler(event: number, object: WorldObject): void { + // Schedule a "say" event to happen after 10 seconds + object.ScheduleEvent(() => { + object.Say("The time has come."); + }, 10000, SAY_EVENT_ID); +} + +function InteractionHandler(event: number, player: Player, object: WorldObject): void { + // Check if the event is still pending + if(object.HasEvent(SAY_EVENT_ID)) { + // Remove the pending event + object.RemoveEventById(SAY_EVENT_ID); + + // Immediate response due to the player's interaction + object.Say("Ah, you've arrived sooner than I expected."); + } +} + +// Registers the spawn handler to execute when the WorldObject of specified entry is spawned. +RegisterWorldObjectEvent(OBJECT_ENTRY, WorldObjectEvents.WORLD_OBJECT_EVENT_ON_SPAWN, (...args) => SpawnHandler(...args)); + +// Registers an interaction handler that triggers when a player interacts with the WorldObject. +RegisterWorldObjectEvent(OBJECT_ENTRY, WorldObjectEvents.WORLD_OBJECT_EVENT_ON_PLAYER_INTERACTION, (...args) => InteractionHandler(...args)); +``` + +In the above script: +- The `SpawnHandler` function schedules a timed event when the WorldObject is spawned. This event will make the WorldObject say "The time has come." after 10 seconds unless it is preemptively removed. +- The `InteractionHandler` function listens for player interactions with the WorldObject. If the player interacts with the object before the 10-second event occurs, the event is removed using `RemoveEventById`, and the object immediately says "Ah, you've arrived sooner than I expected." instead. +- This demonstrates how `RemoveEventById` can be used to dynamically adjust the behavior of objects in response to changing game conditions. + +## RemoveEvents + +Remove all timed events from a WorldObject. This method is used when you want to ensure that no scheduled events are pending on the WorldObject, effectively cleaning its event queue. This can be particularly useful for scripted encounters or when dynamically modifying the behavior of game objects or units without leaving lingering effects. + +### Usage: + +No parameters required. + +### Example Usage: + +Creating a script where a game object should stop all its actions before being destroyed. Imagine a scenario where this game object periodically spawns enemies, but under certain conditions, it must be deactivated instantly. + +```typescript +const GO_DEACTIVATE: gameobject_event_on_event = (eventNumber: number, gameObject: GameObject): void => { + // Assuming some conditions are met to stop the GameObject's actions + gameObject.RemoveEvents(); + + // Additional logic to safely deactivate or delete the GameObject + // without worrying about its pending events. +} + +RegisterGameObjectEvent(GAME_OBJECT_ENTRY_ID, GameObjectEvents.GAMEOBJECT_EVENT_ON_EVENT, (...args) => GO_DEACTIVATE(...args)); +``` + +### Notes +- Use this method with caution. Removing all events from a WorldObject can impact ongoing game mechanics. +- Typically, this method is called before a scripted event changes phase or before a WorldObject's behavior is drastically altered to ensure a clean transition. +- This method does not remove persistent effects or changes made by past events; it only stops future scheduled events from happening. + +By employing `RemoveEvents()`, developers can manage WorldObjects more dynamically, ensuring that objects can transition between states without being hindered by previously set timed events. This functionality is essential for creating a responsive and controlled environment in mod scripting for Azerothcore using the mod-eluna plugin. + +Based on the provided examples, here is how you can document the `SendPacket` method for a `WorldObject` class within a README documentation aimed to support development for mods on Azerothcore using mod-eluna. This documentation includes inline code comments and method signature as provided in the instructions. + +--- + +## SendPacket + +This method is used to transmit custom packets to all players that are currently in the visibility range of the `WorldObject`. It's useful for sending updates or notifications that are not covered by the default AzerothCore functionalities. + +### Parameters + +- **packet**: [WorldPacket](./worldpacket.md) - The custom packet to be sent to nearby players. + +### Usage + +When using `SendPacket`, you must first understand or have in mind the structure of the packet you're sending, as well as the impact it will have on the client-side. This is typically used for advanced modifications and requires a good understanding of the client-server data exchange protocol. + +Here is an example of how one might use `SendPacket` to create a custom visual or audible effect around an object when a specific event occurs. This script adds a custom effect whenever a player interacts with a specific world object: + +```typescript +const CUSTOM_PACKET_ENTRY = 123456; // Make sure this is unique and doesn't clash with existing packets + +const onPlayerInteract: world_object_event_on_interact = (event: number, player: Player, worldObject: WorldObject) => { + // Assuming createCustomPacket is a fictional function to demonstrate packet creation. + let customPacket: WorldPacket = createCustomPacket(CUSTOM_PACKET_ENTRY); + + // Adding data to the packet (this is highly dependent on what the client expects to receive) + customPacket.WriteUInt32(player.GetGUIDLow()); + customPacket.WriteFloat(worldObject.GetX()); + customPacket.WriteFloat(worldObject.GetY()); + customPacket.WriteFloat(worldObject.GetZ()); + + // Sending the packet to players around + worldObject.SendPacket(customPacket); +} + +RegisterWorldObjectEvent(WorldObjectEvents.WORLD_OBJECT_EVENT_ON_INTERACT, (...args) => onPlayerInteract(...args)); + +function createCustomPacket(packetEntry: number): WorldPacket { + // This would be where you create your packet to send to the client + // For the purpose of this example, we'll return a placeholder + return new WorldPacket(packetEntry); // The real implementation would be more complex +} +``` + +### Notes + +- Always ensure the packet structure aligns with what the client expects. Misaligned structures can lead to unexpected behavior or crashes. +- The visibility range is determined by the server configurations and the environmental factors within the AzerothCore framework. +- Use this method responsibly as sending too many custom packets can lead to bandwidth issues or potential exploits. + +Incorporating custom packets can significantly enhance the interaction within the game, offering a more dynamic and immersive experience for players, but it requires careful planning and testing to implement effectively. + +## SetPhaseMask +This method sets the phase mask of the WorldObject. In World of Warcraft, phase masks are used to control visibility and interaction of objects and NPCs for players in different 'phases'. This can be useful for scripting phased content where certain objects or NPCs should only be interactable or visible to players in a specific phase. + +### Parameters +- `phaseMask`: number - The phase mask to set. This controls the phasing visibility and interaction. +- `update?`: boolean - (Optional) Whether to update the phase mask for all players in sight. Defaults to `false` if not specified. + +### Returns +This method does not return a value. + +### Example Usage: +Here's an example script that sets the phase mask of an NPC to 2, making it only interactable by players in phase 2. This script might be part of a quest line where the NPC should only appear after a certain event has occurred. +```typescript +const PHASE_MASK = 2; +const UPDATE_SIGHT = true; + +const onQuestAccepted: creature_event_on_quest_accept = (event: number, player: Player, creature: Creature, quest: Quest): void => { + if(quest.GetId() === SOME_QUEST_ID) { + creature.SetPhaseMask(PHASE_MASK, UPDATE_SIGHT); + } +} + +RegisterCreatureEvent(CREATURE_ID, CreatureEvents.CREATURE_EVENT_ON_QUEST_ACCEPT, (...args) => onQuestAccepted(...args)); +``` +In this example script, when the player accepts a specific quest (`SOME_QUEST_ID`), the `SetPhaseMask` method is called on the NPC (`creature`). The NPC's phase mask is set to 2 (`PHASE_MASK`), and the phase update is applied to all players in sight (`UPDATE_SIGHT`) making the NPC visible only to players in phase 2. This method can be key to creating immersive and dynamic environments in World of Warcraft modding. + +## SpawnCreature +Spawns a creature at the specified location with optional parameters for the spawn type and despawn timer. The spawn type determines the condition under which the creature despawns, such as time-based or event-based conditions. + +### Parameters +- **entry**: number - The entry ID of the creature to be spawned from the `creature_template` table. +- **x**: number - The X coordinate for the spawn location. +- **y**: number - The Y coordinate for the spawn location. +- **z**: number - The Z coordinate for the spawn location. +- **o**: number - The orientation of the creature at the spawn location. +- **spawnType**: TempSummonType (Optional) - An enum value that determines the despawn condition for the creature. +- **despawnTimer**: number (Optional) - Time in milliseconds after which the creature will despawn. The application of this timer depends on the `spawnType`. + +### Enum: TempSummonType +- **TEMPSUMMON_TIMED_OR_DEAD_DESPAWN**: 1 - Despawns after a specified time OR when the creature is no longer alive. +- **TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN**: 2 - Despawns after a specified time OR when the creature dies and leaves a corpse. +- **TEMPSUMMON_TIMED_DESPAWN**: 3 - Despawns strictly after a specified time. +- **TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT**: 4 - Despawns after a specified time once the creature is out of combat. +- **TEMPSUMMON_CORPSE_DESPAWN**: 5 - Instantly despawns upon death. +- **TEMPSUMMON_CORPSE_TIMED_DESPAWN**: 6 - Despawns after a specified time post-death. +- **TEMPSUMMON_DEAD_DESPAWN**: 7 - Despawns when the creature disappears. +- **TEMPSUMMON_MANUAL_DESPAWN**: 8 - Despawns when manually instructed via `UnSummon()`. +- **TEMPSUMMON_TIMED_OOC_OR_CORPSE_DESPAWN**: 9 - Despawns after specified time out of combat (OOC) OR when the creature dies. +- **TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN**: 10 - Despawns after a specified time out of combat (OOC) OR when the creature disappears. + +### Returns +- **Creature**: A reference to the spawned creature. + +### Example Usage +Below is an example that spawns a creature when a player interacts with a GameObject. The creature despawns after 10 minutes or if killed. + +```typescript +const CREATURE_ENTRY = 12345; +const DESPAWN_TIME_MS = 600000; // 10 minutes in milliseconds + +const onGoUse: go_event_on_use = (event: number, player: Player, gameObject: GameObject): void => { + // Spawn location near the GameObject + const spawnX = gameObject.GetX() + 3; + const spawnY = gameObject.GetY() + 3; + const spawnZ = gameObject.GetZ(); + const spawnO = gameObject.GetO(); + + // Spawn the creature with a timed despawn condition + const spawnedCreature = gameObject.SpawnCreature( + CREATURE_ENTRY, + spawnX, + spawnY, + spawnZ, + spawnO, + TempSummonType.TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, // Despawns after time or if dead + DESPAWN_TIME_MS + ); + + if (spawnedCreature) { + player.SendBroadcastMessage(`A wild creature has appeared near ${gameObject.GetName()}!`); + } +}; + +RegisterGameObjectEvent(GAMEOBJECT_TEMPLATE_ID, GameObjectEvents.GO_EVENT_ON_USE, (...args) => onGoUse(...args)); +``` +This setup creates an engaging experience for players by dynamically spawning creatures in the world, enhancing immersion and interaction within the game environment. + +## SummonGameObject +Spawns a GameObject at the specified location with an optional respawn delay. The GameObject will appear in the game world at the coordinates (x, y, z) with orientation (o). The entry parameter corresponds to the GameObject ID as defined in the World Database (`gameobject_template` table). + +### Parameters +- **entry**: number - GameObject Entry Id from `gameobject_template` table. +- **x**: number - The x-coordinate where the GameObject will appear. +- **y**: number - The y-coordinate where the GameObject will appear. +- **z**: number - The z-coordinate where the GameObject will appear. +- **o**: number - The orientation of the GameObject. +- **respawnDelay**: number (optional) - The time in seconds before the GameObject respawns after being interacted with or destroyed. If not specified, the default respawn delay defined in the database will be used. + +### Returns +- **gameObject**: [GameObject](./gameobject.md) - The GameObject that was spawned. + +### Example Usage: +Creates a script that spawns a chest containing treasures for players to find. The chest will respawn 2 hours after being opened. + +```typescript +const CHEST_ENTRY = 190000; // Example GameObject ID for a treasure chest +const TREASURE_HUNT_EVENT_ID = 1; + +const onTreasureHuntStart: global_event_on_start = (eventId: number): void => { + if (eventId === TREASURE_HUNT_EVENT_ID) { + // Coordinates for the treasure chest + const x = -13276.88; + const y = 83.5312; + const z = 21.60645; + const o = 1.57; // Facing south + const respawnDelay = 7200; // 2 hours + + // Spawn the treasure chest + World.Spell:SummonGameObject(CHEST_ENTRY, x, y, z, o, respawnDelay); + + print("A treasure chest has appeared somewhere in the world. Happy hunting!"); + } +} + +RegisterGlobalEvent(GlobalEvents.GLOBAL_EVENT_ON_START, (...args) => onTreasureHuntStart(...args)); +``` + +This script uses a global event to trigger the spawning of a treasure chest when the event `TREASURE_HUNT_EVENT_ID` starts. Players can participate in the treasure hunt, and once the chest is claimed, it will be available again after 2 hours, encouraging players to keep an eye out for the next one. +