This is a read only copy without any forum functionality of the old Modcraft forum.
If there is anything that you would like to have removed, message me on Discord via Kaev#5208.
Big thanks to Alastor for making this copy!

Menu

Author Topic: [TUTORIAL] How to Have Base Player Attributes > 255  (Read 6733 times)

Rimewynd

  • Registred Member
  • GM Isle Explorer
  • *****
  • Posts: 20
    • View Profile
[TUTORIAL] How to Have Base Player Attributes > 255
« on: February 08, 2013, 07:47:11 pm »

[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)

Quote from: "[Goal
:"]

   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.

Quote from: "[Goal
:"]
[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.

Quote from: "[Goal
:"]
[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.

   
Quote from: "[Relevant C++ Info
:"]
      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
« Last Edit: September 18, 2014, 02:53:06 am by Admin »
“The major problem—one of the major problems, for there are several—one of the many major problems..."
 ~ A quote that roughly summarizes my attempts at WoW-modding.

kojak488

  • Registred Member
  • Creator of Worlds
  • *****
  • Posts: 351
    • View Profile
Re: [TUTORIAL] How to Have Base Player Attributes > 255
« Reply #1 on: September 18, 2014, 01:50:08 am »
Great guide.  Like Shlumpf I thought this was hard coded into the client.  I enjoy being wrong every now and again. :D
« Last Edit: January 01, 1970, 01:00:00 am by Admin »

schlumpf

  • Administrator
  • Creator of Worlds
  • *****
  • Posts: 2967
    • View Profile
Re: [TUTORIAL] How to Have Base Player Attributes > 255
« Reply #2 on: September 18, 2014, 01:52:23 am »
It is hardcoded, obviously, and freely changing things like this will lead to undefined behavior.
« Last Edit: January 01, 1970, 01:00:00 am by Admin »

Rimewynd

  • Registred Member
  • GM Isle Explorer
  • *****
  • Posts: 20
    • View Profile
Re: [TUTORIAL] How to Have Base Player Attributes > 255
« Reply #3 on: September 18, 2014, 02:01:01 am »
@kojak488:

Thank you! First time I really made one for public consumption. Glad you found it helpful!


@schlumpf:

Really? That's fascinating. I had no idea that this would force undefined behaviour on the client's end.

I'm not entirely sure how to test for that, as while I understand a decent bit about programming, I'm still struggling to come to terms with a lot of WoW-modding stuff. Would it be fair/a good idea to put that warning at the beginning of the guide?

RE: The WoW client: I'm kinda dissatisfied with it in a number of ways, and I feel like half of what I'm doing is trying to circumvent it. I thought this had in an acceptable manor, but if using this is potentially harmful I ought to post a warning. I'm not entirely sure how *how* it'd be harmful off the top of my head, so if you're willing to education me I'd be really curious.
« Last Edit: January 01, 1970, 01:00:00 am by Admin »
“The major problem—one of the major problems, for there are several—one of the many major problems..."
 ~ A quote that roughly summarizes my attempts at WoW-modding.

schlumpf

  • Administrator
  • Creator of Worlds
  • *****
  • Posts: 2967
    • View Profile
Re: [TUTORIAL] How to Have Base Player Attributes > 255
« Reply #4 on: September 18, 2014, 02:42:39 am »
Quote from: "Rimewynd"
I'm not entirely sure how *how* it'd be harmful off the top of my head, so if you're willing to education me I'd be really curious.
In general: A lot of things are hardcoded, like the actual size of those attributes. It seems like the server uses a wrong size to begin with, so increasing it is fine. Increasing it more might break.

In the end, these attributes map to fields in the unit descriptors. The fields in the unit descriptors are not defined by the server, but by the client. Thus, if you increase the size of the descriptor on the server, it will overlap into another descriptor at some point, thus will (partially) overwrite a different descriptor. Not exactly undefined behavior, but resulting in something like increasing a different stat than intended.

In this case, everything is fine as all you are doing is fixing a bug in the server.

I don't know how PlayerLevelInfo is used in the emulator. Likely it is server side only. Thus, changing the field size there is fine. Changing the type for i in the for loops is not changing anything here. As mentioned above InitStatsForLevel does not change anything at all, you can just leave it as it is. Changing database is server side again.

You never actually change anything sent from the server to the client. It looks like the server already correctly sends a bigger field than is used in the database.
« Last Edit: January 01, 1970, 01:00:00 am by Admin »

Rimewynd

  • Registred Member
  • GM Isle Explorer
  • *****
  • Posts: 20
    • View Profile
Re: [TUTORIAL] How to Have Base Player Attributes > 255
« Reply #5 on: September 18, 2014, 02:50:45 am »
Ohhhhhh.... I get it!

Glad to know that, in this case, everything's alright. Thanks for the swift reply, schlumpf.

Wow, that is going to make sending anything 'new' between the server and the client tricky and hacky at best, and a royal mess at worse.  I'm really beginning to understand now why so many people looking to expand functionality are starting to consider writing it into things like add-ons to 'float' above the client.

Thanks for the education, that really helped me understand a few critical things that I just didn't know about the whole WoW-client-server-ecology beforehand. Certainly makes what I've been trying to do trickier, if not downright non-feasible, but it's nice to know that that's the case (and *why* that'd be the case). It'll help me make a more informed decision about what, exactly, I'm trying to do.

Cheers.
« Last Edit: January 01, 1970, 01:00:00 am by Admin »
“The major problem—one of the major problems, for there are several—one of the many major problems..."
 ~ A quote that roughly summarizes my attempts at WoW-modding.

caduceus

  • Registred Member
  • Race Changer
  • *****
  • Posts: 25
    • View Profile
Re: [TUTORIAL] How to Have Base Player Attributes > 255
« Reply #6 on: March 06, 2015, 05:41:08 am »
[issue resolved]
« Last Edit: January 01, 1970, 01:00:00 am by Admin »