### Run EVTC Log Info Example in Rust Source: https://gitlab.com/dunj3/evtclib/-/blob/master/README.md Shows how to execute a command-line example for processing EVTC log information using cargo. This example takes a path to a log file (e.g., .zevtc) as an argument. Requires the evtclib crate and cargo. ```shell cargo run --example=loginfo -- path/to/log.zevtc ``` -------------------------------- ### Low-Level Raw Parsing of EVTC Files using evtclib Source: https://context7.com/dunj3/evtclib/llms.txt This example demonstrates how to access the raw binary structures of EVTC files using evtclib for advanced, low-level control. It covers parsing both uncompressed and compressed (ZIP) EVTC files, extracting header information, skill counts, agent details, and event data. Dependencies include std::fs::File, std::io::BufReader, and evtclib::raw. Inputs are file paths to EVTC logs, with output being parsed data printed to the console. ```rust use evtclib::raw; use std::fs::File; use std::io::BufReader; fn main() -> Result<(), Box> { // Parse uncompressed evtc file let file = File::open("raw_log.evtc")?; let reader = BufReader::new(file); let evtc = raw::parse_file(reader)?; println!("=== Raw EVTC Header ==="); println!("arcdps build: {}", evtc.header.arcdps_build); println!("Combat/Boss ID: {}", evtc.header.combat_id); println!("Revision: {}", evtc.header.revision); println!("Agent count: {}", evtc.header.agent_count); println!("\n=== Skill Count ==="); println!("Skills: {}", evtc.skill_count); println!("\n=== Raw Agents ==="); for (i, agent) in evtc.agents.iter().take(5).enumerate() { println!("Agent {}: addr={:#x}, prof={}, elite={}", i, agent.addr, agent.prof, agent.is_elite); } println!("\n=== Raw Events (first 10) ==="); for (i, event) in evtc.events.iter().take(10).enumerate() { println!("Event {}: time={}, src_agent={:#x}, dst_agent={:#x}", i, event.time, event.src_agent, event.dst_agent); } // Parse compressed zip file let zip_file = File::open("compressed_log.evtc.zip")?; let zip_reader = BufReader::new(zip_file); let evtc_from_zip = raw::parse_zip(zip_reader)?; println!("\n=== Compressed Log ==="); println!("Total events in compressed log: {}", evtc_from_zip.events.len()); Ok(()) } ``` -------------------------------- ### Extract Log Metadata and Timestamps using evtclib Source: https://context7.com/dunj3/evtclib/llms.txt This Rust snippet demonstrates how to extract metadata from an EVTC log file, including local start and end timestamps, game build ID, combat duration, reward status, and any logged errors. It also shows how to determine if an encounter is generic. Dependencies include the evtclib crate. Inputs are a path to an EVTC file and its compression type, with outputs being various log details printed to the console. ```rust use evtclib::{process_file, Compression}; fn main() -> Result<(), Box> { let log = process_file("metadata_log.zevtc", Compression::Zip)?; // Timestamps if let Some(start) = log.local_start_timestamp() { println!("Local start timestamp: {}", start); } if let Some(end) = log.local_end_timestamp() { println!("Local end timestamp: {}", end); } // Build information if let Some(build) = log.build_id() { println!("Game build: {}", build); } // Combat span println!("Combat duration: {}ms", log.span()); // Reward status println!("Was rewarded: {}", log.was_rewarded()); // Check for errors in the log let errors = log.errors(); if !errors.is_empty() { println!("\n=== Log Errors ==="); for error in errors { println!("Error: {}", error); } } else { println!("No errors in log"); } // Check if this is a generic (unknown) encounter if log.is_generic() { println!("This is a generic/unknown encounter"); } Ok(()) } ``` -------------------------------- ### Serialize and Deserialize Guild Wars 2 Logs with Serde (Rust) Source: https://context7.com/dunj3/evtclib/llms.txt This Rust code snippet demonstrates how to serialize and deserialize Guild Wars 2 combat log data using the `serde` feature of the `evtclib` crate. It shows serializing the entire log, player lists, and events to JSON files. It also includes an example of deserializing an Agent structure from a JSON string. This functionality requires the `serde` feature to be enabled in `evtclib`'s Cargo.toml. ```rust // Cargo.toml: evtclib = { version = "0.7", features = ["serde"] } use evtclib::{process_file, Compression, Agent}; use serde_json; fn main() -> Result<(), Box> { let log = process_file("serialize_test.zevtc", Compression::Zip)?; // Serialize the entire log to JSON let log_json = serde_json::to_string_pretty(&log)?; std::fs::write("log_export.json", &log_json)?; println!("Exported log to log_export.json"); // Serialize specific players let players: Vec<&Agent> = log.players().collect(); let players_json = serde_json::to_string_pretty(&players)?; std::fs::write("players.json", &players_json)?; // Serialize events let events_json = serde_json::to_string_pretty(&log.events())?; std::fs::write("events.json", &events_json)?; // Note: Only Agent<()> (type-erased) can be deserialized // to prevent type coercion issues let json_data = r#"{ "addr": 12345, "kind": {"Player": { "profession": 1, "elite": null, "character_name": "Test Character", "account_name": "Account.1234", "subgroup": 1 }}, "toughness": 1000, "concentration": 0, "healing": 0, "condition": 0, "instance_id": 1, "first_aware": 0, "last_aware": 100000, "master_agent": null }"#; let agent: Agent = serde_json::from_str(json_data)?; println!("Deserialized agent: {:?}", agent.kind()); Ok(()) } ``` -------------------------------- ### Query Agents by Address and Instance using evtclib Source: https://context7.com/dunj3/evtclib/llms.txt This snippet shows how to find specific agents within an EVTC log using their unique address or instance ID. It also demonstrates how to check for master-minion relationships and iterate through different agent types like gadgets and characters. Dependencies include the evtclib crate. Inputs are a path to an EVTC file and compression type, with output being printed information about found agents. ```rust use evtclib::{process_file, Compression}; fn main() -> Result<(), Box> { let log = process_file("ranger_log.zevtc", Compression::Zip)?; // Find agent by unique address let agent_addr = 12345678u64; if let Some(agent) = log.agent_by_addr(agent_addr) { println!("Found agent: {:?}", agent.kind()); println!("Instance ID: {}", agent.instance_id()); // Check for master agent (for pets/minions) if let Some(master_addr) = agent.master_agent() { if let Some(master) = log.agent_by_addr(master_addr) { if let Some(player) = master.as_player() { println!("This is a pet/minion of {}", player.account_name()); } } } } // Find agent by instance ID if let Some(agent) = log.agent_by_instance_id(42) { println!("Agent with instance 42: address {}", agent.addr()); } // Get the master agent helper let minion_addr = 87654321u64; if let Some(master) = log.master_agent(minion_addr) { println!("Master agent: {:?}", master.kind()); } // Iterate all gadgets println!("\n=== Gadgets ==="); for gadget in log.gadgets() { println!("Gadget: {} (ID: {})", gadget.gadget().name(), gadget.gadget().id()); } // Iterate all NPCs/characters println!("\n=== NPCs ==="); for character in log.characters() { println!("Character: {} (ID: {})", character.character().name(), character.character().id() ); } Ok(()) } ``` -------------------------------- ### Process EVTC File from Disk - Rust Source: https://context7.com/dunj3/evtclib/llms.txt Parses an EVTC file from disk, automatically handling compressed (.evtc.zip, .zevtc) and uncompressed formats. It validates the data and enriches it with game metadata, returning a high-level Log structure. Requires the 'evtclib' crate. ```rust use evtclib::{process_file, Compression}; use std::error::Error; fn main() -> Result<(), Box> { // Process an uncompressed evtc file let log = process_file("raid_log.evtc", Compression::None)?; println!("Encounter: {:?}", log.encounter()); println!("Boss ID: {}", log.boss_id()); println!("Total events: {}", log.events().len()); println!("Fight duration: {}ms", log.span()); // Process a compressed zevtc file let compressed_log = process_file("fractal_log.zevtc", Compression::Zip)?; println!("Is Challenge Mode: {}", compressed_log.is_cm()); println!("Game mode: {:?}", compressed_log.game_mode()); Ok(()) } ``` -------------------------------- ### Combat Activation Enumeration for Skill Usage Source: https://gitlab.com/dunj3/evtclib/-/blob/master/material/README.txt The 'cbtactivation' enum describes how a combat skill was activated, differentiating between normal activations, those with 'QUICKNESS', and various cancellation states like 'CANCEL_FIRE', 'CANCEL_CANCEL', and 'RESET'. This helps analyze skill timing and responsiveness. ```c /* combat activation */ enum cbtactivation { ACTV_NONE, // not used - not this kind of event ACTV_NORMAL, // activation without quickness ACTV_QUICKNESS, // activation with quickness ACTV_CANCEL_FIRE, // cancel with reaching channel time ACTV_CANCEL_CANCEL, // cancel without reaching channel time ACTV_RESET // animation completed fully }; ``` -------------------------------- ### Process Combat Events - Rust Source: https://context7.com/dunj3/evtclib/llms.txt Iterates through combat events in an EVTC log to analyze damage, buff applications, and player state changes. Requires the `evtclib` crate and a `.zevtc` log file. Outputs a summary of total damage, critical hits, and buff applications. ```rust use evtclib::{process_file, Compression, EventKind, raw::CbtResult}; fn main() -> Result<(), Box> { let log = process_file("combat_log.zevtc", Compression::Zip)?; let mut total_damage = 0i64; let mut critical_hits = 0; let mut buff_applications = 0; for event in log.events() { let timestamp_ms = event.time(); match event.kind() { EventKind::Physical { source_agent_addr, destination_agent_addr, skill_id, damage, result } => { if *damage > 0 { total_damage += *damage as i64; if *result == CbtResult::Crit { critical_hits += 1; } // Check combat modifiers if event.is_flanking() { println!("[{}ms] Flanking strike! Skill: {}, Damage: {}", timestamp_ms, skill_id, damage); } // Track scholar bonus window if event.is_ninety() { println!("[{}ms] Scholar threshold met (>90% HP)", timestamp_ms); } } } EventKind::BuffApplication { source_agent_addr, destination_agent_addr, buff_id, duration, overstack, .. } => { buff_applications += 1; if let Some(target) = log.agent_by_addr(*destination_agent_addr) { if let Some(player) = target.as_player() { println!("[{}ms] Buff {} applied to {} for {}ms", timestamp_ms, buff_id, player.account_name(), duration); } } } EventKind::ChangeDown { agent_addr } => { if let Some(agent) = log.agent_by_addr(*agent_addr) { if let Some(player) = agent.as_player() { println!("[{}ms] {} is downed!", timestamp_ms, player.account_name()); } } } EventKind::ChangeDead { agent_addr } => { if let Some(agent) = log.agent_by_addr(*agent_addr) { if let Some(player) = agent.as_player() { println!("[{}ms] {} died!", timestamp_ms, player.account_name()); } } } _ => {} // Ignore other event types } } println!("\n=== Summary ==="); println!("Total damage: {}", total_damage); println!("Critical hits: {}", critical_hits); println!("Buff applications: {}", buff_applications); Ok(()) } ``` -------------------------------- ### Handle Profession and Elite Specialization Data in Rust Source: https://context7.com/dunj3/evtclib/llms.txt This Rust code snippet illustrates how to process player data from a Guild Wars 2 combat log, focusing on professions and elite specializations. It uses the `evtclib` library to iterate through players, count occurrences of each profession and elite specialization, and identify specific builds like Firebrand, Dragonhunter, Willbender, and Chronomancer. The code utilizes `HashMap` for counting and `match` statements for conditional logic. It requires the `evtclib` crate and processes a log file containing squad information. ```rust use evtclib::{process_file, Compression, Profession, EliteSpec}; fn main() -> Result<(), Box> { let log = process_file("squad_comp.zevtc", Compression::Zip)?; let mut profession_counts = std::collections::HashMap::new(); let mut elite_counts = std::collections::HashMap::new(); for player in log.players() { let prof = player.profession(); let elite = player.elite(); *profession_counts.entry(prof).or_insert(0) += 1; match elite { Some(spec) => { *elite_counts.entry(spec).or_insert(0) += 1; println!("{}: {:?}", player.account_name(), spec); } None => { println!("{}: {:?} (core)", player.account_name(), prof); } } } println!("\n=== Squad Composition ==="); println!("Professions:"); for (prof, count) in profession_counts { println!(" {:?}: {}", prof, count); } println!("\nElite Specializations:"); for (elite, count) in elite_counts { println!(" {:?}: {}", elite, count); } // Match specific professions or specs for player in log.players() { match player.profession() { Profession::Guardian => { match player.elite() { Some(EliteSpec::Firebrand) => { println!("{} is a Firebrand (boon support)", player.account_name()); } Some(EliteSpec::Dragonhunter) => { println!("{} is a Dragonhunter (DPS)", player.account_name()); } Some(EliteSpec::Willbender) => { println!("{} is a Willbender (DPS)", player.account_name()); } _ => {} // Ignore other Guardian elite specs or core } } Profession::Mesmer => { if player.elite() == Some(EliteSpec::Chronomancer) { println!("{} is a Chronomancer (tank/support)", player.account_name()); } } _ => {} // Ignore other professions } } Ok(()) } ``` -------------------------------- ### Process EVTC Log from Stream - Rust Source: https://context7.com/dunj3/evtclib/llms.txt Parses an EVTC log from any reader implementing Read and Seek, suitable for network streams, in-memory buffers, or custom I/O. Supports both compressed and uncompressed formats. Requires the 'evtclib' crate and standard Rust I/O traits. ```rust use evtclib::{process_stream, Compression}; use std::fs::File; use std::io::BufReader; fn main() -> Result<(), Box> { // Process from a buffered file reader let file = File::open("strike_log.zevtc")?; let reader = BufReader::new(file); let log = process_stream(reader, Compression::Zip)?; println!("Encounter ID: {}", log.encounter_id()); println!("Build ID: {:?}", log.build_id()); // Process from in-memory bytes let bytes = std::fs::read("golem_log.evtc")?; let cursor = std::io::Cursor::new(bytes); let log_from_memory = process_stream(cursor, Compression::None)?; println!("Processed {} events from memory", log_from_memory.events().len()); Ok(()) } ``` -------------------------------- ### Analyze Boss Encounter - Rust Source: https://context7.com/dunj3/evtclib/llms.txt Determines boss encounter type, checks for challenge mode, and analyzes fight outcome from an EVTC log file. Requires the `evtclib` crate and a `.zevtc` log file. Outputs encounter details, game mode, boss agents, challenge mode status, and fight outcome. ```rust use evtclib::{process_file, Compression, Outcome}; fn main() -> Result<(), Box> { let log = process_file("Skorvald_CM.zevtc", Compression::Zip)?; // Get encounter information if let Some(encounter) = log.encounter() { println!("Encounter: {:?}", encounter); println!("Game Mode: {:?}", encounter.game_mode()); // Get all boss entities in the log for boss in log.boss_agents() { println!("Boss agent: {} (ID: {})", boss.addr(), boss.instance_id()); } } // Use the analyzer for advanced fight analysis if let Some(analyzer) = log.analyzer() { println!("Challenge Mode: {}", analyzer.is_cm()); match analyzer.outcome() { Some(Outcome::Success) => println!("Fight outcome: SUCCESS"), Some(Outcome::Failure) => println!("Fight outcome: FAILURE"), None => println!("Fight outcome: UNKNOWN"), } } else { println!("No analyzer available (generic log or unsupported encounter)"); } // Check reward status println!("Was rewarded: {}", log.was_rewarded()); Ok(()) } ``` -------------------------------- ### Parse EVTC Log File in Rust Source: https://gitlab.com/dunj3/evtclib/-/blob/master/README.md Demonstrates how to parse an EVTC log file using the evtclib library. It reads the file, processes it, and iterates through player data to print account names. Requires the evtclib crate. ```rust use std::fs::File; fn main() -> Result<(), Box> { // Parse a log let log = evtclib::process_file("Skorvald/20200421-183243.evtc")?; // Do work on the log for player in log.players() { println!("Player {} participated!", player.account_name()); } Ok(()) } ``` -------------------------------- ### Access Player Information from EVTC Log - Rust Source: https://context7.com/dunj3/evtclib/llms.txt Retrieves and iterates over all players in a parsed EVTC log, providing access to their character details, profession, elite specialization, subgroup, and combat statistics. Requires the 'evtclib' crate and a pre-processed Log object. ```rust use evtclib::{process_file, Compression}; fn main() -> Result<(), Box> { let log = process_file("raid_clear.zevtc", Compression::Zip)?; println!("=== Player Roster ==="); for player in log.players() { let account = player.account_name(); let character = player.character_name(); let profession = player.profession(); let elite_spec = player.elite(); let subgroup = player.subgroup(); match elite_spec { Some(spec) => println!("[Sub {}] {} ({}) - {:?}", subgroup, account, character, spec), None => println!("[Sub {}] {} ({}) - {:?}", subgroup, account, character, profession), } // Access agent stats println!(" Stats - Toughness: {}, Healing: {}, Condition: {}", player.toughness(), player.healing(), player.condition() ); println!(" Active: {}ms to {}ms", player.first_aware(), player.last_aware()); } Ok(()) } ``` -------------------------------- ### Filter Boss Agents and Check Boss Status in Rust Source: https://context7.com/dunj3/evtclib/llms.txt This Rust code snippet demonstrates how to identify and process boss-related agents from a Guild Wars 2 combat log. It uses the `evtclib` library to load a log file, retrieve the primary boss and all boss agents, check if a specific agent is a boss, and calculate total damage dealt to bosses. Dependencies include the `evtclib` crate. It processes a compressed log file and outputs information about bosses and damage. ```rust use evtclib::{process_file, Compression}; fn main() -> Result<(), Box> { let log = process_file("multi_boss.zevtc", Compression::Zip)?; // Get the primary boss let main_boss = log.boss(); println!("Main boss: address={:#x}, instance={}", main_boss.addr(), main_boss.instance_id() ); if let Some(character) = main_boss.as_character() { println!("Boss name: {}", character.character().name()); println!("Boss ID: {}", character.character().id()); } // Get all boss agents (for encounters with multiple phases or targets) println!("\n=== All Boss Agents ==="); for boss in log.boss_agents() { println!("Boss: addr={:#x}, instance={}, first_aware={}ms, last_aware={}ms", boss.addr(), boss.instance_id(), boss.first_aware(), boss.last_aware() ); } // Check if a specific agent address is a boss let test_addr = main_boss.addr(); if log.is_boss(test_addr) { println!("\nAgent {:#x} is a boss", test_addr); } // Track damage to bosses only let mut boss_damage = 0i64; for event in log.events() { if let evtclib::EventKind::Physical { destination_agent_addr, damage, .. } = event.kind() { if log.is_boss(*destination_agent_addr) && *damage > 0 { boss_damage += *damage as i64; } } } println!("\nTotal damage to bosses: {}", boss_damage); Ok(()) } ``` -------------------------------- ### Combat Event Structure Definition Source: https://gitlab.com/dunj3/evtclib/-/blob/master/material/README.txt The 'cbtevent' struct is a comprehensive data structure for recording combat-related events. It includes timestamps, agent identifiers, skill IDs, damage values, buff information, and state change flags, providing a detailed snapshot of combat interactions. ```c /* combat event */ typedef struct cbtevent { uint64_t time; /* timegettime() at time of event */ uint64_t src_agent; /* unique identifier */ uint64_t dst_agent; /* unique identifier */ int32_t value; /* event-specific */ int32_t buff_dmg; /* estimated buff damage. zero on application event */ uint16_t overstack_value; /* estimated overwritten stack duration for buff application */ uint16_t skillid; /* skill id */ uint16_t src_instid; /* agent map instance id */ uint16_t dst_instid; /* agent map instance id */ uint16_t src_master_instid; /* master source agent map instance id if source is a minion/pet */ uint8_t iss_offset; /* internal tracking. garbage */ uint8_t iss_offset_target; /* internal tracking. garbage */ uint8_t iss_bd_offset; /* internal tracking. garbage */ uint8_t iss_bd_offset_target; /* internal tracking. garbage */ uint8_t iss_alt_offset; /* internal tracking. garbage */ uint8_t iss_alt_offset_target; /* internal tracking. garbage */ uint8_t skar; /* internal tracking. garbage */ uint8_t skar_alt; /* internal tracking. garbage */ uint8_t skar_use_alt; /* internal tracking. garbage */ uint8_t iff; /* from iff enum */ uint8_t buff; /* buff application, removal, or damage event */ ``` -------------------------------- ### Combat State Change Enumeration for Agent Status Source: https://gitlab.com/dunj3/evtclib/-/blob/master/material/README.txt The 'cbtstatechange' enum tracks significant changes in an agent's status, such as entering/exiting combat, health updates, spawning/despawning, weapon swaps, and log start/end events. It also includes details on game build and shard ID. ```c /* combat state change */ enum cbtstatechange { CBTS_NONE, // not used - not this kind of event CBTS_ENTERCOMBAT, // src_agent entered combat, dst_agent is subgroup CBTS_EXITCOMBAT, // src_agent left combat CBTS_CHANGEUP, // src_agent is now alive CBTS_CHANGEDEAD, // src_agent is now dead CBTS_CHANGEDOWN, // src_agent is now downed CBTS_SPAWN, // src_agent is now in game tracking range CBTS_DESPAWN, // src_agent is no longer being tracked CBTS_HEALTHUPDATE, // src_agent has reached a health marker. dst_agent = percent * 10000 (eg. 99.5% will be 9950) CBTS_LOGSTART, // log start. value = server unix timestamp **uint32**. buff_dmg = local unix timestamp. src_agent = 0x637261 (arcdps id) CBTS_LOGEND, // log end. value = server unix timestamp **uint32**. buff_dmg = local unix timestamp. src_agent = 0x637261 (arcdps id) CBTS_WEAPSWAP, // src_agent swapped weapon set. dst_agent = current set id (0/1 water, 4/5 land) CBTS_MAXHEALTHUPDATE, // src_agent has had it's maximum health changed. dst_agent = new max health CBTS_POINTOFVIEW, // src_agent will be agent of "recording" player CBTS_LANGUAGE, // src_agent will be text language CBTS_GWBUILD, // src_agent will be game build CBTS_SHARDID, // src_agent will be sever shard id CBTS_REWARD // src_agent is self, dst_agent is reward id, value is reward type. these are the wiggly boxes that you get }; ``` -------------------------------- ### Game Language Enumeration Source: https://gitlab.com/dunj3/evtclib/-/blob/master/material/README.txt The 'gwlanguage' enum maps integer codes to different game client languages, such as 'ENG' (English), 'FRE' (French), 'GEM' (German), and 'SPA' (Spanish). This is used to identify the language settings of the game client. ```c /* language */ enum gwlanguage { GWL_ENG = 0, GWL_FRE = 2, GWL_GEM = 3, GWL_SPA = 4, }; ``` -------------------------------- ### Combat Result Enumeration for Physical Hits Source: https://gitlab.com/dunj3/evtclib/-/blob/master/material/README.txt The 'cbtresult' enum categorizes the outcome of physical combat hits, including 'NORMAL', 'CRIT', 'GLANCE', 'BLOCK', 'EVADE', 'INTERRUPT', 'ABSORB', 'BLIND', and 'KILLINGBLOW'. It provides detailed feedback on combat interactions. ```c /* combat result (physical) */ enum cbtresult { CBTR_NORMAL, // good physical hit CBTR_CRIT, // physical hit was crit CBTR_GLANCE, // physical hit was glance CBTR_BLOCK, // physical hit was blocked eg. mesmer shield 4 CBTR_EVADE, // physical hit was evaded, eg. dodge or mesmer sword 2 CBTR_INTERRUPT, // physical hit interrupted something CBTR_ABSORB, // physical hit was "invlun" or absorbed eg. guardian elite CBTR_BLIND, // physical hit missed CBTR_KILLINGBLOW // physical hit was killing hit }; ``` -------------------------------- ### cbtevent Structure Definition (C) Source: https://gitlab.com/dunj3/evtclib/-/blob/master/material/README.txt Defines the structure `cbtevent` which holds various boolean flags and identifiers related to combat events. These flags include information about the event's result, activation status, buff removal, agent health states, movement, state changes, flanking, and shield damage. It also includes internal tracking variables. ```c struct { uint8_t result; /* from cbtresult enum */ uint8_t is_activation; /* from cbtactivation enum */ uint8_t is_buffremove; /* buff removed. src=relevant, dst=caused it (for strips/cleanses). from cbtr enum */ uint8_t is_ninety; /* source agent health was over 90% */ uint8_t is_fifty; /* target agent health was under 50% */ uint8_t is_moving; /* source agent was moving */ uint8_t is_statechange; /* from cbtstatechange enum */ uint8_t is_flanking; /* target agent was not facing source */ uint8_t is_shields; /* all or part damage was vs barrier/shield */ uint8_t result_local; /* internal tracking. garbage */ uint8_t ident_local; /* internal tracking. garbage */ } cbtevent; ``` -------------------------------- ### Combat Buff Removal Type Enumeration Source: https://gitlab.com/dunj3/evtclib/-/blob/master/material/README.txt The 'cbtbuffremove' enum specifies how buffs are removed from a target, including 'ALL' stacks, 'SINGLE' stack removal, 'MANUAL' removal (e.g., OOC), and 'NONE'. This is important for tracking buff uptimes and cleanse mechanics. ```c /* combat buff remove type */ enum cbtbuffremove { CBTB_NONE, // not used - not this kind of event CBTB_ALL, // all stacks removed CBTB_SINGLE, // single stack removed. disabled on server trigger, will happen for each stack on cleanse CBTB_MANUAL, // autoremoved by ooc or allstack (ignore for strip/cleanse calc, use for in/out volume) }; ``` -------------------------------- ### IFF Enumeration for Friend or Foe Identification Source: https://gitlab.com/dunj3/evtclib/-/blob/master/material/README.txt The 'iff' enum defines states for identifying the relationship between game entities, such as 'FRIEND', 'FOE', and 'UNKNOWN'. This is crucial for distinguishing between allies and enemies in combat logs. ```c /* iff */ enum iff { IFF_FRIEND, // green vs green, red vs red IFF_FOE, // green vs red IFF_UNKNOWN // something very wrong happened }; ``` -------------------------------- ### Custom Skill ID Definitions Source: https://gitlab.com/dunj3/evtclib/-/blob/master/material/README.txt The 'cbtcustomskill' enum provides specific identifiers for certain important skills that may not have standard skill IDs, such as 'RESURRECT', 'BANDAGE', and 'DODGE'. These custom IDs help in accurately identifying specific player actions. ```c /* custom skill ids */ enum cbtcustomskill { CSK_RESURRECT = 1066, // not custom but important and unnamed CSK_BANDAGE = 1175, // personal healing only CSK_DODGE = 65001 // will occur in is_activation==normal event }; ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.