Index: src/client/gui/chatwindow.cpp =================================================================== --- src/client/gui/chatwindow.cpp (revision 1330) +++ src/client/gui/chatwindow.cpp (working copy) @@ -1225,7 +1225,7 @@ if( (psengine->GetCelClient()->GetActorByName(msg.sPerson, false) == NULL) && (psengine->GetCelClient()->GetActorByName(msg.sPerson, true))) { - msg.sPerson = "Someone"; + msg.sPerson = FormatDescription(psengine->GetCelClient()->GetActorByName(msg.sPerson, true)); } break; } @@ -2209,6 +2209,131 @@ AutoselectChatTabIfNeeded(allowedTabs, "NPC Button"); } +csString pawsChatWindow::FormatDescription(GEMClientActor *speaker) +{ + csString description; + if (speaker->race && 1) // 1 represents config "show race" + { + if (speaker->traits && 2) // 2 represents config "show trait" + { + csString traitName, location; + csRef doc = psengine->GetXMLParser()->CreateDocument(); + if (!doc->Parse(speaker->traits)) // if no error string returned + { + csRef traitIter = doc->GetRoot()->GetNode("traits")->GetNodes("trait"); + while ( traitIter->HasNext() ) + { + csRef traitNode = traitIter->Next(); + location = traitNode->GetAttributeValue("loc"); + if (!location) + continue; + + if (csString("SKIN_TONE").CompareNoCase(location)) + { + traitName = traitNode->GetAttributeValue("name"); + if (traitName.IsEmpty()) + continue; + + traitName.Append(" "); + description = traitName; + } + if (csString("HAIR_COLOR").CompareNoCase(location)) + { + traitName = traitNode->GetAttributeValue("name"); + if (traitName.IsEmpty()) + continue; + + traitName.Append(" haired "); + description = traitName; + } + } + } + } + + if (speaker->gender && 3) // 3 represents config "show gender" + { + switch(speaker->gender) + { + case PSCHARACTER_GENDER_MALE: + { + description.Append("male "); + break; + } + case PSCHARACTER_GENDER_FEMALE: + { + description.Append("female "); + break; + } + } + } + + description.Append(speaker->race); + + description = description.Downcase(); + if ( (size_t)-1 != csString("aeiou").FindFirst(description.GetAt(0)) ) // Not perfect, for "u" sounding like "y", or a silent "h" + description.Insert(0, "An "); + else + description.Insert(0, "A "); + + } + else + { + description.Replace("Someone"); + } + + if (4) // 4 represents config "show position" + { + csVector3 playerPos, speakerPos, diff; + float playerYRot; + iSector *playerSector, *speakerSector; + + speaker->GetLastPosition(speakerPos, playerYRot, speakerSector); + psengine->GetCelClient()->GetMainPlayer()->GetLastPosition(playerPos, playerYRot, playerSector); + + if (psengine->GetCelClient()->GetWorld()->WarpSpace(speakerSector, playerSector, speakerPos) == true) // Sectors are connected by a portal + { + diff = speakerPos - playerPos; + + // division by 0 protection + if (diff.x == 0.0F) + diff.x = 0.00001F; + + // Incident angle to other character + float angleRadians = atan2(-diff.x, -diff.z); + // Where the character is facing compared to incident angle + angleRadians = playerYRot - angleRadians; + // Convert to degrees + int angle = static_cast (angleRadians*180.0/PI); + + if (angle >= 360) + while (angle > 360) + angle -= 360; + else if (angle < 0) + while (angle < 0) + angle += 360; + + if (angle > 45 && angle <= 135) + { + description.Append(" to your left"); + } + else if (angle > 135 && angle <= 225) + { + description.Append(" behind you"); + } + else if (angle > 225 && angle <= 315) + { + description.Append(" to your right"); + } + else + { + description.Append(" in front of you"); + } + } + } + + return description; +} + //------------------------------------------------------------------------------ pawsChatHistory::pawsChatHistory() Index: src/server/bulkobjects/pstrait.cpp =================================================================== --- src/server/bulkobjects/pstrait.cpp (revision 1330) +++ src/server/bulkobjects/pstrait.cpp (working copy) @@ -70,10 +70,10 @@ if (compact) { str.Format("", uid,next_trait_uid, - GetLocationString(),cstr_id_mesh, + GetLocationString(),name.GetData(),cstr_id_mesh, cstr_id_material,cstr_id_texture, shaderVar.GetData() ); } else