PDA

View Full Version : 2.4.3 Race Change



Grim
07-20-2016, 03:51 AM
My brother and I worked on this script and We can simply say it works flawlessly.

We developed this script because since pre-WOTLK didn't have race/faction change. (Tested on CMangos 2.4.3) No doubts that it should work on 1.12.1 or even WOTLK.
Thanks to Foereaper, Tommy, Jpp and Syphex for helpin' us out!


--[[

Race Change Script
Developed for CMaNGOS 2.4.3

Developers: Grim, Render1982

What does it do:

For forty gold, it will change the player's race/faction.
If it's a faction change it will then teleport the player to their major city (SW and Org) and set their hearthstone binding to their teleport location.

How is it done:
It executes an SQL Query then Logs Out the player. all in only a second!

Known Bugs:

Items such as mounts and tabards won't change. (Implement Soon?) Temporary Fix was remove all the Race Restrictions


]]

local MoneyCount = 400000
local NPC_ENTRY = 60012

-- Do not touch these variables
local pGUID = 0
local coinage = 0
local isAlliance = false;
local isGM = false;

function ChangeRaceMenu(event, player, unit)

-- Check if the player is a GM; if so make it free
isGM = player:IsGM()
if isGM == true then
ReqCost = 0;
end

-- Check the player's class
if not (player:GetClass() == 3 or player:GetClass() == 7 or player:GetClass() == 11) then
player:GossipMenuAddItem(0, "Change Race to Human", 0, 1)
end

if not (player:GetClass() == 2 or player:GetClass() == 7 or player:GetClass() == 8 or player:GetClass() == 9) then
player:GossipMenuAddItem(0, "Change Race to Night Elf", 0, 2)
end

if not (player:GetClass() == 7 or player:GetClass() == 8 or player:GetClass() == 9 or player:GetClass() == 11) then
player:GossipMenuAddItem(0, "Change Race to Dwarf", 0, 3)
end

if not (player:GetClass() == 2 or player:GetClass() == 7 or player:GetClass() == 11 or player:GetClass() == 3) then
player:GossipMenuAddItem(0, "Change Race to Gnome", 0, 4)
end

if not (player:GetClass() == 2 or player:GetClass() == 8 or player:GetClass() == 11 or player:GetClass() == 5) then
player:GossipMenuAddItem(0, "Change Race to Orc", 0, 5)
end

if not (player:GetClass() == 2 or player:GetClass() == 8 or player:GetClass() == 9 or player:GetClass() == 4 or player:GetClass() == 5) then
player:GossipMenuAddItem(0, "Change Race to Tauren", 0, 6)
end

if not (player:GetClass() == 2 or player:GetClass() == 9 or player:GetClass() == 11) then
player:GossipMenuAddItem(0, "Change Race to Troll", 0, 7)
end

if not (player:GetClass() == 3 or player:GetClass() == 2 or player:GetClass() == 7 or player:GetClass() == 11) then
player:GossipMenuAddItem(0, "Change Race to Undead", 0, 8)
end

isAlliance = player:IsAlliance()
coinage = player:GetCoinage()
player:GossipMenuAddItem(0, "Nevermind..", 0, 9)
player:GossipSendMenu(1, unit)
end

-- Change the player's race, teleport them and set their hearthstone if needed, and deduct the forty gold.
function ChangeRaceSelect(event, player, unit, sender, intid, code)
if (intid == 1) then
if (coinage < MoneyCount) then
player:SendAreaTriggerMessage("Insufficent Funds!")
player:GossipComplete()
else
if (isAlliance == false) then
player:Teleport(0, -8944, 559, 94, 5.4)
player:SetBindPoint(-8944, 559, 94, 0, 1519)
end
player:ModifyMoney(-MoneyCount)
CreateLuaEvent(ToHuman, 1000, 2)
pGUID = player:GetGUIDLow()
player:LogoutPlayer(true)
end
elseif (intid == 2) then
if (coinage < MoneyCount) then
player:SendAreaTriggerMessage("Insufficent Funds!")
player:GossipComplete()
else
if (isAlliance == false) then
player:Teleport(0, -8944, 559, 94, 5.4)
player:SetBindPoint(-8944, 559, 94, 0, 1519)
end
player:ModifyMoney(-MoneyCount)
CreateLuaEvent(ToNelf, 1000, 2)
pGUID = player:GetGUIDLow()
player:LogoutPlayer(true)
end
elseif (intid == 3) then
if (coinage < MoneyCount) then
player:SendAreaTriggerMessage("Insufficent Funds!")
player:GossipComplete()
else
if (isAlliance == false) then
player:Teleport(0, -8944, 559, 94, 5.4)
player:SetBindPoint(-8944, 559, 94, 0, 1519)
end
player:ModifyMoney(-MoneyCount)
CreateLuaEvent(ToDwarf, 1000, 2)
pGUID = player:GetGUIDLow()
player:LogoutPlayer(true)
end
elseif (intid == 4) then
if (coinage < MoneyCount) then
player:SendAreaTriggerMessage("Insufficent Funds!")
player:GossipComplete()
else
if (isAlliance == false) then
player:Teleport(0, -8944, 559, 94, 5.4)
player:SetBindPoint(-8944, 559, 94, 0, 1519)
end
player:ModifyMoney(-MoneyCount)
CreateLuaEvent(ToGnome, 1000, 2)
pGUID = player:GetGUIDLow()
player:LogoutPlayer(true)
end
elseif (intid == 5) then
if (coinage < MoneyCount) then
player:SendAreaTriggerMessage("Insufficent Funds!")
player:GossipComplete()
else
if (isAlliance == true) then
player:Teleport(1, 1425.7, -4365.1, 25.24, 1.2)
player:SetBindPoint(1425.7, -4365.1, 25.24, 1, 1637)
end
player:ModifyMoney(-MoneyCount)
CreateLuaEvent(ToOrc, 1000, 2)
pGUID = player:GetGUIDLow()
player:LogoutPlayer(true)

