Adding Custom Titles - Twigie/vmangos_guides GitHub Wiki
Preface: I know very little CPP so please feel free to change the code as you see fit.
We will be using the City Protector titles in Vanilla World of Warcraft to add our own titles that we can use.
You will need an unlocked client, see the links below on how to do this.
The Client
The client reads the titles from the GlobalStrings.lua file that can be found in the patch-2.mpq. Search for PVP_Medal in the file and you will find the current City Protector titles. We can simple add more entries for PVP_Medals to give us access to new titles. Use Ladiks MQP editor to create your own patch-3.mpq with the updated GlobalStrings.Lua. That is all that is needed for the client. If you want to have an item grant a title you will need to create a new spell and add it to the client. Use spell effect 77 if you are following this guide as this will run a script on the server that will set the title based on the itemID the spell was cast from.
The Server
The server has a SetCityTitle function that we can use to our advantage to set the title of the player. Normally this function gets the players raceID, 1 for humans, and thats how it determines what title to give the player, PVP_MEDAL1=Protector of Stormwind. So when we created our client change if we added a PVP_Medal9 we can tell the server to instead of passing the players raceID to instead just pass the int 9 and this will tell the clients to display that specific title.
The server has a .character citytitle command that we can change so we can just use the command to change the players title. So instead of passing on or off as the args we will pass the number that corresponds to the PVP_MEDAL that we set in GlobalStrings.lua
bool ChatHandler::HandleCharacterCityTitleCommand(char* args)
{
Player* pPlayer = GetSelectedPlayer();
if (!pPlayer)
{
SendSysMessage(LANG_NO_CHAR_SELECTED);
return false;
}
// sLog.Out(LOG_BASIC, LOG_LVL_MINIMAL, "%s this is the args", args);
// bool value;
// if (!ExtractOnOff(&args, value))
// {
// PSendSysMessage("Syntax: .title on | off");
// return false;
// }
// Change the args from a char to an int that SetCityTitle can accept
if (args)
pPlayer->SetCityTitle(args[0] - '0');
else
pPlayer->RemoveCityTitle();
return true;
}
You can further expand on this by creating an item with an on use spell that triggers the citytitle command based on the item id. For example I create a item called 'Grant Title: Developer' this item has the ID of 30000. This item has an on use effect that casts a custom spell I made with the ID of 35000 (See other guide on custom spells). That spell has an effect of SPELL_EFFECT_SCRIPT_EFFECT. In SpellEffects.cpp you can add the below to the switch case of EffectScriptEffect>SPELLFAMILY_GENERIC.
case 35000:
{
if (Player* player = m_caster->ToPlayer())
{
if (m_CastItem)
{
// This sets the title based on the ItemID,
switch (m_CastItem->GetProto()->ItemId)
{
case 30000:
player->SetCityTitle(9);
sLog.Out(LOG_BASIC, LOG_LVL_DETAIL, "Character: %s has gained a title: %s", player->GetName(), m_CastItem->GetProto()->Name1);
return;
case 30001:
player->SetCityTitle(2);
sLog.Out(LOG_BASIC, LOG_LVL_DETAIL, "Character: %s has gained a title: %s", player->GetName(), m_CastItem->GetProto()->Name1);
return;
case 30002:
player->SetCityTitle(3);
sLog.Out(LOG_BASIC, LOG_LVL_DETAIL, "Character: %s has gained a title: %s", player->GetName(), m_CastItem->GetProto()->Name1);
return;
default:
sLog.Out(LOG_BASIC, LOG_LVL_DETAIL, "default");
return;
}
}
return;
}
return;
}