diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index fdb4c4d58..ac13b5953 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -392,6 +392,7 @@ 9136|2019_02_04_profanity_command.sql|SHOW TABLES LIKE 'profanity_list'|empty| 9137|2018_12_12_client_faction_tables.sql|SHOW TABLES LIKE 'faction_base_data'|empty| 9138|2018_12_12_convert_to_client_functions.sql|SELECT `id` FROM `faction_list` WHERE `id` > 4999|empty| +9139|2019_03_25_optional_npc_model.sql|SHOW COLUMNS FROM `npc_types` LIKE 'model'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not diff --git a/utils/sql/git/required/2019_03_25_optional_npc_model.sql b/utils/sql/git/required/2019_03_25_optional_npc_model.sql new file mode 100644 index 000000000..0f82bd62e --- /dev/null +++ b/utils/sql/git/required/2019_03_25_optional_npc_model.sql @@ -0,0 +1 @@ +ALTER TABLE `npc_types` ADD COLUMN `model` SMALLINT(5) NOT NULL DEFAULT '0' AFTER `stuck_behavior`; diff --git a/zone/beacon.cpp b/zone/beacon.cpp index 36075dca5..81b964290 100644 --- a/zone/beacon.cpp +++ b/zone/beacon.cpp @@ -56,7 +56,7 @@ Beacon::Beacon(Mob *at_mob, int lifetime) :Mob ( nullptr, nullptr, 0, 0, 0, INVISIBLE_MAN, 0, BT_NoTarget, 0, 0, 0, 0, 0, at_mob->GetPosition(), 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, EQEmu::TintProfile(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, EQEmu::TintProfile(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ), remove_timer(lifetime), spell_timer(0) diff --git a/zone/client.cpp b/zone/client.cpp index 7eea9e845..f56aa1d31 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -119,6 +119,7 @@ Client::Client(EQStreamInterface* ieqs) 0, 0, 0, + 0, 0 ), hpupdate_timer(2000), diff --git a/zone/corpse.cpp b/zone/corpse.cpp index fbb319cb5..1465064f3 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -152,7 +152,8 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP in_npc->GetDeity(),in_npc->GetLevel(),in_npc->GetNPCTypeID(),in_npc->GetSize(),0, in_npc->GetPosition(), in_npc->GetInnateLightType(), in_npc->GetTexture(),in_npc->GetHelmTexture(), 0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,EQEmu::TintProfile(),0xff,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + 0,0,0,0,0,0,0,0,0,0,EQEmu::TintProfile(),0xff,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + (*in_npctypedata)->use_model), corpse_decay_timer(in_decaytime), corpse_rez_timer(0), corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)), @@ -258,6 +259,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( 0, // uint8 in_bracertexture, 0, // uint8 in_handtexture, 0, // uint8 in_legtexture, + 0, 0 // uint8 in_feettexture, ), corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)), @@ -484,6 +486,7 @@ EQEmu::TintProfile(), 0, 0, 0, +0, 0), corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)), corpse_rez_timer(RuleI(Character, CorpseResTimeMS)), diff --git a/zone/encounter.cpp b/zone/encounter.cpp index 1eff0ca59..e0ec83d90 100644 --- a/zone/encounter.cpp +++ b/zone/encounter.cpp @@ -36,7 +36,7 @@ Encounter::Encounter(const char* enc_name) :Mob ( nullptr, nullptr, 0, 0, 0, INVISIBLE_MAN, 0, BT_NoTarget, 0, 0, 0, 0, 0, glm::vec4(0,0,0,0), 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, EQEmu::TintProfile(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, EQEmu::TintProfile(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) { encounter_name[0] = 0; diff --git a/zone/mob.cpp b/zone/mob.cpp index aec319ba7..b068905a9 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -92,7 +92,8 @@ Mob::Mob( uint8 in_bracertexture, uint8 in_handtexture, uint8 in_legtexture, - uint8 in_feettexture + uint8 in_feettexture, + uint16 in_usemodel ) : attack_timer(2000), attack_dw_timer(2000), @@ -147,6 +148,7 @@ Mob::Mob( race = in_race; base_gender = in_gender; base_race = in_race; + use_model = in_usemodel; class_ = in_class; bodytype = in_bodytype; orig_bodytype = in_bodytype; @@ -1112,7 +1114,7 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) ns->spawn.spawnId = GetID(); ns->spawn.curHp = static_cast(GetHPRatio()); ns->spawn.max_hp = 100; //this field needs a better name - ns->spawn.race = race; + ns->spawn.race = (use_model) ? use_model : race; ns->spawn.runspeed = runspeed; ns->spawn.walkspeed = walkspeed; ns->spawn.class_ = class_; @@ -1692,151 +1694,74 @@ void Mob::SendIllusionPacket( float in_size ) { + uint8 new_texture = in_texture; + uint8 new_helmtexture = in_helmtexture; + uint8 new_haircolor; + uint8 new_beardcolor; + uint8 new_eyecolor1; + uint8 new_eyecolor2; + uint8 new_hairstyle; + uint8 new_luclinface; + uint8 new_beard; + uint8 new_aa_title; + uint32 new_drakkin_heritage; + uint32 new_drakkin_tattoo; + uint32 new_drakkin_details; - uint16 BaseRace = GetBaseRace(); + race = (in_race) ? in_race : GetBaseRace(); - if (in_race == 0) { - race = BaseRace; - if (in_gender == 0xFF) { - gender = GetBaseGender(); + if (in_gender != 0xFF) + { + gender = in_gender; } - else { - gender = in_gender; + else + { + gender = (in_race) ? GetDefaultGender(race, gender) : GetBaseGender(); } - } - else { - race = in_race; - if (in_gender == 0xFF) { - gender = GetDefaultGender(race, gender); + + if (in_texture == 0xFF && !IsPlayerRace(in_race)) + { + new_texture = GetTexture(); } - else { - gender = in_gender; + + if (in_helmtexture == 0xFF && !IsPlayerRace(in_race)) + { + new_helmtexture = GetHelmTexture(); } - } - if (in_texture == 0xFF) { - if (IsPlayerRace(in_race)) { - texture = 0xFF; - } - else { - texture = GetTexture(); - } - } - else { - 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) { - haircolor = GetHairColor(); - } - else { - haircolor = in_haircolor; - } - - if (in_beardcolor == 0xFF) { - beardcolor = GetBeardColor(); - } - else { - beardcolor = in_beardcolor; - } - - if (in_eyecolor1 == 0xFF) { - eyecolor1 = GetEyeColor1(); - } - else { - eyecolor1 = in_eyecolor1; - } - - if (in_eyecolor2 == 0xFF) { - eyecolor2 = GetEyeColor2(); - } - else { - eyecolor2 = in_eyecolor2; - } - - if (in_hairstyle == 0xFF) { - hairstyle = GetHairStyle(); - } - else { - hairstyle = in_hairstyle; - } - - if (in_luclinface == 0xFF) { - luclinface = GetLuclinFace(); - } - else { - luclinface = in_luclinface; - } - - if (in_beard == 0xFF) { - beard = GetBeard(); - } - else { - beard = in_beard; - } - - aa_title = in_aa_title; - - if (in_drakkin_heritage == 0xFFFFFFFF) { - drakkin_heritage = GetDrakkinHeritage(); - } - else { - drakkin_heritage = in_drakkin_heritage; - } - - if (in_drakkin_tattoo == 0xFFFFFFFF) { - drakkin_tattoo = GetDrakkinTattoo(); - } - else { - drakkin_tattoo = in_drakkin_tattoo; - } - - if (in_drakkin_details == 0xFFFFFFFF) { - drakkin_details = GetDrakkinDetails(); - } - else { - drakkin_details = in_drakkin_details; - } - - if (in_size <= 0.0f) { - size = GetSize(); - } - else { - size = in_size; - } + new_haircolor = (in_haircolor == 0xFF) ? GetHairColor() : in_haircolor; + new_beardcolor = (in_beardcolor == 0xFF) ? GetBeardColor() : in_beardcolor; + new_eyecolor1 = (in_eyecolor1 == 0xFF) ? GetEyeColor1() : in_eyecolor1; + new_eyecolor2 = (in_eyecolor2 == 0xFF) ? GetEyeColor2() : in_eyecolor2; + new_hairstyle = (in_hairstyle == 0xFF) ? GetHairStyle() : in_hairstyle; + new_luclinface = (in_luclinface == 0xFF) ? GetLuclinFace() : in_luclinface; + new_beard = (in_beard == 0xFF) ? GetBeard() : in_beard; + new_drakkin_heritage = + (in_drakkin_heritage == 0xFFFFFFFF) ? GetDrakkinHeritage() : in_drakkin_heritage; + new_drakkin_tattoo = + (in_drakkin_tattoo == 0xFFFFFFFF) ? GetDrakkinTattoo() : in_drakkin_tattoo; + new_drakkin_details = + (in_drakkin_details == 0xFFFFFFFF) ? GetDrakkinDetails() : in_drakkin_details; + new_aa_title = in_aa_title; + size = (in_size <= 0.0f) ? GetSize() : in_size; // 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(); + race = CastToClient()->GetBaseRace(); + gender = CastToClient()->GetBaseGender(); + new_texture = texture = 0xFF; + new_helmtexture = helmtexture = 0xFF; + new_haircolor = haircolor = CastToClient()->GetBaseHairColor(); + new_beardcolor = beardcolor = CastToClient()->GetBaseBeardColor(); + new_eyecolor1 = eyecolor1 = CastToClient()->GetBaseEyeColor(); + new_eyecolor2 = eyecolor2 = CastToClient()->GetBaseEyeColor(); + new_hairstyle = hairstyle = CastToClient()->GetBaseHairStyle(); + new_luclinface = luclinface = CastToClient()->GetBaseFace(); + new_beard = beard = CastToClient()->GetBaseBeard(); + new_aa_title = aa_title = 0xFF; + new_drakkin_heritage = drakkin_heritage = CastToClient()->GetBaseHeritage(); + new_drakkin_tattoo = drakkin_tattoo = CastToClient()->GetBaseTattoo(); + new_drakkin_details = drakkin_details = CastToClient()->GetBaseDetails(); switch (race) { case OGRE: size = 9; @@ -1873,18 +1798,18 @@ void Mob::SendIllusionPacket( strcpy(is->charname, GetCleanName()); 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->texture = new_texture; + is->helmtexture = new_helmtexture; + is->haircolor = new_haircolor; + is->beardcolor = new_beardcolor; + is->beard = new_beard; + is->eyecolor1 = new_eyecolor1; + is->eyecolor2 = new_eyecolor2; + is->hairstyle = new_hairstyle; + is->face = new_luclinface; + is->drakkin_heritage = new_drakkin_heritage; + is->drakkin_tattoo = new_drakkin_tattoo; + is->drakkin_details = new_drakkin_details; is->size = size; entity_list.QueueClients(this, outapp); @@ -1898,17 +1823,17 @@ void Mob::SendIllusionPacket( "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", race, gender, - texture, - helmtexture, - haircolor, - beardcolor, - eyecolor1, - eyecolor2, - hairstyle, - luclinface, - drakkin_heritage, - drakkin_tattoo, - drakkin_details, + new_texture, + new_helmtexture, + new_haircolor, + new_beardcolor, + new_eyecolor1, + new_eyecolor2, + new_hairstyle, + new_luclinface, + new_drakkin_heritage, + new_drakkin_tattoo, + new_drakkin_details, size); } diff --git a/zone/mob.h b/zone/mob.h index 18cdfeceb..a92f5cacb 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -159,7 +159,8 @@ public: uint8 in_bracertexture, uint8 in_handtexture, uint8 in_legtexture, - uint8 in_feettexture + uint8 in_feettexture, + uint16 in_usemodel ); virtual ~Mob(); @@ -1280,6 +1281,7 @@ protected: uint8 gender; uint16 race; + uint16 use_model; uint8 base_gender; uint16 base_race; uint8 class_; diff --git a/zone/npc.cpp b/zone/npc.cpp index 16a508d1f..ac8825774 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -112,7 +112,8 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi npc_type_data->bracertexture, npc_type_data->handtexture, npc_type_data->legtexture, - npc_type_data->feettexture + npc_type_data->feettexture, + npc_type_data->use_model ), attacked_timer(CombatEventTimer_expire), swarm_timer(100), diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 82bc5ae29..093e1e30c 100755 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -2483,7 +2483,8 @@ const NPCType* ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load "npc_types.charm_atk, " "npc_types.skip_global_loot, " "npc_types.rare_spawn, " - "npc_types.stuck_behavior " + "npc_types.stuck_behavior, " + "npc_types.model " "FROM npc_types %s", where_condition.c_str() ); @@ -2673,6 +2674,7 @@ const NPCType* ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load temp_npctype_data->skip_global_loot = atoi(row[107]) != 0; temp_npctype_data->rare_spawn = atoi(row[108]) != 0; temp_npctype_data->stuck_behavior = atoi(row[109]); + temp_npctype_data->use_model = atoi(row[110]); // If NPC with duplicate NPC id already in table, // free item we attempted to add. diff --git a/zone/zonedump.h b/zone/zonedump.h index b75057a16..be978a1be 100644 --- a/zone/zonedump.h +++ b/zone/zonedump.h @@ -144,6 +144,7 @@ struct NPCType bool skip_global_loot; bool rare_spawn; int8 stuck_behavior; + uint16 use_model; }; namespace player_lootitem {