Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Server Code Submissions

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #1  
Old 06-21-2009, 06:54 PM
Shendare
Dragon
 
Join Date: Apr 2009
Location: California
Posts: 814
Cool Armor Tint Deluxe

Okay, I wasn't satisfied with a single armor_tint value for an NPC's entire outfit. I wanted the ability to specify colors for individual armor pieces, so I could create colored armor uniforms for guards and such, potentially replacing old low-poly guards with Luclin models.

It wasn't too horribly difficult.



SQL change:
Code:
ALTER TABLE `npc_types` ADD COLUMN `armortint_id` INTEGER UNSIGNED NOT NULL DEFAULT 0 AFTER `drakkin_details`;
SQL table addition:
Code:
CREATE TABLE `npc_types_tint` (
  `id` int unsigned NOT NULL DEFAULT '0',
  `red1h` tinyint unsigned NOT NULL DEFAULT '0',
  `grn1h` tinyint unsigned NOT NULL DEFAULT '0',
  `blu1h` tinyint unsigned NOT NULL DEFAULT '0',
  `red2c` tinyint unsigned NOT NULL DEFAULT '0',
  `grn2c` tinyint unsigned NOT NULL DEFAULT '0',
  `blu2c` tinyint unsigned NOT NULL DEFAULT '0',
  `red3a` tinyint unsigned NOT NULL DEFAULT '0',
  `grn3a` tinyint unsigned NOT NULL DEFAULT '0',
  `blu3a` tinyint unsigned NOT NULL DEFAULT '0',
  `red4b` tinyint unsigned NOT NULL DEFAULT '0',
  `grn4b` tinyint unsigned NOT NULL DEFAULT '0',
  `blu4b` tinyint unsigned NOT NULL DEFAULT '0',
  `red5g` tinyint unsigned NOT NULL DEFAULT '0',
  `grn5g` tinyint unsigned NOT NULL DEFAULT '0',
  `blu5g` tinyint unsigned NOT NULL DEFAULT '0',
  `red6l` tinyint unsigned NOT NULL DEFAULT '0',
  `grn6l` tinyint unsigned NOT NULL DEFAULT '0',
  `blu6l` tinyint unsigned NOT NULL DEFAULT '0',
  `red7f` tinyint unsigned NOT NULL DEFAULT '0',
  `grn7f` tinyint unsigned NOT NULL DEFAULT '0',
  `blu7f` tinyint unsigned NOT NULL DEFAULT '0',
  `red8x` tinyint unsigned NOT NULL DEFAULT '0',
  `grn8x` tinyint unsigned NOT NULL DEFAULT '0',
  `blu8x` tinyint unsigned NOT NULL DEFAULT '0',
  `red9x` tinyint unsigned NOT NULL DEFAULT '0',
  `grn9x` tinyint unsigned NOT NULL DEFAULT '0',
  `blu9x` tinyint unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
Notes:

- I don't know if the table specs (engine, row_format, etc.) are the best ones to use. They were just the defaults used with my MySQL installation.

- Field numberings are Helm, Chest, Arms, Bracers, Gloves, Legs, then Face. The letters after the numbers can help if you're editing the table data directly. 8 and 9 are for Primary and Secondary weapon slots, and as far as I can tell are unused by the client at this time. They can be left at 0.

Server Code changes:

eq_packet_structs.h - Line 1868
Code:
...
  /*085*/  uint8  haircolor;    // Verified
- /*085*/  uint8  beard;      // Verified
+ /*086*/  uint8  beard;      // Verified
  /*087*/  uint8  beardcolor;    // Verified
  /*088*/  uint32  drakkin_heritage;  // Temp Placeholder until field is identified in SoF
  /*092*/  uint32  drakkin_tattoo;    // Temp Placeholder until field is identified in SoF
  /*096*/  uint32  drakkin_details;  // Temp Placeholder until field is identified in SoF
- /*100*/  uint32  armor_tint;    // Temp Placeholder until field is identified in SoF
- /*104*/  uint8  eyecolor1;    // Temp Placeholder until field is identified in SoF
- /*105*/  uint8  eyecolor2;    // Temp Placeholder until field is identified in SoF
- /*106*/  uint8  unknown106[150];  //was uint8  unknown021[168];
+ /*100*/  uint32  armor_tint[MAX_MATERIALS];    // Temp Placeholder until field is identified in SoF
+ /*136*/  uint8  eyecolor1;    // Temp Placeholder until field is identified in SoF
+ /*137*/  uint8  eyecolor2;    // Temp Placeholder until field is identified in SoF
+ /*138*/  uint8  unknown138[118];  //was uint8 unknown106[150]; //was uint8  unknown021[168];
  /*256*/
  };
...
mob.h - Line 374
Code:
...
  int32  in_drakkin_details,
- int32  in_armor_tint,
+ int32  in_armor_tint[MAX_MATERIALS],
  int8   in_aa_title,
...
mob.h - Line 535
Code:
...
  inline int8  GetDrakkinDetails()      const { return drakkin_details; }
