Mercenaries now spawn as the same Gender and Size of the Merchant they are purchased from.

Mercenaries now spawn with randomized facial features when purchased.
Setting a lastname for NPCs will now override any hard coded lastname (such as GM Trainers).
This commit is contained in:
Trevius 2014-12-01 19:54:01 -06:00
parent cbadd8bde1
commit 24ea7a0d45
13 changed files with 549 additions and 540 deletions

View File

@ -1,5 +1,11 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 12/01/2014 ==
Trevius: Mercenaries now spawn as the same Gender and Size of the Merchant they are purchased from.
Trevius: Mercenaries now spawn with randomized facial features when purchased.
Trevius: Setting a lastname for NPCs will now override any hard coded lastname (such as GM Trainers).
Required SQL: utils/sql/git/required/2014_12_01_mercs_table_update.sql
== 11/28/2014 ==
Trevius: Fixed a zone crash related to numhits for spells.

View File

@ -30,7 +30,7 @@
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/
#define CURRENT_BINARY_DATABASE_VERSION 9058
#define CURRENT_BINARY_DATABASE_VERSION 9059
#define COMPILE_DATE __DATE__
#define COMPILE_TIME __TIME__
#ifndef WIN32

View File

@ -312,6 +312,7 @@
9056|2014_11_08_RaidMembers.sql|SHOW COLUMNS FROM `raid_members` LIKE 'groupid'|missing|unsigned
9057|2014_11_13_spells_new_updates.sql|SHOW COLUMNS FROM `spells_new` LIKE 'disallow_sit'|empty|
9058|2014_11_26_InventoryTableUpdate.sql|SHOW COLUMNS FROM `inventory` LIKE 'ornamenticon'|empty|
9059|2014_11_30_mercs_table_update.sql|SHOW COLUMNS FROM `mercs` LIKE 'MercSize'|empty|
# Upgrade conditions:
# This won't be needed after this system is implemented, but it is used database that are not

View File

@ -0,0 +1 @@
ALTER TABLE `mercs` ADD `MercSize` float( 0 ) NOT NULL DEFAULT '5' AFTER `Gender`;

View File

@ -9619,7 +9619,7 @@ void Client::Handle_OP_MercenaryHire(const EQApplicationPacket *app)
TakeMoneyFromPP(cost, true);
}
// 0 is approved hire request
// approved hire request
SendMercMerchantResponsePacket(0);
}
else

View File

@ -4985,189 +4985,10 @@ void command_randomfeatures(Client *c, const Seperator *sep)
c->Message(0,"Error: This command requires a target");
else
{
uint16 Race = target->GetRace();
if (Race <= 12 || Race == 128 || Race == 130 || Race == 330 || Race == 522) {
uint8 Gender = target->GetGender();
uint8 Texture = 0xFF;
uint8 HelmTexture = 0xFF;
uint8 HairColor = 0xFF;
uint8 BeardColor = 0xFF;
uint8 EyeColor1 = 0xFF;
uint8 EyeColor2 = 0xFF;
uint8 HairStyle = 0xFF;
uint8 LuclinFace = 0xFF;
uint8 Beard = 0xFF;
uint32 DrakkinHeritage = 0xFFFFFFFF;
uint32 DrakkinTattoo = 0xFFFFFFFF;
uint32 DrakkinDetails = 0xFFFFFFFF;
// Set some common feature settings
EyeColor1 = MakeRandomInt(0, 9);
EyeColor2 = MakeRandomInt(0, 9);
LuclinFace = MakeRandomInt(0, 7);
// Adjust all settings based on the min and max for each feature of each race and gender
switch (Race)
{
case 1: // Human
HairColor = MakeRandomInt(0, 19);
if (Gender == 0) {
BeardColor = HairColor;
HairStyle = MakeRandomInt(0, 3);
Beard = MakeRandomInt(0, 5);
}
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 2);
}
break;
case 2: // Barbarian
HairColor = MakeRandomInt(0, 19);
LuclinFace = MakeRandomInt(0, 87);
if (Gender == 0) {
BeardColor = HairColor;
HairStyle = MakeRandomInt(0, 3);
Beard = MakeRandomInt(0, 5);
}
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 2);
}
break;
case 3: // Erudite
if (Gender == 0) {
BeardColor = MakeRandomInt(0, 19);
Beard = MakeRandomInt(0, 5);
LuclinFace = MakeRandomInt(0, 57);
}
if (Gender == 1) {
LuclinFace = MakeRandomInt(0, 87);
}
break;
case 4: // WoodElf
HairColor = MakeRandomInt(0, 19);
if (Gender == 0) {
HairStyle = MakeRandomInt(0, 3);
}
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 2);
}
break;
case 5: // HighElf
HairColor = MakeRandomInt(0, 14);
if (Gender == 0) {
HairStyle = MakeRandomInt(0, 3);
LuclinFace = MakeRandomInt(0, 37);
BeardColor = HairColor;
}
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 2);
}
break;
case 6: // DarkElf
HairColor = MakeRandomInt(13, 18);
if (Gender == 0) {
HairStyle = MakeRandomInt(0, 3);
LuclinFace = MakeRandomInt(0, 37);
BeardColor = HairColor;
}
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 2);
}
break;
case 7: // HalfElf
HairColor = MakeRandomInt(0, 19);
if (Gender == 0) {
HairStyle = MakeRandomInt(0, 3);
LuclinFace = MakeRandomInt(0, 37);
BeardColor = HairColor;
}
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 2);
}
break;
case 8: // Dwarf
HairColor = MakeRandomInt(0, 19);
BeardColor = HairColor;
if (Gender == 0) {
HairStyle = MakeRandomInt(0, 3);
Beard = MakeRandomInt(0, 5);
}
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 2);
LuclinFace = MakeRandomInt(0, 17);
}
break;
case 9: // Troll
EyeColor1 = MakeRandomInt(0, 10);
EyeColor2 = MakeRandomInt(0, 10);
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 3);
HairColor = MakeRandomInt(0, 23);
}
break;
case 10: // Ogre
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 3);
HairColor = MakeRandomInt(0, 23);
}
break;
case 11: // Halfling
HairColor = MakeRandomInt(0, 19);
if (Gender == 0) {
BeardColor = HairColor;
HairStyle = MakeRandomInt(0, 3);
Beard = MakeRandomInt(0, 5);
}
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 2);
}
break;
case 12: // Gnome
HairColor = MakeRandomInt(0, 24);
if (Gender == 0) {
BeardColor = HairColor;
HairStyle = MakeRandomInt(0, 3);
Beard = MakeRandomInt(0, 5);
}
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 2);
}
break;
case 128: // Iksar
case 130: // VahShir
break;
case 330: // Froglok
LuclinFace = MakeRandomInt(0, 9);
case 522: // Drakkin
HairColor = MakeRandomInt(0, 3);
BeardColor = HairColor;
EyeColor1 = MakeRandomInt(0, 11);
EyeColor2 = MakeRandomInt(0, 11);
LuclinFace = MakeRandomInt(0, 6);
DrakkinHeritage = MakeRandomInt(0, 6);
DrakkinTattoo = MakeRandomInt(0, 7);
DrakkinDetails = MakeRandomInt(0, 7);
if (Gender == 0) {
Beard = MakeRandomInt(0, 12);
HairStyle = MakeRandomInt(0, 8);
}
if (Gender == 1) {
Beard = MakeRandomInt(0, 3);
HairStyle = MakeRandomInt(0, 7);
}
break;
default:
break;
}
target->SendIllusionPacket(Race, Gender, Texture, HelmTexture, HairColor, BeardColor,
EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF,
DrakkinHeritage, DrakkinTattoo, DrakkinDetails);
c->Message(0,"NPC Features Randomized");
}
if (target->RandomizeFeatures())
c->Message(0,"Features Randomized");
else
c->Message(0,"This command requires a Playable Race as the Target");
c->Message(0,"This command requires a Playable Race as the target");
}
}

