[Author's Note]:
Well it took bloody long enough, didn't it?
To anyone who was looking for this guide much earlier, I apologize. I've had a really crazy second half of the year and that's slowed down most things WoW-modding related to a crawl for me.
This guide goes out to marx, who was the one who first wanted it. I hope it's still not too late to help.
This guide was written for the TrinityCore, but given that that's a fork off of MANgOS (did I get that right?) I'd guess it'd work there as well. In theory, the same basic idea could work for ArcEmu but not knowing ArcEmu I have no idea where you'd want to look for it.
WARNING (EDIT):
While doing this shouldn't cause any problems between your server and your client, please consider reading the replies to understand more about the delicate connection between them and how doing this sort of thing can, potentially, cause problems. This information kindly brought to you via the ever-knowledgeable schlumpf.
[Warning]:
This does alter the base code of your server. So, if you upgrade your core, then you will lose the modifications and you'll have to start all over again.
With that in mind, Let's begin.
[]A Guide to Raising Base Attribute Limits[]
[CORE]: TrinityCore
[WoW Version]:3.3.5a (WoLK)
:"]
The goal of this guide is to show you how to alter the limits on the player's basic attributes and attributes-per-level. This sort of thing is only really useful if you're planning to make some alterations to gameplay, or for your own amusement. While it's not actually that hard, it will require a server recompile and restart. If you've never installed a server before you should probably take a look at that and get a bit of a feel for it.
Please note, while it's entirely possible to do this without knowledge of programming or databases, and just on working knowledge of computers such knowledge will make it easier.
:"]
[Required Tools]:
An editor capable of editing .cpp and .h Files (having a find feature will also be useful)
I personally use Notepad++, which I'd recommend highly to anyone. It's got some basic highlighting in there, too, so that helps. Get it Here
Having a method of access and editing your Databases.
There's a bunch of different tools out there for this. Personally, I just use phpMyAdmin that comes with MySQL. Maybe not the best solution, but it's easy for me to access and modify whenever I want to.
:"]
[Editing Targets]:
Sourcecode Files:
*servergameEntitiesPlayerPlayer.ccp
*servergameEntitiesPlayerPlayer.h
Databases:
(World Database) :: (player_levelstats)
[Altering the Code]:
{
Alright. Now that we're all set up, let's get started.
First thing you'll need to do is open the two files "Player.cpp" and "Player.h".
Navigate to the folder in which you have your sourcecode files.
Select the "server" folder.
Select the "game" folder.
Select the "Entities" folder.
Select the "Player" folder.
You should now see two files: "Player.cpp" and "Player.h". You'll want to open them both up. I'll be covering the changes to "Player.h" first.
[attachment=9:2ttfkmim]05.png[/attachment:2ttfkmim]
Normally, when you open the files they'll look something like this (my view is from Notepad++)
[attachment=8:2ttfkmim]06.png[/attachment:2ttfkmim]
To make it easier to highlight just the sections we want, I'm going to fold all the brackets up. If you're new to Notepad++ what you need to do is go to the 'View' menu at the told and select 'Fold All'. You can also use the shortcut "Alt-0".
If you haven't played around with C++ that much, you might want to consider reading the following hidden section. Otherwise, you can overlook it.
:"]
In C++ - an object orientated language - programs are broken down into objects, which both store and process data. C++ uses two different file types - .h and .cpp - to describe what a class is and how it works.
.h files - or header files - contain a list of everything within the class, and will ocassionally describe their functioning. Functions that are described in the header files are refered to as 'inline' functions.
.cpp files - or dot-c-plus-plus files - when used for classes contain descriptions of the functioning of the elements of the class.
Within the TrinityCore, all players are built using the Player class, and we'll need to change one of both types of functions to allow players to have base stats higher than 255.
The reason we're in Player.h is because there's an inline function named "PlayerLevelInfo" We're going to do a search for it.
[attachment=7:2ttfkmim]10.png[/attachment:2ttfkmim]
Once we're there, you'll notice two instances of a uint8 datatype. (As far as I know) this function is actually responsible for getting the data from the databases, and the uint8 are the datatypes responsible for holding those numbers. Unfortunately, no matter what gets put in the databases, uint8 can't store a value over 255.
[attachment=6:2ttfkmim]11.png[/attachment:2ttfkmim]
Because I want to have a much wider range available, I'm going to use uint16, which will let me get up to 65,535. Since I only plan to use up to four digits maximum, this gives me plenty of room. And have lots of room to play around with stat ranges if I decide I want to scale up.
If that's not going to be enough for you, you can always move up to a uint32, which should get you up to 4,294,967,295. If you need stats larger than that I'll be stunned.
With the changes, my copy now looks like this:
[attachment=5:2ttfkmim]12.png[/attachment:2ttfkmim]
I'd advise moving to the end of the line and adding a comment (type "//" then continue typing your message on the same line) to mark the place so you can find it in the future if you need to change it again.
Once you're done save and switch over to "Player.cpp"
This time, we're looking for a function that assigns the stats every level. You'll want to do a search for "Player::InitStatsForLevel". It's important to include the 'Player::' because otherwise you'll find not only where that function is described, but every single time the class would ever use it.
Once you get there, you should more or less see this:
[attachment=4:2ttfkmim]13.png[/attachment:2ttfkmim]
Once again, we need to go in and alter a pair of uint8s. There's more uint8s there than just these two, but these are the only ones we actually need to change.
[attachment=3:2ttfkmim]14.png[/attachment:2ttfkmim]
Once again, I've set mine to be uint16s. Go ahead and save the file. Once you've done that, if you haven't been modifying the originals used to compile your server you'll need to overwrite the origins so that when you recompile the server will take these changes into affect.
With that completed, let's move on to the databases.
[Changing the Database]:
Now, before we begin to make some changes, let's take a look at some relevant data. Steer your browser on over to the following location:
http://archive.trinitycore.info/Player_levelstats_tc2 Scroll down (or do a find-search) until you reach "Description of the fields" What you want is the descriptions of the "race" and "class" fields, as show below:
[attachment=2:2ttfkmim]17.png[/attachment:2ttfkmim]
With those two keys, we are ready to edit the hell out of the stats.
Log into your database.
Once logged in, select your 'World' table (usually named 'World') and scroll down until you see the table titled "player_levelstats"
[attachment=1:2ttfkmim]18oops.png[/attachment:2ttfkmim]
Now, before we can change anything, we'll need to make sure that the actual datatypes for our database can hold the kind of number we want to put in there.
Go ahead and use whatever method your database editor provides to edit the structure of this particular table. I believe default type for all the stats in this table is Tinyint(3), which caps them at a 3 digit number. You'll want to upgrade them all to smallInts. You should only really need a Smallint(3), which will let you have up to 32,767 inside each one.
[attachment=0:2ttfkmim]19oops.png[/attachment:2ttfkmim]
This allows you to store the larger numbers that your server can now accept. I've already made the changes to mine. Here's how you'll make the changes to yours.
Open up whatever tab or method you use to execute SQL scripts for your database (mine's built into the interface) and prepare to do an update. What you'll need to enter is something like this:
UPDATE `player_levelstats` SET `str`=[value-1],`agi`=[value-2],`sta`=[value-3],`inte`=[value-4],`spi`=[value-5] WHERE `race`=[race number],`class`=[class number], `level`=[level number]
Each of the value-[number]s is where you'd insert whatever number you wanted (don't keep the bracket) that stat to be for whatever race, class, and level you specified. If you don't want one of the variables, simply remove it. For instance, I wanted my basic stats to be the same at every level for all races and classes, so I simply used the format:
UPDATE `player_levelstats` SET `str`=[value-1],`agi`=[value-2],`sta`=[value-3],`inte`=[value-4],`spi`=[value-5] WHERE `race`=[race number],`class`=[class number]
Once the update has been done, you'll need to recompile your server using your modified "Player.h" and "Player.cpp". Recompiling and restarting will also take care of the server accepting the changes you've made to the database.
And voila! That's it!
Cheers!
~Rimewynd