mirror of
https://github.com/ornfelt/azerothcore_lua_scripts
synced 2026-08-22 06:26:03 -04:00
285 lines
12 KiB
C++
285 lines
12 KiB
C++
// Race Changer NPC
|
|
// Smolderforge 2014-2016
|
|
|
|
#include "ScriptPCH.h"
|
|
|
|
#define RACE_CHANGE_TOKEN 385846
|
|
|
|
bool GossipHello_racechanger(Player *player, Creature *creature)
|
|
{
|
|
if (player->HasItemCount(RACE_CHANGE_TOKEN, 1, false) || player->isGameMaster())
|
|
{
|
|
// clear flags in case player closed menu previously, and wants different settings this time
|
|
player->SetFlaggedForRename(false);
|
|
player->SetFlaggedForGenderSwap(false);
|
|
|
|
// Check if player is aware and ready to proceed
|
|
player->ADD_GOSSIP_ITEM_EXTENDED(0, "Yes, I am ready to proceed.", GOSSIP_SENDER_MAIN, 40, "Notice: Your professions will be reset and lost by undergoing a race change.", 0, false);
|
|
|
|
player->SEND_GOSSIP_MENU(77, creature->GetGUID());
|
|
}
|
|
else if (player->GetTeam() == HORDE && sWorld->getConfig(CONFIG_FREE_ALLY_TRANSFER))
|
|
{
|
|
player->ADD_GOSSIP_ITEM_EXTENDED(0, "Yes, I am ready to proceed.", GOSSIP_SENDER_MAIN, 101, "Notice: Your professions will be reset and lost by undergoing a race change.", 0, false);
|
|
|
|
player->SEND_GOSSIP_MENU(85, creature->GetGUID());
|
|
}
|
|
else
|
|
player->SEND_GOSSIP_MENU(78, creature->GetGUID());
|
|
|
|
return true;
|
|
}
|
|
|
|
bool GossipSelect_racechanger(Player *player, Creature *creature, uint32 sender, uint32 action)
|
|
{
|
|
switch (action)
|
|
{
|
|
case 40:
|
|
// Check if rename is desired from player first
|
|
player->ADD_GOSSIP_ITEM(0, "No, continue with race change.", GOSSIP_SENDER_MAIN, 51);
|
|
player->ADD_GOSSIP_ITEM(0, "Yes, flag me for rename.", GOSSIP_SENDER_MAIN, 50);
|
|
|
|
player->SEND_GOSSIP_MENU(79, creature->GetGUID());
|
|
// Perform rename if desired, check for gender swap
|
|
break;
|
|
case 50:
|
|
case 51:
|
|
{
|
|
if (action == 50) // opted for rename
|
|
player->SetFlaggedForRename(true);
|
|
|
|
player->ADD_GOSSIP_ITEM(0, "No, continue with race change.", GOSSIP_SENDER_MAIN, 76);
|
|
player->ADD_GOSSIP_ITEM(0, "Yes, swap my gender.", GOSSIP_SENDER_MAIN, 75);
|
|
|
|
player->SEND_GOSSIP_MENU(80, creature->GetGUID());
|
|
}
|
|
break;
|
|
|
|
// Perform gender swap if needed and question faction switch
|
|
case 75:
|
|
case 76:
|
|
{
|
|
if (action == 75) // opted for gender swap
|
|
player->SetFlaggedForGenderSwap(true);
|
|
|
|
player->ADD_GOSSIP_ITEM(0, "Alliance", GOSSIP_SENDER_MAIN, 100);
|
|
player->ADD_GOSSIP_ITEM(0, "Horde", GOSSIP_SENDER_MAIN, 200);
|
|
|
|
player->SEND_GOSSIP_MENU(81, creature->GetGUID());
|
|
}
|
|
break;
|
|
|
|
/* To reduce the amount of code by having the pop-up warning on every single
|
|
* selection, the race value is added to 50, then modulated later to produce
|
|
* the correct value. (see default case)
|
|
*/
|
|
case 100:
|
|
case 101:
|
|
{
|
|
switch (player->getClass())
|
|
{
|
|
case CLASS_WARRIOR:
|
|
player->ADD_GOSSIP_ITEM(0, "Human", GOSSIP_SENDER_MAIN, 1 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Dwarf", GOSSIP_SENDER_MAIN, 3 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Night Elf", GOSSIP_SENDER_MAIN, 4 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Gnome", GOSSIP_SENDER_MAIN, 7 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Draenei", GOSSIP_SENDER_MAIN, 11 + 500);
|
|
break;
|
|
case CLASS_PALADIN:
|
|
player->ADD_GOSSIP_ITEM(0, "Human", GOSSIP_SENDER_MAIN, 1 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Dwarf", GOSSIP_SENDER_MAIN, 3 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Draenei", GOSSIP_SENDER_MAIN, 11 + 500);
|
|
break;
|
|
case CLASS_HUNTER:
|
|
player->ADD_GOSSIP_ITEM(0, "Dwarf", GOSSIP_SENDER_MAIN, 3 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Night Elf", GOSSIP_SENDER_MAIN, 4 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Draenei", GOSSIP_SENDER_MAIN, 11 + 500);
|
|
break;
|
|
case CLASS_ROGUE:
|
|
player->ADD_GOSSIP_ITEM(0, "Human", GOSSIP_SENDER_MAIN, 1 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Dwarf", GOSSIP_SENDER_MAIN, 3 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Night Elf", GOSSIP_SENDER_MAIN, 4 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Gnome", GOSSIP_SENDER_MAIN, 7 + 500);
|
|
break;
|
|
case CLASS_PRIEST:
|
|
player->ADD_GOSSIP_ITEM(0, "Human", GOSSIP_SENDER_MAIN, 1 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Dwarf", GOSSIP_SENDER_MAIN, 3 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Night Elf", GOSSIP_SENDER_MAIN, 4 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Draenei", GOSSIP_SENDER_MAIN, 11 + 500);
|
|
break;
|
|
case CLASS_SHAMAN:
|
|
player->ADD_GOSSIP_ITEM(0, "Draenei", GOSSIP_SENDER_MAIN, 11 + 500);
|
|
break;
|
|
case CLASS_MAGE:
|
|
player->ADD_GOSSIP_ITEM(0, "Human", GOSSIP_SENDER_MAIN, 1 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Gnome", GOSSIP_SENDER_MAIN, 7 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Draenei", GOSSIP_SENDER_MAIN, 11 + 500);
|
|
break;
|
|
case CLASS_WARLOCK:
|
|
player->ADD_GOSSIP_ITEM(0, "Human", GOSSIP_SENDER_MAIN, 1 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Gnome", GOSSIP_SENDER_MAIN, 7 + 500);
|
|
break;
|
|
case CLASS_DRUID:
|
|
player->ADD_GOSSIP_ITEM(0, "Night Elf", GOSSIP_SENDER_MAIN, 4 + 500);
|
|
break;
|
|
}
|
|
if (action == 100) // do not display if it's a free transfer
|
|
player->ADD_GOSSIP_ITEM(0, "« Back", GOSSIP_SENDER_MAIN, 76);
|
|
|
|
player->SEND_GOSSIP_MENU(82, creature->GetGUID());
|
|
break;
|
|
}
|
|
|
|
case 200:
|
|
{
|
|
switch (player->getClass())
|
|
{
|
|
case CLASS_WARRIOR:
|
|
player->ADD_GOSSIP_ITEM(0, "Orc", GOSSIP_SENDER_MAIN, 2 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Undead", GOSSIP_SENDER_MAIN, 5 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Tauren", GOSSIP_SENDER_MAIN, 6 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Troll", GOSSIP_SENDER_MAIN, 8 + 500);
|
|
break;
|
|
case CLASS_PALADIN:
|
|
player->ADD_GOSSIP_ITEM(0, "Blood Elf", GOSSIP_SENDER_MAIN, 10 + 500);
|
|
break;
|
|
case CLASS_HUNTER:
|
|
player->ADD_GOSSIP_ITEM(0, "Orc", GOSSIP_SENDER_MAIN, 2 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Tauren", GOSSIP_SENDER_MAIN, 6 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Troll", GOSSIP_SENDER_MAIN, 8 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Blood Elf", GOSSIP_SENDER_MAIN, 10 + 500);
|
|
break;
|
|
case CLASS_ROGUE:
|
|
player->ADD_GOSSIP_ITEM(0, "Orc", GOSSIP_SENDER_MAIN, 2 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Undead", GOSSIP_SENDER_MAIN, 5 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Troll", GOSSIP_SENDER_MAIN, 8 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Blood Elf", GOSSIP_SENDER_MAIN, 10 + 500);
|
|
break;
|
|
case CLASS_PRIEST:
|
|
player->ADD_GOSSIP_ITEM(0, "Undead", GOSSIP_SENDER_MAIN, 5 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Troll", GOSSIP_SENDER_MAIN, 8 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Blood Elf", GOSSIP_SENDER_MAIN, 10 + 500);
|
|
break;
|
|
case CLASS_SHAMAN:
|
|
player->ADD_GOSSIP_ITEM(0, "Orc", GOSSIP_SENDER_MAIN, 2 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Tauren", GOSSIP_SENDER_MAIN, 6 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Troll", GOSSIP_SENDER_MAIN, 8 + 500);
|
|
break;
|
|
case CLASS_MAGE:
|
|
player->ADD_GOSSIP_ITEM(0, "Undead", GOSSIP_SENDER_MAIN, 5 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Troll", GOSSIP_SENDER_MAIN, 8 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Blood Elf", GOSSIP_SENDER_MAIN, 10 + 500);
|
|
break;
|
|
case CLASS_WARLOCK:
|
|
player->ADD_GOSSIP_ITEM(0, "Orc", GOSSIP_SENDER_MAIN, 2 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Undead", GOSSIP_SENDER_MAIN, 5 + 500);
|
|
player->ADD_GOSSIP_ITEM(0, "Blood Elf", GOSSIP_SENDER_MAIN, 10 + 500);
|
|
break;
|
|
case CLASS_DRUID:
|
|
player->ADD_GOSSIP_ITEM(0, "Tauren", GOSSIP_SENDER_MAIN, 6 + 500);
|
|
break;
|
|
}
|
|
player->ADD_GOSSIP_ITEM(0, "« Back", GOSSIP_SENDER_MAIN, 76);
|
|
|
|
player->SEND_GOSSIP_MENU(82, creature->GetGUID());
|
|
break;
|
|
}
|
|
default:
|
|
if (action > 11)
|
|
{
|
|
// Display warning, re-invoke selection with mod of 500 to change race. 500 is just arbitrary.
|
|
player->ADD_GOSSIP_ITEM_EXTENDED(1, "[Not shown to player.]", GOSSIP_SENDER_MAIN, action % 500, "You are about to undergo a race change. Your professions will be reset. If you are changing factions, your PvP title will update upon your next kill, and reputations will be converted.", 0, false);
|
|
player->SEND_GOSSIP_MENU(82, creature->GetGUID());
|
|
break;
|
|
}
|
|
|
|
if (player->GetIsFlaggedForRename())
|
|
player->SetAtLoginFlag(AT_LOGIN_RENAME);
|
|
|
|
if (player->GetIsFlaggedForGenderSwap())
|
|
{
|
|
uint32 displayId = player->GetNativeDisplayId();
|
|
uint32 new_displayId = displayId;
|
|
Gender gender;
|
|
if (player->getGender() == GENDER_FEMALE)
|
|
{
|
|
new_displayId = player->getRace() == RACE_BLOODELF ? displayId+1 : displayId-1;
|
|
gender = GENDER_MALE;
|
|
}
|
|
else if (player->getGender() == GENDER_MALE)
|
|
{
|
|
new_displayId = player->getRace() == RACE_BLOODELF ? displayId-1 : displayId+1;
|
|
gender = GENDER_FEMALE;
|
|
}
|
|
|
|
// Set gender
|
|
player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender);
|
|
player->SetByteValue(PLAYER_BYTES_3, 0, gender);
|
|
|
|
// Change display ID
|
|
player->SetDisplayId(new_displayId);
|
|
player->SetNativeDisplayId(new_displayId);
|
|
}
|
|
|
|
player->DestroyItemCount(RACE_CHANGE_TOKEN, 1, true, false);
|
|
std::string IP_str = player->GetSession()->GetRemoteAddress();
|
|
sLog->outChar("Account: %d (IP: %s) Race Change on Character:[%s] (guid: %u) from Race ID %u to %u", player->GetSession()->GetAccountId(), IP_str.c_str(), player->GetName(), player->GetGUIDLow(), action, player->getRace());
|
|
player->ChangeRace(player, action);
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
enum RaceChanger
|
|
{
|
|
EVENT_MORPH = 1
|
|
};
|
|
|
|
int modelIds[] = {21869, 21839, 21875, 21844, 21847, 21863}; // 6 length
|
|
|
|
struct racechangerAI : public Scripted_NoMovementAI
|
|
{
|
|
racechangerAI(Creature *c) : Scripted_NoMovementAI(c) {}
|
|
|
|
EventMap events;
|
|
|
|
void Reset()
|
|
{
|
|
events.Reset();
|
|
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
|
|
events.ScheduleEvent(EVENT_MORPH, 1); // initial switch
|
|
}
|
|
|
|
void UpdateAI(const uint32 diff)
|
|
{
|
|
events.Update(diff);
|
|
while (uint32 eventId = events.ExecuteEvent())
|
|
{
|
|
switch (eventId)
|
|
{
|
|
case EVENT_MORPH:
|
|
me->SetDisplayId(modelIds[urand(0, 5)]);
|
|
events.ScheduleEvent(EVENT_MORPH, 30 * IN_MILLISECONDS); // repeat after 30 sec
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
CreatureAI* GetAI_racechanger(Creature* creature)
|
|
{
|
|
return new racechangerAI(creature);
|
|
}
|
|
|
|
void AddSC_racechanger()
|
|
{
|
|
Script *newscript;
|
|
|
|
newscript = new Script;
|
|
newscript->Name="racechanger";
|
|
newscript->pGossipHello = &GossipHello_racechanger;
|
|
newscript->pGossipSelect = &GossipSelect_racechanger;
|
|
newscript->GetAI = &GetAI_racechanger;
|
|
newscript->RegisterSelf();
|
|
}
|