end
elseif (intid == 6) then
if (coinage < MoneyCount) then
player:SendAreaTriggerMessage("Insufficent Funds!")
player:GossipComplete()
else
if (isAlliance == true) then
player:Teleport(1, 1425.7, -4365.1, 25.24, 1.2)
player:SetBindPoint(1425.7, -4365.1, 25.24, 1, 1637)
end
player:ModifyMoney(-MoneyCount)
CreateLuaEvent(ToTauren, 1000, 2)
pGUID = player:GetGUIDLow()
player:LogoutPlayer(true)
if (isAlliance == true) then
player:Teleport(1, 1425.7, -4365.1, 25.24, 1.2)
player:SetBindPoint(1425.7, -4365.1, 25.24, 1, 1637)
end
end
elseif (intid == 7) then
if (coinage < MoneyCount) then
player:SendAreaTriggerMessage("Insufficent Funds!")
player:GossipComplete()
else
if (isAlliance == true) then
player:Teleport(1, 1425.7, -4365.1, 25.24, 1.2)
player:SetBindPoint(1425.7, -4365.1, 25.24, 1, 1637)
end
player:ModifyMoney(-MoneyCount)
CreateLuaEvent(ToTroll, 1000, 2)
pGUID = player:GetGUIDLow()
player:LogoutPlayer(true)
end
elseif (intid == 8) then
if (coinage < MoneyCount) then
player:SendAreaTriggerMessage("Insufficent Funds!")
player:GossipComplete()
else
if (isAlliance == true) then
player:Teleport(1, 1425.7, -4365.1, 25.24, 1.2)
player:SetBindPoint(1425.7, -4365.1, 25.24, 1, 1637)
end
player:ModifyMoney(-MoneyCount)
CreateLuaEvent(ToUndead, 1000, 2)
pGUID = player:GetGUIDLow()
player:LogoutPlayer(true)
end
elseif (intid == 9) then
player:GossipComplete()
end
end

-- Execute the SQL Query and Change their Race

function ToHuman(event, delay, call)
CharDBExecute("UPDATE `characters`.`characters` SET `race`=1 WHERE `guid`="..pGUID..";")
end

function ToDwarf(event, delay, call)
CharDBExecute("UPDATE `characters`.`characters` SET `race`=3 WHERE `guid`="..pGUID..";")
end

function ToNelf(event, delay, call)
CharDBExecute("UPDATE `characters`.`characters` SET `race`=4 WHERE `guid`="..pGUID..";")
end

function ToUndead(event, delay, call)
CharDBExecute("UPDATE `characters`.`characters` SET `race`=5 WHERE `guid`="..pGUID..";")
end

function ToTauren(event, delay, call)
CharDBExecute("UPDATE `characters`.`characters` SET `race`=6 WHERE `guid`="..pGUID..";")
end

function ToGnome(event, delay, call)
CharDBExecute("UPDATE `characters`.`characters` SET `race`=7 WHERE `guid`="..pGUID..";")
end

function ToTroll(event, delay, call)
CharDBExecute("UPDATE `characters`.`characters` SET `race`=8 WHERE `guid`="..pGUID..";")
end

function ToOrc(event, delay, call)
CharDBExecute("UPDATE `characters`.`characters` SET `race`=2 WHERE `guid`="..pGUID..";")
end
RegisterCreatureGossipEvent(NPC_ENTRY, 1, ChangeRaceMenu)
RegisterCreatureGossipEvent(NPC_ENTRY, 2, ChangeRaceSelect)

Update:
Fixed Impossible Race Change "Undead Paladins"
Added a GM check so it would remove the price if there is user is a GM (Requires .gm on)

Foereaper
07-20-2016, 09:47 PM
I would suggest making your script somewhat more dynamic instead of using so many static single use functions. As an example, all your ToGnome, ToHuman functions could be merged into a single function, where you simply pass the new race ID to the function. The same could be done with all of your elseif intid's, they could simply be merged into a single piece of code where you use the new race ID as the identifier for specific information.

Also, your code is relatively unsafe with the way you pass variables between functions, especially since you store info directly in the global namespace. This is bound to cause collisions and should be revised. I have rewritten your script to be more secure and efficient, let me know if you want me to post it :)

