/// <summary> /// Creates a new instance of an <see cref="NPC"/>. /// </summary> public NPC(AgentOrigin agentOrigin, string name, int speciesId, int toughness, int concentration, int healing, int condition, int hitboxWidth, int hitboxHeight) : base(agentOrigin, name, hitboxWidth, hitboxHeight) { SpeciesId = speciesId; Toughness = toughness; Concentration = concentration; Healing = healing; Condition = condition; }
/// <summary> /// Creates a new instance of a <see cref="Player"/> character. /// </summary> public Player(AgentOrigin agentOrigin, string name, int toughness, int concentration, int healing, int condition, int hitboxWidth, int hitboxHeight, string accountName, Profession profession, EliteSpecialization eliteSpecialization, int subgroup, bool identified) : base(agentOrigin, name, hitboxWidth, hitboxHeight) { Toughness = toughness; Concentration = concentration; Healing = healing; Condition = condition; Identified = identified; Subgroup = subgroup; AccountName = accountName; Profession = profession; EliteSpecialization = eliteSpecialization; }
public AttackTarget(AgentOrigin agentOrigin, int volatileId, string name, int hitboxWidth, int hitboxHeight) : base(agentOrigin, name, hitboxWidth, hitboxHeight) { VolatileId = volatileId; }
private IEnumerable <Agent> GetAgents(ParsedLog log) { var idsByAddress = new Dictionary <ulong, int>(); foreach (var combatItem in log.ParsedCombatItems) { if (combatItem.IsStateChange == StateChange.Normal) { idsByAddress[combatItem.SrcAgent] = combatItem.SrcAgentId; } } var playerAddresses = new HashSet <ulong>(); foreach (var agent in log.ParsedAgents) { if (agent.IsElite != 0xFFFFFFFF) { // Player uint professionIndex = agent.Prof - 1; Profession profession; // We need to check if the profession is valid. // The 2021-05-25 game update caused old versions of arcdps to report invalid profession values. // Future game versions might also introduce new professions. if (professionIndex < Professions.Length) { profession = Professions[professionIndex]; } else { profession = Profession.None; } EliteSpecialization specialization; if (agent.IsElite == 0) { specialization = EliteSpecialization.None; } else if (agent.IsElite == 1) { specialization = Characters.GetHeartOfThornsEliteSpecialization(profession); } else { specialization = Characters.GetEliteSpecializationFromId(agent.IsElite); } if (!idsByAddress.TryGetValue(agent.Address, out int id)) { id = -1; } // All parts of the name of the player might not be available, most commonly in WvW logs. var nameParts = agent.Name.Split(new[] { '\0' }, StringSplitOptions.RemoveEmptyEntries); string characterName = nameParts[0]; string accountName = nameParts.Length > 1 ? nameParts[1] : ":Unknown"; string subgroupLiteral = nameParts.Length > 2 ? nameParts[2] : ""; bool identified = nameParts.Length >= 3; if (!int.TryParse(subgroupLiteral, out int subgroup)) { subgroup = -1; } if (playerAddresses.Contains(agent.Address)) { // If there is already an agent with this address, this is the same player after changing // characters. For now we simply merge everything into the first instance, even though that // may result in a player using skills of a different profession, a better solution will be // needed for the future. continue; } playerAddresses.Add(agent.Address); var origin = new AgentOrigin(new OriginalAgentData(agent.Address, id)); yield return(new Player(origin, characterName, agent.Toughness, agent.Concentration, agent.Healing, agent.Condition, agent.HitboxWidth, agent.HitboxHeight, accountName, profession, specialization, subgroup, identified)); } else { if (agent.Prof >> 16 == 0xFFFF) { // Gadget or Attack Target int volatileId = (int)(agent.Prof & 0xFFFF); string name = agent.Name.Trim('\0'); var origin = new AgentOrigin(new OriginalAgentData(agent.Address, volatileId)); if (name.StartsWith("at")) { // The attack target name is structured as "at[MasterAddress]-[GadgetId]-[MasterId]" // Preferably, the AttackTarget statechange would be used to detect if this is an // attack target to not rely on the name which could change in the future yield return(new AttackTarget(origin, volatileId, name, agent.HitboxWidth, agent.HitboxHeight)); } else { yield return(new Gadget(origin, volatileId, name, agent.HitboxWidth, agent.HitboxHeight)); } } else { // NPC if (!idsByAddress.TryGetValue(agent.Address, out int id)) { id = -1; } string name = agent.Name.Trim('\0'); int speciesId = (int)(agent.Prof & 0xFFFF); var origin = new AgentOrigin(new OriginalAgentData(agent.Address, id)); yield return(new NPC(origin, name, speciesId, agent.Toughness, agent.Concentration, agent.Healing, agent.Condition, agent.HitboxWidth, agent.HitboxHeight)); } } } }