- inline int32  GetArmorTint()      const { return armor_tint; }
+ inline int32  GetArmorTint(int8 i)      const { return armor_tint[(i < MAX_MATERIALS) ? i : 0]; }
  inline int8  GetClass()          const { return class_; }
...
mob.h - Line 726
Code:
...
  void  TryDotCritical(int16 spell_id, Mob *caster, int &damage);

- void  SendIllusionPacket(int16 in_race, int8 in_gender = 0xFF, int16 in_texture = 0xFFFF, int16 in_helmtexture = 0xFFFF, int8 in_haircolor = 0xFF, int8 in_beardcolor = 0xFF, int8 in_eyecolor1 = 0xFF, int8 in_eyecolor2 = 0xFF, int8 in_hairstyle = 0xFF, int8 in_luclinface = 0xFF, int8 in_beard = 0xFF, int8 in_aa_title = 0xFF, int32 in_drakkin_heritage = 0xFFFFFFFF, int32 in_drakkin_tattoo = 0xFFFFFFFF, int32 in_drakkin_details = 0xFFFFFFFF, int32 in_armor_tint = 0xFFFFFFFF);
+ void  SendIllusionPacket(int16 in_race, int8 in_gender = 0xFF, int16 in_texture = 0xFFFF, int16 in_helmtexture = 0xFFFF, int8 in_haircolor = 0xFF, int8 in_beardcolor = 0xFF, int8 in_eyecolor1 = 0xFF, int8 in_eyecolor2 = 0xFF, int8 in_hairstyle = 0xFF, int8 in_luclinface = 0xFF, int8 in_beard = 0xFF, int8 in_aa_title = 0xFF, int32 in_drakkin_heritage = 0xFFFFFFFF, int32 in_drakkin_tattoo = 0xFFFFFFFF, int32 in_drakkin_details = 0xFFFFFFFF, int32* in_armor_tint = 0);

  static  int32  GetAppearanceValue(EmuAppearance iAppearance);
...
mob.h - Line 1162
Code:
...
  int32  drakkin_details;
- int32  armor_tint;
+ int32  armor_tint[MAX_MATERIALS];

  int8  aa_title;
...
mob.cpp - Line 89
Code:
...
  int32  in_drakkin_details,
- int32  in_armor_tint,
+ int32  in_armor_tint[MAX_MATERIALS],

  int8   in_aa_title,
...
mob.cpp - Line 187
Code:
...
  drakkin_details    = in_drakkin_details;
- armor_tint = in_armor_tint;
  attack_speed = 0;
...
mob.cpp - Line 249
Code:
...
  }

+ for (i = 0; i < MAX_MATERIALS; i++)
+ {
+   if (in_armor_tint)
+   {
+     armor_tint[i] = in_armor_tint[i];
+   }
+   else
+   {
+     armor_tint[i] = 0;
+   }
+ }

  delta_heading = 0;
...
mob.cpp - Line 792
Code:
...
    ns->spawn.equipment[i] = GetEquipmentMaterial(i);
-   if (armor_tint)
-   {
-      ns->spawn.colors[i].color = armor_tint;
-   }
+   if (armor_tint[i])
+   {
+      ns->spawn.colors[i].color = armor_tint[i];
+   }
    else
    {
      ns->spawn.colors[i].color = GetEquipmentColor(i);
    }
  }
...
mob.cpp - Line 1164
Code:
...
- void Mob::SendIllusionPacket(int16 in_race, int8 in_gender, int16 in_texture, int16 in_helmtexture, int8 in_haircolor, int8 in_beardcolor, int8 in_eyecolor1, int8 in_eyecolor2, int8 in_hairstyle, int8 in_luclinface, int8 in_beard, int8 in_aa_title, int32 in_drakkin_heritage, int32 in_drakkin_tattoo, int32 in_drakkin_details, int32 in_armor_tint) {
+ void Mob::SendIllusionPacket(int16 in_race, int8 in_gender, int16 in_texture, int16 in_helmtexture, int8 in_haircolor, int8 in_beardcolor, int8 in_eyecolor1, int8 in_eyecolor2, int8 in_hairstyle, int8 in_luclinface, int8 in_beard, int8 in_aa_title, int32 in_drakkin_heritage, int32 in_drakkin_tattoo, int32 in_drakkin_details, int32* in_armor_tint) {
...
mob.cpp - Line 1209
Code:
...
  this->helmtexture = in_helmtexture;

+ int i;

  if (in_race > 12 && in_race != 128 && in_race != 130 && in_race != 330 && in_race != 522) {
...
mob.cpp - Line 1223
Code:
...
    this->drakkin_details = 0xFFFFFFFF;
-   this->armor_tint = 0xFFFFFFFF;
+   for (i = 0; i < MAX_MATERIALS; i++)
+   {
+     this->armor_tint[i] = 0xFFFFFFFF;
+   }

  }
...
mob.cpp - Line 1282
Code:
...
    this->drakkin_details = in_drakkin_details;

-   if (in_armor_tint == 0xFFFFFFFF)
-     this->armor_tint = GetArmorTint();
-   else
-     this->armor_tint = in_armor_tint;    

+   for (i = 0; i < MAX_MATERIALS; i++)
+   {
+     if ((in_armor_tint) && (in_armor_tint[i]))
+       this->armor_tint[i] = in_armor_tint[i];
+     else
+       this->armor_tint[i] = GetArmorTint(i);
+   }
    
  }
...
mob.cpp - Line 1308
Code:
...
    this->drakkin_details = CastToClient()->GetBaseDetails();
-   this->armor_tint = 0xFFFFFFFF;
+   for (i = 0; i < MAX_MATERIALS; i++)
+   {
+     this->armor_tint[i] = 0xFFFFFFFF;
+   }
  }