Grim
07-20-2016, 10:39 PM
That's the best part about coding: You can do the same thing an infinite number of ways. You can post it if you like, it would only benefit me and enhance my scripting skills. :)

Foereaper
07-20-2016, 10:54 PM
The below is untested, however it *should* work :P At least the logic of it does. Let me know if there are any issues.


--[[

Race Change Script
Developed for CMaNGOS 2.4.3

Developers: Grim, Render1982

What does it do:

For forty gold, it will change the player's race/faction.
If it's a faction change it will then teleport the player to their major city (SW and Org) and set their hearthstone binding to their teleport location.

How is it done:
It executes an SQL Query then Logs Out the player. all in only a second!

Known Bugs:

Items such as mounts and tabards won't change. (Implement Soon?) Temporary Fix was remove all the Race Restrictions


]]

local RaceChanger = {
ReqMoney = 400000,
NPC_ENTRY = 60012,
["RaceInfo"] = {
-- [RaceId] = {"RaceName", TeamId, MapId, AreaId, X, Y, Z, O, [DisallowedClasses]}
[1] = {"Human", 0, 0, 1519, -8944, 559, 94, 5.4, ["ClassFilter"] = {3, 7, 11}},
[2] = {"Orc", 1, 1, 1637, 1425.7, -4365.1, 25.24, 1.2, ["ClassFilter"] = {2, 5, 8, 11}},
[3] = {"Dwarf", 0, 0, 1519, -8944, 559, 94, 5.4, ["ClassFilter"] = {7, 8, 9, 11}},
[4] = {"Night Elf", 0, 0, 1519, -8944, 559, 94, 5.4, ["ClassFilter"] = {2, 7, 8, 9}},
[5] = {"Undead", 1, 1, 1637, 1425.7, -4365.1, 25.24, 1.2, ["ClassFilter"] = {2, 3, 7, 11}},
[6] = {"Tauren", 1, 1, 1637, 1425.7, -4365.1, 25.24, 1.2, ["ClassFilter"] = {2, 4, 5, 8, 9}},
[7] = {"Gnome", 0, 0, 1519, -8944, 559, 94, 5.4, ["ClassFilter"] = {2, 3, 7, 11}},
[8] = {"Troll", 1, 1, 1637, 1425.7, -4365.1, 25.24, 1.2, ["ClassFilter"] = {2, 9, 11}},
},
}

-- Helper function for class filter

local function contains(table, val)
for i=1,#table do
if table[i] == val then
return true
end
end
return false
end

function RaceChanger.OnHello(event, player, unit)
-- Check the player's class
for k, v in pairs(RaceChanger["RaceInfo"]) do
if not(contains(v["ClassFilter"], player:GetClass())) and player:GetRace() ~= k then
player:GossipMenuAddItem(0, "Change Race to "..v[1], 0, k, false, "Are you sure you would like to change your race?", RaceChanger.ReqMoney)
end
end

player:GossipMenuAddItem(0, "Nevermind..", 0, 0)
player:GossipSendMenu(1, unit)
end

function RaceChanger.OnSelect(event, player, unit, sender, intid, code)
if(intid > 0) then
local rInfo = RaceChanger["RaceInfo"][intid]
if (player:GetTeam() ~= rInfo[2]) then
player:Teleport(rInfo[3], rInfo[5], rInfo[6], rInfo[7], rInfo[8])
player:SetBindPoint(rInfo[5], rInfo[6], rInfo[7], rInfo[3], rInfo[4])
end
local pGuid = player:GetGUIDLow()
CreateLuaEvent(function() RaceChanger.ChangeRace(intid, pGuid); end, 1000, 2)
player:LogoutPlayer(true)
else
player:GossipComplete()
end
end

function RaceChanger.ChangeRace(newRace, guid)
CharDBExecute("UPDATE `characters` SET `race`="..newRace.." WHERE `guid`="..guid..";")
end

RegisterCreatureGossipEvent(RaceChanger.NPC_ENTRY, 1, RaceChanger.OnHello)
RegisterCreatureGossipEvent(RaceChanger.NPC_ENTRY, 2, RaceChanger.OnSelect)

Edit: Did a couple small fixes to some typos, oops.

Grim
07-21-2016, 03:18 AM
The gossip menu is blank, all that shows is "Nevermind...". I'd tried commenting out the class checker and it gave an error:

lua_scripts/custom/racechange.lua:66: bad argument #5 to 'Teleport' (number expected, got nil)

UPDATE: Found a glitch, when the user changes their race, the faces sometimes gets glitchy and creating a customization seems to be on the advanced side of things as it works with PlayerBytes which is just a bunch of random numbers :{

Foereaper
07-21-2016, 10:15 PM
Fixed the above script, had messed up a few checks.

Shaorin
08-20-2016, 07:07 AM
i tried to use it but nothing happening. i did amke a npc and set the flag to 3 for "Gossip" i spawn the npc see the menu, i was blood elf and try to make me to night elf.

i get the pay thing. they take the money but nothing after that. nothing saying this is complte. i try to delete cache and relog, even restart the server.
i use Mangos 2.4.3 delevop21 core