a failed dial says which failure, and the sword reads the at-war bit

- "Unable to connect" now says which: an address that does not resolve reads the reference's "Invalid Login Server", a resolved address nothing answers on reads "Login Server Down", and each names the `host:port` actually dialed — resolution and connection are two operations now (a DNS failure surfaces as `Uncategorized` on macOS, so no error kind could tell them apart), and every address a name carries is tried, `localhost` → `::1` then `127.0.0.1` included
- a typed wrong password shows the login dialog instead of exiting the client, and the two auth-result enums — realmd's and the world server's — are split so a code is read against the family that sent it, with the world server's own refusal text shown for its codes
- the world cursor's fork is `CanInteract` and `CanAttack`, not a reaction-rank threshold: a Cenarion Circle NPC with no gossip showed the sword at neutral (and TAB acquired it, and right-click attacked it) because one predicate implemented twice read the standing where the binary reads the at-war bit in the player→unit direction; one byte-verified `CanAttack` is shared by the cursor, TAB, pet attack orders, `UnitCanAttack` and the action-button usable gate, the service ladder falls out to a plain pointer instead of the attack leg, and `/reaction` prints the at-war bit and the branch verdict

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Sam
2026-08-29 17:18:29 +07:00
co-authored by Claude Fable 5
parent 0d7b984304
commit dc779b3017
20 changed files with 863 additions and 127 deletions
@@ -872,8 +872,8 @@ impl ObjectFields {
}
/// The object's class from the type field (`OBJECT_FIELD_TYPE`), used for `Values`/`Movement`
/// updates that carry no separate `TypeId`. Unused by the create path (which has a `TypeId`).
#[allow(dead_code)]
/// updates that carry no separate `TypeId`. Also the reference's own "is this a Player" test
/// (`[obj->descriptorBlock[2] + 8] >> 4 & 1`), which is how `CanAttack`/`CanInteract` ask.
pub fn object_type(&self) -> Option<ObjectType> {
self.get_u32(FIELD_OBJECT_TYPE).map(|bits| {
if bits & 0x10 != 0 {