...
mob.cpp - Line 1334
Code:
...
    is->drakkin_details = this->drakkin_details;
-   is->armor_tint = this->armor_tint;
+   for (i = 0; i < MAX_MATERIALS; i++)
+   {
+     is->armor_tint[i] = this->armor_tint[i];
+   }
  
    DumpPacket(outapp);
...
npc.cpp - Line 97
Code:
...
    d->drakkin_details,
-   d->armor_tint,
+   (int32*)d->armor_tint,
    0,
...
zonedump.h - Line 89
Code:
...
    int32  drakkin_details;
-   int32  armor_tint;
+   int32  armor_tint[MAX_MATERIALS];
//  int8  aa_title;  ////not loaded from DB
...
zonedb.cpp - Line 1053
Code:
...
      "npc_types.drakkin_details,"
+     "npc_types.armortint_id,"
      "npc_types.armortint_red,"
...
zonedb.cpp - Line 1144
Code:
...
        tmpNPCType->drakkin_details = atoi(row[r++]);

-       tmpNPCType->armor_tint = (atoi(row[r++]) & 0xFF) << 16;
-       tmpNPCType->armor_tint |= (atoi(row[r++]) & 0xFF) << 8;
-       tmpNPCType->armor_tint |= (atoi(row[r++]) & 0xFF);
-       tmpNPCType->armor_tint |= (tmpNPCType->armor_tint) ? (0xFF << 24) : 0;

+       uint32 armor_tint_id = atoi(row[r++]);
+       tmpNPCType->armor_tint[0] = (atoi(row[r++]) & 0xFF) << 16;
+       tmpNPCType->armor_tint[0] |= (atoi(row[r++]) & 0xFF) << 8;
+       tmpNPCType->armor_tint[0] |= (atoi(row[r++]) & 0xFF);
+       tmpNPCType->armor_tint[0] |= (tmpNPCType->armor_tint[0]) ? (0xFF << 24) : 0;
+
+       int i;
+       if (armor_tint_id > 0)
+       {
+         if (tmpNPCType->armor_tint[0] == 0)
+         {
+           char at_errbuf[MYSQL_ERRMSG_SIZE];
+           char *at_query = NULL;
+           MYSQL_RES *at_result = NULL;
+            MYSQL_ROW at_row;
+            
+            MakeAnyLenString(&at_query,
+             "SELECT "
+             "red1h,grn1h,blu1h,"
+             "red2c,grn2c,blu2c,"
+             "red3a,grn3a,blu3a,"
+             "red4b,grn4b,blu4b,"
+             "red5g,grn5g,blu5g,"
+             "red6l,grn6l,blu6l,"
+             "red7f,grn7f,blu7f,"
+             "red8x,grn8x,blu8x,"
+             "red9x,grn9x,blu9x "
+             "FROM npc_types_tint WHERE id=%d", armor_tint_id);
+
+           if (RunQuery(at_query, strlen(at_query), at_errbuf, &at_result))
+           {
+             if ((at_row = mysql_fetch_row(at_result)))
+             {
+               for (i = 0; i < MAX_MATERIALS; i++)
+               {
+                 tmpNPCType->armor_tint[i] = atoi(at_row[i * 3]) << 16;
+                 tmpNPCType->armor_tint[i] |= atoi(at_row[i * 3 + 1]) << 8;
+                 tmpNPCType->armor_tint[i] |= atoi(at_row[i * 3 + 2]);
+                  tmpNPCType->armor_tint[i] |= (tmpNPCType->armor_tint[i]) ? (0xFF << 24) : 0;
+               }
+             }
+             else
+             {
+               armor_tint_id = 0;
+             }
+           }
+           else
+           {
+             armor_tint_id = 0;
+           }
+
+           if (at_result)
+           {
+              mysql_free_result(at_result);
+            }
+            
+           safe_delete_array(at_query);
+         }
+         else
+         {
+           armor_tint_id = 0;
+         }
+       }
+
+       if (armor_tint_id == 0)
+       {
+         for (i = 1; i < MAX_MATERIALS; i++)
+         {
+           tmpNPCType->armor_tint[i] = tmpNPCType->armor_tint[0];
+         }
+       }

        tmpNPCType->see_invis = atoi(row[r++])==0?false:true;      // Set see_invis flag
...
I think that got everything.

Last edited by trevius; 06-22-2009 at 01:11 PM.. Reason: Changed zonedb.h to zonedump.h
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 12:05 AM.


 

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