Go Back   EQEmulator Home > EQEmulator Forums > Support > Support::General Support

Support::General Support Post all topics here having to do with errors while trying to connect to an EQEMu server but not about the setup/running of the Server itself.

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #17  
Old 01-25-2016, 12:19 PM
Kingly_Krab
Administrator
 
Join Date: May 2013
Location: United States
Posts: 1,604
Default

Titanium's race-class combinations are actually set separately in the source code. world/client.cpp contains this:
Code:
bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
{
    uint32 bSTR, bSTA, bAGI, bDEX, bWIS, bINT, bCHA, bTOTAL, cTOTAL, stat_points; //these are all uint32 in CharCreate_Struct, so we'll make them uint32 here to make the compiler shut up
    int classtemp, racetemp;
    int Charerrors = 0;


// if this is increased you'll have to add a column to the classrace
// table below
#define _TABLE_RACES 16

    static const int BaseRace[_TABLE_RACES][7] =
    {            /* STR  STA  AGI  DEX  WIS  INT  CHR */
    { /*Human*/      75,  75,  75,  75,  75,  75,  75},
    { /*Barbarian*/ 103,  95,  82,  70,  70,  60,  55},
    { /*Erudite*/    60,  70,  70,  70,  83, 107,  70},
    { /*Wood Elf*/   65,  65,  95,  80,  80,  75,  75},
    { /*High Elf*/   55,  65,  85,  70,  95,  92,  80},
    { /*Dark Elf*/   60,  65,  90,  75,  83,  99,  60},
    { /*Half Elf*/   70,  70,  90,  85,  60,  75,  75},
    { /*Dwarf*/      90,  90,  70,  90,  83,  60,  45},
    { /*Troll*/     108, 109,  83,  75,  60,  52,  40},
    { /*Ogre*/      130, 122,  70,  70,  67,  60,  37},
    { /*Halfling*/   70,  75,  95,  90,  80,  67,  50},
    { /*Gnome*/      60,  70,  85,  85,  67,  98,  60},
    { /*Iksar*/      70,  70,  90,  85,  80,  75,  55},
    { /*Vah Shir*/   90,  75,  90,  70,  70,  65,  65},
    { /*Froglok*/    70,  80, 100, 100,  75,  75,  50},
    { /*Drakkin*/    70,  80,  85,  75,  80,  85,  75}
    };

    static const int BaseClass[PLAYER_CLASS_COUNT][8] =
    {              /* STR  STA  AGI  DEX  WIS  INT  CHR  ADD*/
    { /*Warrior*/      10,  10,   5,   0,   0,   0,   0,  25},
    { /*Cleric*/        5,   5,   0,   0,  10,   0,   0,  30},
    { /*Paladin*/      10,   5,   0,   0,   5,   0,  10,  20},
    { /*Ranger*/        5,  10,  10,   0,   5,   0,   0,  20},
    { /*ShadowKnight*/ 10,   5,   0,   0,   0,   10,  5,  20},
    { /*Druid*/         0,  10,   0,   0,  10,   0,   0,  30},
    { /*Monk*/          5,   5,  10,  10,   0,   0,   0,  20},
    { /*Bard*/          5,   0,   0,  10,   0,   0,  10,  25},
    { /*Rouge*/         0,   0,  10,  10,   0,   0,   0,  30},
    { /*Shaman*/        0,   5,   0,   0,  10,   0,   5,  30},
    { /*Necromancer*/   0,   0,   0,  10,   0,  10,   0,  30},
    { /*Wizard*/        0,  10,   0,   0,   0,  10,   0,  30},
    { /*Magician*/      0,  10,   0,   0,   0,  10,   0,  30},
    { /*Enchanter*/     0,   0,   0,   0,   0,  10,  10,  30},
    { /*Beastlord*/     0,  10,   5,   0,  10,   0,   5,  20},
    { /*Berserker*/    10,   5,   0,  10,   0,   0,   0,  25}
    };

    static const bool ClassRaceLookupTable[PLAYER_CLASS_COUNT][_TABLE_RACES]=
    {                   /*Human  Barbarian Erudite Woodelf Highelf Darkelf Halfelf Dwarf  Troll  Ogre   Halfling Gnome  Iksar  Vahshir Froglok Drakkin*/
    { /*Warrior*/         true,  true,     false,  true,   false,  true,   true,   true,  true,  true,  true,    true,  true,  true,   true,   true},
    { /*Cleric*/          true,  false,    true,   false,  true,   true,   true,   true,  false, false, true,    true,  false, false,  true,   true},
    { /*Paladin*/         true,  false,    true,   false,  true,   false,  true,   true,  false, false, true,    true,  false, false,  true,   true},
    { /*Ranger*/          true,  false,    false,  true,   false,  false,  true,   false, false, false, true,    false, false, false,  false,  true},
    { /*ShadowKnight*/    true,  false,    true,   false,  false,  true,   false,  false, true,  true,  false,   true,  true,  false,  true,   true},
    { /*Druid*/           true,  false,    false,  true,   false,  false,  true,   false, false, false, true,    false, false, false,  false,  true},
    { /*Monk*/            true,  false,    false,  false,  false,  false,  false,  false, false, false, false,   false, true,  false,  false,  true},
    { /*Bard*/            true,  false,    false,  true,   false,  false,  true,   false, false, false, false,   false, false, true,   false,  true},
    { /*Rogue*/           true,  true,     false,  true,   false,  true,   true,   true,  false, false, true,    true,  false, true,   true,   true},
    { /*Shaman*/          false, true,     false,  false,  false,  false,  false,  false, true,  true,  false,   false, true,  true,   true,   false},
    { /*Necromancer*/     true,  false,    true,   false,  false,  true,   false,  false, false, false, false,   true,  true,  false,  true,   true},
    { /*Wizard*/          true,  false,    true,   false,  true,   true,   false,  false, false, false, false,   true,  false, false,  true,   true},
    { /*Magician*/        true,  false,    true,   false,  true,   true,   false,  false, false, false, false,   true,  false, false,  false,  true},
    { /*Enchanter*/       true,  false,    true,   false,  true,   true,   false,  false, false, false, false,   true,  false, false,  false,  true},
    { /*Beastlord*/       false, true,     false,  false,  false,  false,  false,  false, true,  true,  false,   false, true,  true,   false,  false},
    { /*Berserker*/       false, true,     false,  false,  false,  false,  false,  true,  true,  true,  false,   false, false, true,   false,  false}
    };

    if (!cc)
        return false;

    Log.Out(Logs::Detail, Logs::World_Server,"Validating char creation info...");

    classtemp = cc->class_ - 1;
    racetemp = cc->race - 1;
    // these have non sequential race numbers so they need to be mapped
    if (cc->race == FROGLOK) racetemp = 14;
    if (cc->race == VAHSHIR) racetemp = 13;
    if (cc->race == IKSAR) racetemp = 12;
    if (cc->race == DRAKKIN) racetemp = 15;

    // if out of range looking it up in the table would crash stuff
    // so we return from these
    if (classtemp >= PLAYER_CLASS_COUNT) {
        Log.Out(Logs::Detail, Logs::World_Server,"  class is out of range");
        return false;
    }
    if (racetemp >= _TABLE_RACES) {
        Log.Out(Logs::Detail, Logs::World_Server,"  race is out of range");
        return false;
    }

    if (!ClassRaceLookupTable[classtemp][racetemp]) { //Lookup table better than a bunch of ifs?
        Log.Out(Logs::Detail, Logs::World_Server,"  invalid race/class combination");
        // we return from this one, since if it's an invalid combination our table
        // doesn't have meaningful values for the stats
        return false;
    }

    // add up the base values for this class/race
    // this is what they start with, and they have stat_points more
    // that can distributed
    bSTR = BaseClass[classtemp][0] + BaseRace[racetemp][0];
    bSTA = BaseClass[classtemp][1] + BaseRace[racetemp][1];
    bAGI = BaseClass[classtemp][2] + BaseRace[racetemp][2];
    bDEX = BaseClass[classtemp][3] + BaseRace[racetemp][3];
    bWIS = BaseClass[classtemp][4] + BaseRace[racetemp][4];
    bINT = BaseClass[classtemp][5] + BaseRace[racetemp][5];
    bCHA = BaseClass[classtemp][6] + BaseRace[racetemp][6];
    stat_points = BaseClass[classtemp][7];
    bTOTAL = bSTR + bSTA + bAGI + bDEX + bWIS + bINT + bCHA;
    cTOTAL = cc->STR + cc->STA + cc->AGI + cc->DEX + cc->WIS + cc->INT + cc->CHA;

    // the first check makes sure the total is exactly what was expected.
    // this will catch all the stat cheating, but there's still the issue
    // of reducing CHA or INT or something, to use for STR, so we check
    // that none are lower than the base or higher than base + stat_points
    // NOTE: these could just be else if, but i want to see all the stats
    // that are messed up not just the first hit

    if (bTOTAL + stat_points != cTOTAL) {
        Log.Out(Logs::Detail, Logs::World_Server,"  stat points total doesn't match expected value: expecting %d got %d", bTOTAL + stat_points, cTOTAL);
        Charerrors++;
    }

    if (cc->STR > bSTR + stat_points || cc->STR < bSTR) {
        Log.Out(Logs::Detail, Logs::World_Server,"  stat STR is out of range");
        Charerrors++;
    }
    if (cc->STA > bSTA + stat_points || cc->STA < bSTA) {
        Log.Out(Logs::Detail, Logs::World_Server,"  stat STA is out of range");
        Charerrors++;
    }
    if (cc->AGI > bAGI + stat_points || cc->AGI < bAGI) {
        Log.Out(Logs::Detail, Logs::World_Server,"  stat AGI is out of range");
        Charerrors++;
    }
    if (cc->DEX > bDEX + stat_points || cc->DEX < bDEX) {
        Log.Out(Logs::Detail, Logs::World_Server,"  stat DEX is out of range");
        Charerrors++;
    }
    if (cc->WIS > bWIS + stat_points || cc->WIS < bWIS) {
        Log.Out(Logs::Detail, Logs::World_Server,"  stat WIS is out of range");
        Charerrors++;
    }
    if (cc->INT > bINT + stat_points || cc->INT < bINT) {
        Log.Out(Logs::Detail, Logs::World_Server,"  stat INT is out of range");
        Charerrors++;
    }
    if (cc->CHA > bCHA + stat_points || cc->CHA < bCHA) {
        Log.Out(Logs::Detail, Logs::World_Server,"  stat CHA is out of range");
        Charerrors++;
    }

    /*TODO: Check for deity/class/race.. it'd be nice, but probably of any real use to hack(faction, deity based items are all I can think of)
    I am NOT writing those tables - kathgar*/

    Log.Out(Logs::Detail, Logs::World_Server,"Found %d errors in character creation request", Charerrors);

    return Charerrors == 0;
}
Reply With Quote
 


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 06:03 PM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3