View File

@ -658,10 +658,12 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue)
void EntityList::AddMerc(Merc *merc, bool SendSpawnPacket, bool dontqueue)
{
if (merc) {
if (merc)
{
merc->SetID(GetFreeID());
if (SendSpawnPacket) {
if (SendSpawnPacket)
{
if (dontqueue) {
// Send immediately
EQApplicationPacket *outapp = new EQApplicationPacket();
@ -673,12 +675,10 @@ void EntityList::AddMerc(Merc *merc, bool SendSpawnPacket, bool dontqueue)
// Queue the packet
NewSpawn_Struct *ns = new NewSpawn_Struct;
memset(ns, 0, sizeof(NewSpawn_Struct));
merc->FillSpawnStruct(ns, merc);
merc->FillSpawnStruct(ns, 0);
AddToSpawnQueue(merc->GetID(), &ns);
safe_delete(ns);
}
//parse->EventMERC(EVENT_SPAWN, merc, nullptr, "", 0);
}
merc_list.insert(std::pair<uint16, Merc *>(merc->GetID(), merc));

View File

@ -62,7 +62,7 @@ Merc::Merc(const NPCType* d, float x, float y, float z, float heading)
skills[r] = database.GetSkillCap(GetClass(),(SkillUseTypes)r,GetLevel());
}
GetMercSize();
size = d->size;
CalcBonuses();
SetHP(GetMaxHP());
@ -112,131 +112,66 @@ void Merc::CalcBonuses()
rooted = FindType(SE_Root);
}
void Merc::GetMercSize() {
float Merc::GetDefaultSize() {
float MercSize = GetSize();
switch(this->GetRace()) {
case 1: // Humans have no race bonus
break;
case 2: // Barbarian
MercSize = 7.0;
break;
case 3: // Erudite
break;
case 4: // Wood Elf
MercSize = 5.0;
break;
case 5: // High Elf
break;
case 6: // Dark Elf
MercSize = 5.0;
break;
case 7: // Half Elf
MercSize = 5.5;
break;
case 8: // Dwarf
MercSize = 4.0;
break;
case 9: // Troll
MercSize = 8.0;
break;
case 10: // Ogre
MercSize = 9.0;
break;
case 11: // Halfling
MercSize = 3.5;
break;
case 12: // Gnome
MercSize = 3.0;
break;
case 128: // Iksar
break;
case 130: // Vah Shir
MercSize = 7.0;
break;
case 330: // Froglok
MercSize = 5.0;
break;
case 522: // Drakkin
MercSize = 5.0;
break;
switch(this->GetRace())
{
case 1: // Humans
MercSize = 6.0;
break;
case 2: // Barbarian
MercSize = 7.0;
break;
case 3: // Erudite
MercSize = 6.0;
break;
case 4: // Wood Elf
MercSize = 5.0;
break;
case 5: // High Elf
MercSize = 6.0;
break;
case 6: // Dark Elf
MercSize = 5.0;
break;
case 7: // Half Elf
MercSize = 5.5;
break;
case 8: // Dwarf
MercSize = 4.0;
break;
case 9: // Troll
MercSize = 8.0;
break;
case 10: // Ogre
MercSize = 9.0;
break;
case 11: // Halfling
MercSize = 3.5;
break;
case 12: // Gnome
MercSize = 3.0;
break;
case 128: // Iksar
MercSize = 6.0;
break;
case 130: // Vah Shir
MercSize = 7.0;
break;
case 330: // Froglok
MercSize = 5.0;
break;
case 522: // Drakkin
MercSize = 5.0;
break;
default:
MercSize = 6.0;
break;
}
this->size = MercSize;
}
void Merc::GenerateAppearance() {
// Randomize facial appearance
int iFace = 0;
if(this->GetRace() == 2) { // Barbarian w/Tatoo
iFace = MakeRandomInt(0, 79);
}
else {
iFace = MakeRandomInt(0, 7);
}
int iHair = 0;
int iBeard = 0;
int iBeardColor = 1;
if(this->GetRace() == 522) {
iHair = MakeRandomInt(0, 8);
iBeard = MakeRandomInt(0, 11);
iBeardColor = MakeRandomInt(0, 3);
}
else if(this->GetGender()) {
iHair = MakeRandomInt(0, 2);
if(this->GetRace() == 8) { // Dwarven Females can have a beard
if(MakeRandomInt(1, 100) < 50) {
iFace += 10;
}
}
}
else {
iHair = MakeRandomInt(0, 3);
iBeard = MakeRandomInt(0, 5);
iBeardColor = MakeRandomInt(0, 19);
}
int iHairColor = 0;
if(this->GetRace() == 522) {
iHairColor = MakeRandomInt(0, 3);
}
else {
iHairColor = MakeRandomInt(0, 19);
}
uint8 iEyeColor1 = (uint8)MakeRandomInt(0, 9);
uint8 iEyeColor2 = 0;
if(this->GetRace() == 522) {
iEyeColor1 = iEyeColor2 = (uint8)MakeRandomInt(0, 11);
}
else if(MakeRandomInt(1, 100) > 96) {
iEyeColor2 = MakeRandomInt(0, 9);
}
else {
iEyeColor2 = iEyeColor1;
}
int iHeritage = 0;
int iTattoo = 0;
int iDetails = 0;
if(this->GetRace() == 522) {
iHeritage = MakeRandomInt(0, 6);
iTattoo = MakeRandomInt(0, 7);
iDetails = MakeRandomInt(0, 7);
}
this->luclinface = iFace;
this->hairstyle = iHair;
this->beard = iBeard;
this->beardcolor = iBeardColor;
this->haircolor = iHairColor;
this->eyecolor1 = iEyeColor1;
this->eyecolor2 = iEyeColor2;
this->drakkin_heritage = iHeritage;
this->drakkin_tattoo = iTattoo;
this->drakkin_details = iDetails;
return MercSize;
}
int Merc::CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat)
@ -1258,7 +1193,6 @@ void Merc::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
ns->spawn.guildrank = 0;
ns->spawn.showhelm = 1;
ns->spawn.flymode = 0;
ns->spawn.size = 0;
ns->spawn.NPC = 1; // 0=player,1=npc,2=pc corpse,3=npc corpse
ns->spawn.IsMercenary = 1;
@ -4940,22 +4874,37 @@ Merc* Merc::LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id,
}
snprintf(npc_type->name, 64, "%s", c->GetMercInfo().merc_name);
}
uint8 gender = 0;
if(merchant_id > 0) {
npc_type->race = merc_template->RaceID;
// Use the Gender and Size of the Merchant if possible
uint8 tmpgender = 0;
float tmpsize = 6.0f;
if(merchant_id > 0)
{
NPC* tar = entity_list.GetNPCByID(merchant_id);
if(tar) {
gender = Mob::GetDefaultGender(npc_type->race, tar->GetGender());
if(tar)
{
tmpgender = tar->GetGender();
tmpsize = tar->GetSize();
}
else
{
tmpgender = Mob::GetDefaultGender(npc_type->race, c->GetMercInfo().Gender);
}
}
else {
gender = c->GetMercInfo().Gender;
else
{
tmpgender = c->GetMercInfo().Gender;
tmpsize = c->GetMercInfo().MercSize;
}
sprintf(npc_type->lastname, "%s's %s", c->GetName(), "Mercenary");
npc_type->gender = gender;
sprintf(npc_type->lastname, "%s's Mercenary", c->GetName());
npc_type->gender = tmpgender;
npc_type->size = tmpsize;
npc_type->loottable_id = 0; // Loottable has to be 0, otherwise we'll be leavin' some corpses!
npc_type->npc_id = 0; //NPC ID has to be 0, otherwise db gets all confuzzled.
npc_type->race = merc_template->RaceID;
npc_type->class_ = merc_template->ClassID;
npc_type->maxlevel = 0; //We should hard-set this to override scalerate's functionality in the NPC class when it is constructed.
@ -4975,6 +4924,7 @@ Merc* Merc::LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id,
snprintf(merc->name, 64, "%s", c->GetMercInfo().merc_name);
merc->SetSuspended(c->GetMercInfo().IsSuspended);
merc->gender = c->GetMercInfo().Gender;
merc->size = c->GetMercInfo().MercSize;
merc->SetHP(c->GetMercInfo().hp <= 0 ? merc->GetMaxHP() : c->GetMercInfo().hp);
merc->SetMana(c->GetMercInfo().hp <= 0 ? merc->GetMaxMana() : c->GetMercInfo().mana);
merc->SetEndurance(c->GetMercInfo().endurance);
@ -4989,6 +4939,11 @@ Merc* Merc::LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id,
merc->drakkin_tattoo = c->GetMercInfo().drakkinTattoo;
merc->drakkin_details = c->GetMercInfo().drakkinDetails;
}
else
{
// Give Random Features to newly hired Mercs
merc->RandomizeFeatures(false, true);
}
if(merc->GetMercID()) {
database.LoadMercBuffs(merc);
@ -5008,7 +4963,8 @@ void Merc::UpdateMercInfo(Client *c) {
snprintf(c->GetMercInfo().merc_name, 64, "%s", name);
c->GetMercInfo().mercid = GetMercID();
c->GetMercInfo().IsSuspended = IsSuspended();
c->GetMercInfo().Gender = gender;
c->GetMercInfo().Gender = GetGender();
c->GetMercInfo().MercSize = GetSize();
c->GetMercInfo().hp = GetHP();
c->GetMercInfo().mana = GetMana();
c->GetMercInfo().endurance = GetEndurance();
@ -5558,6 +5514,11 @@ void Client::SpawnMercOnZone() {
Message(7, "Mercenary Debug: SpawnMercOnZone Suspended Merc.");
}
}
else
{
// No Merc Hired
SendClearMercInfo();
}
}
void Client::SendMercTimer(Merc* merc) {
@ -5604,10 +5565,7 @@ void Client::SpawnMerc(Merc* merc, bool setMaxStats) {
SetMerc(merc);
merc->Unsuspend(setMaxStats);
merc->SetStance(GetMercInfo().Stance);
GetMercInfo().SuspendedTime = 0;
//SendMercTimer(merc);
if (MERC_DEBUG > 0)
Message(7, "Mercenary Debug: SpawnMerc Success.");
@ -5666,7 +5624,6 @@ bool Client::MercOnlyOrNoGroup() {
bool Merc::Unsuspend(bool setMaxStats) {
Client* mercOwner = nullptr;
bool loaded = false;
if(GetMercOwner()) {
mercOwner = GetMercOwner();
@ -5694,12 +5651,8 @@ bool Merc::Unsuspend(bool setMaxStats) {
if(!mercOwner->GetPTimers().Expired(&database, pTimerMercSuspend, false))
mercOwner->GetPTimers().Clear(&database, pTimerMercSuspend);
MercJoinClientGroup();
if(loaded)
if (MercJoinClientGroup())
{
LoadMercSpells();
if(setMaxStats)
{
SetHP(GetMaxHP());
@ -6073,7 +6026,7 @@ void Client::SetMerc(Merc* newmerc) {
GetMercInfo().IsSuspended = newmerc->IsSuspended();
GetMercInfo().SuspendedTime = 0;
GetMercInfo().Gender = newmerc->GetGender();
//GetMercInfo().State = newmerc->GetStance();
GetMercInfo().State = newmerc->IsSuspended() ? MERC_STATE_SUSPENDED : MERC_STATE_NORMAL;
snprintf(GetMercInfo().merc_name, 64, "%s", newmerc->GetName());
if (MERC_DEBUG > 0)
Message(7, "Mercenary Debug: SetMerc New Merc.");

View File

@ -332,9 +332,7 @@ private:
int GroupLeadershipAAHealthRegeneration();
int GroupLeadershipAAOffenseEnhancement();
void GetMercSize();
void GenerateAppearance();
float GetDefaultSize();
bool LoadMercSpells();
bool CheckStance(int16 stance);

View File

@ -739,7 +739,8 @@ void Mob::CreateSpawnPacket(EQApplicationPacket* app, Mob* ForWho) {
NewSpawn_Struct* ns = (NewSpawn_Struct*)app->pBuffer;
FillSpawnStruct(ns, ForWho);
if(strlen(ns->spawn.lastName) == 0) {
if(strlen(ns->spawn.lastName) == 0)
{
switch(ns->spawn.class_)
{
case TRIBUTE_MASTER:
@ -817,70 +818,78 @@ void Mob::CreateSpawnPacket(EQApplicationPacket* app, NewSpawn_Struct* ns) {
// Custom packet data
NewSpawn_Struct* ns2 = (NewSpawn_Struct*)app->pBuffer;
strcpy(ns2->spawn.name, ns->spawn.name);
switch(ns->spawn.class_)
{
case TRIBUTE_MASTER:
strcpy(ns2->spawn.lastName, "Tribute Master");
break;
case ADVENTURERECRUITER:
strcpy(ns2->spawn.lastName, "Adventure Recruiter");
break;
case BANKER:
strcpy(ns2->spawn.lastName, "Banker");
break;
case ADVENTUREMERCHANT:
strcpy(ns->spawn.lastName,"Adventure Merchant");
break;
case WARRIORGM:
strcpy(ns2->spawn.lastName, "GM Warrior");
break;
case PALADINGM:
strcpy(ns2->spawn.lastName, "GM Paladin");
break;
case RANGERGM:
strcpy(ns2->spawn.lastName, "GM Ranger");
break;
case SHADOWKNIGHTGM:
strcpy(ns2->spawn.lastName, "GM Shadowknight");
break;
case DRUIDGM:
strcpy(ns2->spawn.lastName, "GM Druid");
break;
case BARDGM:
strcpy(ns2->spawn.lastName, "GM Bard");
break;
case ROGUEGM:
strcpy(ns2->spawn.lastName, "GM Rogue");
break;
case SHAMANGM:
strcpy(ns2->spawn.lastName, "GM Shaman");
break;
case NECROMANCERGM:
strcpy(ns2->spawn.lastName, "GM Necromancer");
break;
case WIZARDGM:
strcpy(ns2->spawn.lastName, "GM Wizard");
break;
case MAGICIANGM:
strcpy(ns2->spawn.lastName, "GM Magician");
break;
case ENCHANTERGM:
strcpy(ns2->spawn.lastName, "GM Enchanter");
break;
case BEASTLORDGM:
strcpy(ns2->spawn.lastName, "GM Beastlord");
break;
case BERSERKERGM:
strcpy(ns2->spawn.lastName, "GM Berserker");
break;
case MERCERNARY_MASTER:
strcpy(ns->spawn.lastName, "Mercenary Recruiter");
break;
default:
strcpy(ns2->spawn.lastName, ns->spawn.lastName);
break;
}
// Set default Last Names for certain Classes if not defined
if (strlen(ns->spawn.lastName) == 0)
{
switch (ns->spawn.class_)
{
case TRIBUTE_MASTER:
strcpy(ns2->spawn.lastName, "Tribute Master");
break;
case ADVENTURERECRUITER:
strcpy(ns2->spawn.lastName, "Adventure Recruiter");
break;
case BANKER:
strcpy(ns2->spawn.lastName, "Banker");
break;
case ADVENTUREMERCHANT:
strcpy(ns2->spawn.lastName, "Adventure Merchant");
break;
case WARRIORGM:
strcpy(ns2->spawn.lastName, "GM Warrior");
break;
case PALADINGM:
strcpy(ns2->spawn.lastName, "GM Paladin");
break;
case RANGERGM:
strcpy(ns2->spawn.lastName, "GM Ranger");
break;
case SHADOWKNIGHTGM:
strcpy(ns2->spawn.lastName, "GM Shadowknight");
break;
case DRUIDGM:
strcpy(ns2->spawn.lastName, "GM Druid");
break;
case BARDGM:
strcpy(ns2->spawn.lastName, "GM Bard");
break;
case ROGUEGM:
strcpy(ns2->spawn.lastName, "GM Rogue");
break;
case SHAMANGM:
strcpy(ns2->spawn.lastName, "GM Shaman");
break;
case NECROMANCERGM:
strcpy(ns2->spawn.lastName, "GM Necromancer");
break;
case WIZARDGM:
strcpy(ns2->spawn.lastName, "GM Wizard");
break;
case MAGICIANGM:
strcpy(ns2->spawn.lastName, "GM Magician");
break;
case ENCHANTERGM:
strcpy(ns2->spawn.lastName, "GM Enchanter");
break;
case BEASTLORDGM:
strcpy(ns2->spawn.lastName, "GM Beastlord");
break;
case BERSERKERGM:
strcpy(ns2->spawn.lastName, "GM Berserker");
break;
case MERCERNARY_MASTER:
strcpy(ns2->spawn.lastName, "Mercenary liaison");
break;
default:
strcpy(ns2->spawn.lastName, ns->spawn.lastName);
break;
}
}
else
{
strcpy(ns2->spawn.lastName, ns->spawn.lastName);
}
memset(&app->pBuffer[sizeof(Spawn_Struct)-7], 0xFF, 7);
}
@ -941,7 +950,7 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
}
ns->spawn.guildrank = 0xFF;
ns->spawn.size = size;
ns->spawn.size = size;
ns->spawn.bodytype = bodytype;
// The 'flymode' settings have the following effect:
// 0 - Mobs in water sink like a stone to the bottom
@ -1387,147 +1396,150 @@ void Mob::SendIllusionPacket(uint16 in_race, uint8 in_gender, uint8 in_texture,
uint16 BaseRace = GetBaseRace();
if (in_race == 0) {
this->race = BaseRace;
if (in_race == 0)
{
race = BaseRace;
if (in_gender == 0xFF)
this->gender = GetBaseGender();
else
this->gender = in_gender;
}
else {
this->race = in_race;
if (in_gender == 0xFF) {
uint8 tmp = Mob::GetDefaultGender(this->race, gender);
if (tmp == 2)
gender = 2;
else if (gender == 2 && GetBaseGender() == 2)
gender = tmp;
else if (gender == 2)
gender = GetBaseGender();
}
gender = GetBaseGender();
else
gender = in_gender;
}
if (in_texture == 0xFF) {
if (in_race <= 12 || in_race == 128 || in_race == 130 || in_race == 330 || in_race == 522)
this->texture = 0xFF;
else
this->texture = GetTexture();
}
else
this->texture = in_texture;
{
race = in_race;
if (in_gender == 0xFF)
gender = GetDefaultGender(race, gender);
else
gender = in_gender;
}
if (in_helmtexture == 0xFF) {
if (in_race <= 12 || in_race == 128 || in_race == 130 || in_race == 330 || in_race == 522)
this->helmtexture = 0xFF;
else if (in_texture != 0xFF)
this->helmtexture = in_texture;
if (in_texture == 0xFF)
{
if (IsPlayerRace(in_race))
texture = 0xFF;
else
this->helmtexture = GetHelmTexture();
texture = GetTexture();
}
else
this->helmtexture = in_helmtexture;
{
texture = in_texture;
}
if (in_helmtexture == 0xFF)
{
if (IsPlayerRace(in_race))
helmtexture = 0xFF;
else if (in_texture != 0xFF)
helmtexture = in_texture;
else
helmtexture = GetHelmTexture();
}
else
{
helmtexture = in_helmtexture;
}
if (in_haircolor == 0xFF)
this->haircolor = GetHairColor();
haircolor = GetHairColor();
else
this->haircolor = in_haircolor;
haircolor = in_haircolor;
if (in_beardcolor == 0xFF)
this->beardcolor = GetBeardColor();
beardcolor = GetBeardColor();
else
this->beardcolor = in_beardcolor;
beardcolor = in_beardcolor;
if (in_eyecolor1 == 0xFF)
this->eyecolor1 = GetEyeColor1();
eyecolor1 = GetEyeColor1();
else
this->eyecolor1 = in_eyecolor1;
eyecolor1 = in_eyecolor1;
if (in_eyecolor2 == 0xFF)
this->eyecolor2 = GetEyeColor2();
eyecolor2 = GetEyeColor2();
else
this->eyecolor2 = in_eyecolor2;
eyecolor2 = in_eyecolor2;
if (in_hairstyle == 0xFF)
this->hairstyle = GetHairStyle();
hairstyle = GetHairStyle();
else
this->hairstyle = in_hairstyle;
hairstyle = in_hairstyle;
if (in_luclinface == 0xFF)
this->luclinface = GetLuclinFace();
luclinface = GetLuclinFace();
else
this->luclinface = in_luclinface;
luclinface = in_luclinface;
if (in_beard == 0xFF)
this->beard = GetBeard();
beard = GetBeard();
else
this->beard = in_beard;
beard = in_beard;
this->aa_title = 0xFF;
aa_title = in_aa_title;
if (in_drakkin_heritage == 0xFFFFFFFF)
this->drakkin_heritage = GetDrakkinHeritage();
drakkin_heritage = GetDrakkinHeritage();
else
this->drakkin_heritage = in_drakkin_heritage;
drakkin_heritage = in_drakkin_heritage;
if (in_drakkin_tattoo == 0xFFFFFFFF)
this->drakkin_tattoo = GetDrakkinTattoo();
drakkin_tattoo = GetDrakkinTattoo();
else
this->drakkin_tattoo = in_drakkin_tattoo;
drakkin_tattoo = in_drakkin_tattoo;
if (in_drakkin_details == 0xFFFFFFFF)
this->drakkin_details = GetDrakkinDetails();
drakkin_details = GetDrakkinDetails();
else
this->drakkin_details = in_drakkin_details;
drakkin_details = in_drakkin_details;
if (in_size <= 0.0f)
this->size = GetSize();
size = GetSize();
else
this->size = in_size;
size = in_size;
// Forces the feature information to be pulled from the Player Profile
if (this->IsClient() && in_race == 0) {
this->race = CastToClient()->GetBaseRace();
this->gender = CastToClient()->GetBaseGender();
this->texture = 0xFF;
this->helmtexture = 0xFF;
this->haircolor = CastToClient()->GetBaseHairColor();
this->beardcolor = CastToClient()->GetBaseBeardColor();
this->eyecolor1 = CastToClient()->GetBaseEyeColor();
this->eyecolor2 = CastToClient()->GetBaseEyeColor();
this->hairstyle = CastToClient()->GetBaseHairStyle();
this->luclinface = CastToClient()->GetBaseFace();
this->beard = CastToClient()->GetBaseBeard();
this->aa_title = 0xFF;
this->drakkin_heritage = CastToClient()->GetBaseHeritage();
this->drakkin_tattoo = CastToClient()->GetBaseTattoo();
this->drakkin_details = CastToClient()->GetBaseDetails();
// Reset features to Base from the Player Profile
if (IsClient() && in_race == 0)
{
race = CastToClient()->GetBaseRace();
gender = CastToClient()->GetBaseGender();
texture = 0xFF;
helmtexture = 0xFF;
haircolor = CastToClient()->GetBaseHairColor();
beardcolor = CastToClient()->GetBaseBeardColor();
eyecolor1 = CastToClient()->GetBaseEyeColor();
eyecolor2 = CastToClient()->GetBaseEyeColor();
hairstyle = CastToClient()->GetBaseHairStyle();
luclinface = CastToClient()->GetBaseFace();
beard = CastToClient()->GetBaseBeard();
aa_title = 0xFF;
drakkin_heritage = CastToClient()->GetBaseHeritage();
drakkin_tattoo = CastToClient()->GetBaseTattoo();
drakkin_details = CastToClient()->GetBaseDetails();
switch(race){
case OGRE:
this->size = 9;
size = 9;
break;
case TROLL:
this->size = 8;
size = 8;
break;
case VAHSHIR:
case BARBARIAN:
this->size = 7;
size = 7;
break;
case HALF_ELF:
case WOOD_ELF:
case DARK_ELF:
case FROGLOK:
this->size = 5;
size = 5;
break;
case DWARF:
this->size = 4;
size = 4;
break;
case HALFLING:
case GNOME:
this->size = 3;
size = 3;
break;
default:
this->size = 6;
size = 6;
break;
}
}
@ -1535,39 +1547,250 @@ void Mob::SendIllusionPacket(uint16 in_race, uint8 in_gender, uint8 in_texture,
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Illusion, sizeof(Illusion_Struct));
memset(outapp->pBuffer, 0, sizeof(outapp->pBuffer));
Illusion_Struct* is = (Illusion_Struct*) outapp->pBuffer;
is->spawnid = this->GetID();
is->spawnid = GetID();
strcpy(is->charname, GetCleanName());
is->race = this->race;
is->gender = this->gender;
is->texture = this->texture;
is->helmtexture = this->helmtexture;
is->haircolor = this->haircolor;
is->beardcolor = this->beardcolor;
is->beard = this->beard;
is->eyecolor1 = this->eyecolor1;
is->eyecolor2 = this->eyecolor2;
is->hairstyle = this->hairstyle;
is->face = this->luclinface;
//is->aa_title = this->aa_title;
is->drakkin_heritage = this->drakkin_heritage;
is->drakkin_tattoo = this->drakkin_tattoo;
is->drakkin_details = this->drakkin_details;
is->size = this->size;
is->race = race;
is->gender = gender;
is->texture = texture;
is->helmtexture = helmtexture;
is->haircolor = haircolor;
is->beardcolor = beardcolor;
is->beard = beard;
is->eyecolor1 = eyecolor1;
is->eyecolor2 = eyecolor2;
is->hairstyle = hairstyle;
is->face = luclinface;
is->drakkin_heritage = drakkin_heritage;
is->drakkin_tattoo = drakkin_tattoo;
is->drakkin_details = drakkin_details;
is->size = size;
entity_list.QueueClients(this, outapp);
safe_delete(outapp);
mlog(CLIENT__SPELLS, "Illusion: Race = %i, Gender = %i, Texture = %i, HelmTexture = %i, HairColor = %i, BeardColor = %i, EyeColor1 = %i, EyeColor2 = %i, HairStyle = %i, Face = %i, DrakkinHeritage = %i, DrakkinTattoo = %i, DrakkinDetails = %i, Size = %f",
this->race, this->gender, this->texture, this->helmtexture, this->haircolor, this->beardcolor, this->eyecolor1, this->eyecolor2, this->hairstyle, this->luclinface, this->drakkin_heritage, this->drakkin_tattoo, this->drakkin_details, this->size);
race, gender, texture, helmtexture, haircolor, beardcolor, eyecolor1, eyecolor2, hairstyle, luclinface, drakkin_heritage, drakkin_tattoo, drakkin_details, size);
}
bool Mob::RandomizeFeatures(bool send_illusion, bool set_variables)
{
if (IsPlayerRace(GetRace()))
{
uint8 Gender = GetGender();
uint8 Texture = 0xFF;
uint8 HelmTexture = 0xFF;
uint8 HairColor = 0xFF;
uint8 BeardColor = 0xFF;
uint8 EyeColor1 = 0xFF;
uint8 EyeColor2 = 0xFF;
uint8 HairStyle = 0xFF;
uint8 LuclinFace = 0xFF;
uint8 Beard = 0xFF;
uint32 DrakkinHeritage = 0xFFFFFFFF;
uint32 DrakkinTattoo = 0xFFFFFFFF;
uint32 DrakkinDetails = 0xFFFFFFFF;
// Set some common feature settings
EyeColor1 = MakeRandomInt(0, 9);
EyeColor2 = MakeRandomInt(0, 9);
LuclinFace = MakeRandomInt(0, 7);
// Adjust all settings based on the min and max for each feature of each race and gender
switch (GetRace())
{
case 1: // Human
HairColor = MakeRandomInt(0, 19);
if (Gender == 0) {
BeardColor = HairColor;
HairStyle = MakeRandomInt(0, 3);
Beard = MakeRandomInt(0, 5);
}
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 2);
}
break;
case 2: // Barbarian
HairColor = MakeRandomInt(0, 19);
LuclinFace = MakeRandomInt(0, 87);
if (Gender == 0) {
BeardColor = HairColor;
HairStyle = MakeRandomInt(0, 3);
Beard = MakeRandomInt(0, 5);
}
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 2);
}
break;
case 3: // Erudite
if (Gender == 0) {
BeardColor = MakeRandomInt(0, 19);
Beard = MakeRandomInt(0, 5);
LuclinFace = MakeRandomInt(0, 57);
}
if (Gender == 1) {
LuclinFace = MakeRandomInt(0, 87);
}
break;
case 4: // WoodElf
HairColor = MakeRandomInt(0, 19);
if (Gender == 0) {
HairStyle = MakeRandomInt(0, 3);
}
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 2);
}
break;
case 5: // HighElf
HairColor = MakeRandomInt(0, 14);
if (Gender == 0) {
HairStyle = MakeRandomInt(0, 3);
LuclinFace = MakeRandomInt(0, 37);
BeardColor = HairColor;
}
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 2);
}
break;
case 6: // DarkElf
HairColor = MakeRandomInt(13, 18);
if (Gender == 0) {
HairStyle = MakeRandomInt(0, 3);
LuclinFace = MakeRandomInt(0, 37);
BeardColor = HairColor;
}
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 2);
}
break;
case 7: // HalfElf
HairColor = MakeRandomInt(0, 19);
if (Gender == 0) {
HairStyle = MakeRandomInt(0, 3);
LuclinFace = MakeRandomInt(0, 37);
BeardColor = HairColor;
}
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 2);
}
break;
case 8: // Dwarf
HairColor = MakeRandomInt(0, 19);
BeardColor = HairColor;
if (Gender == 0) {
HairStyle = MakeRandomInt(0, 3);
Beard = MakeRandomInt(0, 5);
}
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 2);
LuclinFace = MakeRandomInt(0, 17);
}
break;
case 9: // Troll
EyeColor1 = MakeRandomInt(0, 10);
EyeColor2 = MakeRandomInt(0, 10);
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 3);
HairColor = MakeRandomInt(0, 23);
}
break;
case 10: // Ogre
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 3);
HairColor = MakeRandomInt(0, 23);
}
break;
case 11: // Halfling
HairColor = MakeRandomInt(0, 19);
if (Gender == 0) {
BeardColor = HairColor;
HairStyle = MakeRandomInt(0, 3);
Beard = MakeRandomInt(0, 5);
}
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 2);
}
break;
case 12: // Gnome
HairColor = MakeRandomInt(0, 24);
if (Gender == 0) {
BeardColor = HairColor;
HairStyle = MakeRandomInt(0, 3);
Beard = MakeRandomInt(0, 5);
}
if (Gender == 1) {
HairStyle = MakeRandomInt(0, 2);
}
break;
case 128: // Iksar
case 130: // VahShir
break;
case 330: // Froglok
LuclinFace = MakeRandomInt(0, 9);
case 522: // Drakkin
HairColor = MakeRandomInt(0, 3);
BeardColor = HairColor;
EyeColor1 = MakeRandomInt(0, 11);
EyeColor2 = MakeRandomInt(0, 11);
LuclinFace = MakeRandomInt(0, 6);
DrakkinHeritage = MakeRandomInt(0, 6);
DrakkinTattoo = MakeRandomInt(0, 7);
DrakkinDetails = MakeRandomInt(0, 7);
if (Gender == 0) {
Beard = MakeRandomInt(0, 12);
HairStyle = MakeRandomInt(0, 8);
}
if (Gender == 1) {
Beard = MakeRandomInt(0, 3);
HairStyle = MakeRandomInt(0, 7);
}
break;
default:
break;
}
if (set_variables)
{
haircolor = HairColor;
beardcolor = BeardColor;
eyecolor1 = EyeColor1;
eyecolor2 = EyeColor2;
hairstyle = HairStyle;
luclinface = LuclinFace;
beard = Beard;
drakkin_heritage = DrakkinHeritage;
drakkin_tattoo = DrakkinTattoo;
drakkin_details = DrakkinDetails;
}
if (send_illusion)
{
SendIllusionPacket(GetRace(), Gender, Texture, HelmTexture, HairColor, BeardColor,
EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF, DrakkinHeritage,
DrakkinTattoo, DrakkinDetails);
}
return true;
}
return false;
}
bool Mob::IsPlayerRace(uint16 in_race) {
if ((in_race >= HUMAN && in_race <= GNOME) || in_race == IKSAR || in_race == VAHSHIR || in_race == FROGLOK || in_race == DRAKKIN)
{
return true;
}
return false;
}
uint8 Mob::GetDefaultGender(uint16 in_race, uint8 in_gender) {
//std::cout << "Gender in: " << (int)in_gender << std::endl; // undefined cout [CODEBUG]
if ((in_race > 0 && in_race <= GNOME )
|| in_race == IKSAR || in_race == VAHSHIR || in_race == FROGLOK || in_race == DRAKKIN
|| in_race == 15 || in_race == 50 || in_race == 57 || in_race == 70 || in_race == 98 || in_race == 118) {
if (Mob::IsPlayerRace(in_race) || in_race == 15 || in_race == 50 || in_race == 57 || in_race == 70 || in_race == 98 || in_race == 118) {
if (in_gender >= 2) {
// Female default for PC Races
return 1;
// Male default for PC Races
return 0;
}
else
return in_gender;

View File

@ -497,6 +497,7 @@ public:
//Util
static uint32 RandomTimer(int min, int max);
static uint8 GetDefaultGender(uint16 in_race, uint8 in_gender = 0xFF);
static bool IsPlayerRace(uint16 in_race);
uint16 GetSkillByItemType(int ItemType);
uint8 GetItemTypeBySkill(SkillUseTypes skill);
virtual void MakePet(uint16 spell_id, const char* pettype, const char *petname = nullptr);
@ -577,6 +578,7 @@ public:
uint8 in_hairstyle = 0xFF, uint8 in_luclinface = 0xFF, uint8 in_beard = 0xFF, uint8 in_aa_title = 0xFF,
uint32 in_drakkin_heritage = 0xFFFFFFFF, uint32 in_drakkin_tattoo = 0xFFFFFFFF,
uint32 in_drakkin_details = 0xFFFFFFFF, float in_size = -1.0f);
bool RandomizeFeatures(bool send_illusion = true, bool set_variables = true);
virtual void Stun(int duration);
virtual void UnStun();
inline void Silence(bool newval) { silenced = newval; }

View File

@ -2100,7 +2100,7 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client
bool ZoneDatabase::LoadMercInfo(Client *client) {
std::string query = StringFormat("SELECT MercID, Slot, Name, TemplateID, SuspendedTime, "
"IsSuspended, TimerRemaining, Gender, StanceID, HP, Mana, "
"IsSuspended, TimerRemaining, Gender, MercSize, StanceID, HP, Mana, "
"Endurance, Face, LuclinHairStyle, LuclinHairColor, "
"LuclinEyeColor, LuclinEyeColor2, LuclinBeardColor, LuclinBeard, "
"DrakkinHeritage, DrakkinTattoo, DrakkinDetails "
@ -2126,21 +2126,22 @@ bool ZoneDatabase::LoadMercInfo(Client *client) {
client->GetMercInfo(slot).IsSuspended = atoi(row[5]) == 1 ? true : false;
client->GetMercInfo(slot).MercTimerRemaining = atoi(row[6]);
client->GetMercInfo(slot).Gender = atoi(row[7]);
client->GetMercInfo(slot).MercSize = atof(row[8]);
client->GetMercInfo(slot).State = 5;
client->GetMercInfo(slot).Stance = atoi(row[8]);
client->GetMercInfo(slot).hp = atoi(row[9]);
client->GetMercInfo(slot).mana = atoi(row[10]);
client->GetMercInfo(slot).endurance = atoi(row[11]);
client->GetMercInfo(slot).face = atoi(row[12]);
client->GetMercInfo(slot).luclinHairStyle = atoi(row[13]);
client->GetMercInfo(slot).luclinHairColor = atoi(row[14]);
client->GetMercInfo(slot).luclinEyeColor = atoi(row[15]);
client->GetMercInfo(slot).luclinEyeColor2 = atoi(row[16]);
client->GetMercInfo(slot).luclinBeardColor = atoi(row[17]);
client->GetMercInfo(slot).luclinBeard = atoi(row[18]);
client->GetMercInfo(slot).drakkinHeritage = atoi(row[19]);
client->GetMercInfo(slot).drakkinTattoo = atoi(row[20]);
client->GetMercInfo(slot).drakkinDetails = atoi(row[21]);
client->GetMercInfo(slot).Stance = atoi(row[9]);
client->GetMercInfo(slot).hp = atoi(row[10]);
client->GetMercInfo(slot).mana = atoi(row[11]);
client->GetMercInfo(slot).endurance = atoi(row[12]);
client->GetMercInfo(slot).face = atoi(row[13]);
client->GetMercInfo(slot).luclinHairStyle = atoi(row[14]);
client->GetMercInfo(slot).luclinHairColor = atoi(row[15]);
client->GetMercInfo(slot).luclinEyeColor = atoi(row[16]);
client->GetMercInfo(slot).luclinEyeColor2 = atoi(row[17]);
client->GetMercInfo(slot).luclinBeardColor = atoi(row[18]);
client->GetMercInfo(slot).luclinBeard = atoi(row[19]);
client->GetMercInfo(slot).drakkinHeritage = atoi(row[20]);
client->GetMercInfo(slot).drakkinTattoo = atoi(row[21]);
client->GetMercInfo(slot).drakkinDetails = atoi(row[22]);
}
return true;
@ -2154,7 +2155,7 @@ bool ZoneDatabase::LoadCurrentMerc(Client *client) {
return false;
std::string query = StringFormat("SELECT MercID, Name, TemplateID, SuspendedTime, "
"IsSuspended, TimerRemaining, Gender, StanceID, HP, "
"IsSuspended, TimerRemaining, Gender, MercSize, StanceID, HP, "
"Mana, Endurance, Face, LuclinHairStyle, LuclinHairColor, "
"LuclinEyeColor, LuclinEyeColor2, LuclinBeardColor, "
"LuclinBeard, DrakkinHeritage, DrakkinTattoo, DrakkinDetails "
@ -2178,20 +2179,21 @@ bool ZoneDatabase::LoadCurrentMerc(Client *client) {
client->GetMercInfo(slot).IsSuspended = atoi(row[4]) == 1? true: false;
client->GetMercInfo(slot).MercTimerRemaining = atoi(row[5]);
client->GetMercInfo(slot).Gender = atoi(row[6]);
client->GetMercInfo(slot).State = atoi(row[7]);
client->GetMercInfo(slot).hp = atoi(row[8]);
client->GetMercInfo(slot).mana = atoi(row[9]);
client->GetMercInfo(slot).endurance = atoi(row[10]);
client->GetMercInfo(slot).face = atoi(row[11]);
client->GetMercInfo(slot).luclinHairStyle = atoi(row[12]);
client->GetMercInfo(slot).luclinHairColor = atoi(row[13]);
client->GetMercInfo(slot).luclinEyeColor = atoi(row[14]);
client->GetMercInfo(slot).luclinEyeColor2 = atoi(row[15]);
client->GetMercInfo(slot).luclinBeardColor = atoi(row[16]);
client->GetMercInfo(slot).luclinBeard = atoi(row[17]);
client->GetMercInfo(slot).drakkinHeritage = atoi(row[18]);
client->GetMercInfo(slot).drakkinTattoo = atoi(row[19]);
client->GetMercInfo(slot).drakkinDetails = atoi(row[20]);
client->GetMercInfo(slot).MercSize = atof(row[7]);
client->GetMercInfo(slot).State = atoi(row[8]);
client->GetMercInfo(slot).hp = atoi(row[9]);
client->GetMercInfo(slot).mana = atoi(row[10]);
client->GetMercInfo(slot).endurance = atoi(row[11]);
client->GetMercInfo(slot).face = atoi(row[12]);
client->GetMercInfo(slot).luclinHairStyle = atoi(row[13]);
client->GetMercInfo(slot).luclinHairColor = atoi(row[14]);
client->GetMercInfo(slot).luclinEyeColor = atoi(row[15]);
client->GetMercInfo(slot).luclinEyeColor2 = atoi(row[16]);
client->GetMercInfo(slot).luclinBeardColor = atoi(row[17]);
client->GetMercInfo(slot).luclinBeard = atoi(row[18]);
client->GetMercInfo(slot).drakkinHeritage = atoi(row[19]);
client->GetMercInfo(slot).drakkinTattoo = atoi(row[20]);
client->GetMercInfo(slot).drakkinDetails = atoi(row[21]);
}
return true;
@ -2209,19 +2211,19 @@ bool ZoneDatabase::SaveMerc(Merc *merc) {
std::string query = StringFormat("INSERT INTO mercs "
"(OwnerCharacterID, Slot, Name, TemplateID, "
"SuspendedTime, IsSuspended, TimerRemaining, "
"Gender, StanceID, HP, Mana, Endurance, Face, "
"Gender, MercSize, StanceID, HP, Mana, Endurance, Face, "
"LuclinHairStyle, LuclinHairColor, LuclinEyeColor, "
"LuclinEyeColor2, LuclinBeardColor, LuclinBeard, "
"DrakkinHeritage, DrakkinTattoo, DrakkinDetails) "
"VALUES('%u', '%u', '%s', '%u', '%u', '%u', '%u', "
"'%u', '%u', '%u', '%u', '%u', '%i', '%i', '%i', "
"'%u', '%u', '%f', '%u', '%u', '%u', '%i', '%i', '%i', "
"'%i', '%i', '%i', '%i', '%i', '%i', '%i')",
merc->GetMercCharacterID(), owner->GetNumMercs(),
merc->GetCleanName(), merc->GetMercTemplateID(),
owner->GetMercInfo().SuspendedTime, merc->IsSuspended(),
owner->GetMercInfo().MercTimerRemaining, merc->GetGender(),
merc->GetStance(), merc->GetHP(), merc->GetMana(),
merc->GetEndurance(), merc->GetLuclinFace(),
merc->GetSize(), merc->GetStance(), merc->GetHP(),
merc->GetMana(), merc->GetEndurance(), merc->GetLuclinFace(),
merc->GetHairStyle(), merc->GetHairColor(), merc->GetEyeColor1(),
merc->GetEyeColor2(), merc->GetBeardColor(),
merc->GetBeard(), merc->GetDrakkinHeritage(),
@ -2245,7 +2247,7 @@ bool ZoneDatabase::SaveMerc(Merc *merc) {
// Update existing merc record
std::string query = StringFormat("UPDATE mercs SET OwnerCharacterID = '%u', Slot = '%u', "
"Name = '%s', TemplateID = '%u', SuspendedTime = '%u', "
"IsSuspended = '%u', TimerRemaining = '%u', Gender = '%u', "
"IsSuspended = '%u', TimerRemaining = '%u', Gender = '%u', MercSize = '%f', "
"StanceID = '%u', HP = '%u', Mana = '%u', Endurance = '%u', "
"Face = '%i', LuclinHairStyle = '%i', LuclinHairColor = '%i', "
"LuclinEyeColor = '%i', LuclinEyeColor2 = '%i', LuclinBeardColor = '%i', "
@ -2254,11 +2256,12 @@ bool ZoneDatabase::SaveMerc(Merc *merc) {
merc->GetMercCharacterID(), owner->GetMercSlot(), merc->GetCleanName(),
merc->GetMercTemplateID(), owner->GetMercInfo().SuspendedTime,
merc->IsSuspended(), owner->GetMercInfo().MercTimerRemaining,
merc->GetGender(), merc->GetStance(), merc->GetHP(), merc->GetMana(),
merc->GetEndurance(), merc->GetLuclinFace(), merc->GetHairStyle(),
merc->GetHairColor(), merc->GetEyeColor1(), merc->GetEyeColor2(),
merc->GetBeardColor(), merc->GetBeard(), merc->GetDrakkinHeritage(),
merc->GetDrakkinTattoo(), merc->GetDrakkinDetails(), merc->GetMercID());
merc->GetGender(), merc->GetSize(), merc->GetStance(), merc->GetHP(),
merc->GetMana(), merc->GetEndurance(), merc->GetLuclinFace(),
merc->GetHairStyle(), merc->GetHairColor(), merc->GetEyeColor1(),
merc->GetEyeColor2(), merc->GetBeardColor(), merc->GetBeard(),
merc->GetDrakkinHeritage(), merc->GetDrakkinTattoo(), merc->GetDrakkinDetails(),
merc->GetMercID());
auto results = database.QueryDatabase(query);
if (!results.Success()) {

View File

@ -181,6 +181,7 @@ struct MercInfo {
bool IsSuspended;
uint32 MercTimerRemaining;
uint8 Gender;
float MercSize;
int32 State;
uint32 Stance;
int32 hp;