eluna-scripts-ornfelt/lua/WowEmulationScriptPack/C++/racechanger.cpp

286 lines
12 KiB
C++
Raw Permalink Normal View History

2023-08-16 00:50:59 +02:00
// 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();
}