From baf2f23ce6f924d4a5f41f5bc49d27421769efd4 Mon Sep 17 00:00:00 2001 From: Trevius Date: Wed, 24 Dec 2014 12:02:30 -0600 Subject: [PATCH] (RoF+) Implemented Hero's Forge Armor for NPCs. Set the herosforgemodel field in npc_types table to the model (example: 84 for full set, or 12107 for robe). (RoF+) Hero's Forge Armor now overrides NPC texture settings. To display Hero's Forge Armor Helms, set helmtexture field to anything other than 0. Fixed some NPC loading from the database that was incorrect after adding herosforgemodel. --- changelog.txt | 4 +++- common/patches/rof2.cpp | 2 +- zone/mob.cpp | 10 +++++----- zone/zonedb.cpp | 36 ++++++++++++++++++++++-------------- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/changelog.txt b/changelog.txt index 60a1e4b9d..0c9bed583 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,8 +1,10 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- == 12/24/2014 == -Trevius: (RoF+) Added herosforgemodel field to the npc_types table. Not fully functional yet for NPCs (currently only displays helm correctly). +Trevius: (RoF+) Added herosforgemodel field to the npc_types table. Trevius: (RoF2) Updated item links from #npcstat command output. +Trevius: (RoF+) Implemented Hero's Forge Armor for NPCs. Set the herosforgemodel field in npc_types table to the model (example: 84 for full set, or 12107 for robe). +Trevius: (RoF+) Hero's Forge Armor now overrides NPC texture settings. To display Hero's Forge Armor Helms, set helmtexture field to anything other than 0. == 12/23/2014 == Uleat: Tidied up some ItemInst* declarations and added some nullptr checks. diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index 8a998b94a..c57266f0a 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -3742,7 +3742,7 @@ namespace RoF2 VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->drakkin_tattoo); VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->drakkin_details); - VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->equip_chest2); // unknown8 + VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->equip_chest2); VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown9 VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown10 VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->helm); // unknown11 diff --git a/zone/mob.cpp b/zone/mob.cpp index 455a1c4ef..8baf361bd 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -925,7 +925,7 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) ns->spawn.animation = 0; ns->spawn.findable = findable?1:0; ns->spawn.light = light; - ns->spawn.showhelm = 1; + ns->spawn.showhelm = (helmtexture && helmtexture != 0xFF) ? 1 : 0; ns->spawn.invis = (invisible || hidden) ? 1 : 0; // TODO: load this before spawning players ns->spawn.NPC = IsClient() ? 0 : 1; @@ -945,11 +945,11 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) ns->spawn.drakkin_heritage = drakkin_heritage; ns->spawn.drakkin_tattoo = drakkin_tattoo; ns->spawn.drakkin_details = drakkin_details; - ns->spawn.equip_chest2 = texture; + ns->spawn.equip_chest2 = GetHerosForgeModel(1) != 0 ? 0xff : texture; // ns->spawn.invis2 = 0xff;//this used to be labeled beard.. if its not FF it will turn mob invis - if(helmtexture && helmtexture != 0xFF) + if (helmtexture && helmtexture != 0xFF && GetHerosForgeModel(0) == 0) { ns->spawn.helm=helmtexture; } else { @@ -2770,8 +2770,8 @@ int32 Mob::GetHerosForgeModel(uint8 material_slot) const if (IsNPC()) { HeroModel = CastToNPC()->GetHeroForgeModel(); - // Robes require full model number, and should only be sent to chest slot - if (HeroModel > 1000 && material_slot != 1) + // Robes require full model number, and should only be sent to chest, arms, wrists, and legs slots + if (HeroModel > 1000 && material_slot != 1 && material_slot != 2 && material_slot != 3 && material_slot != 5) { HeroModel = 0; } diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 8d5bc1dd0..d067411e6 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -1790,7 +1790,7 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) { tmpNPCType->gender = atoi(row[7]); tmpNPCType->texture = atoi(row[8]); tmpNPCType->helmtexture = atoi(row[9]); - tmpNPCType->herosforgemodel = atoi(row[10]); + tmpNPCType->herosforgemodel = atoul(row[10]); tmpNPCType->size = atof(row[11]); tmpNPCType->loottable_id = atoi(row[12]); tmpNPCType->merchanttype = atoi(row[13]); @@ -1816,7 +1816,7 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) { tmpNPCType->max_dmg = atoi(row[33]); tmpNPCType->attack_count = atoi(row[34]); - if (row[34] != nullptr) + if (row[35] != nullptr) strn0cpy(tmpNPCType->special_abilities, row[35], 512); else tmpNPCType->special_abilities[0] = '\0'; @@ -1835,7 +1835,7 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) { tmpNPCType->hp_regen = atoi(row[47]); tmpNPCType->mana_regen = atoi(row[48]); - // set defaultvalue for aggroradius + // set default value for aggroradius tmpNPCType->aggroradius = (int32)atoi(row[49]); if (tmpNPCType->aggroradius <= 0) tmpNPCType->aggroradius = 70; @@ -1844,7 +1844,7 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) { if (tmpNPCType->assistradius <= 0) tmpNPCType->assistradius = tmpNPCType->aggroradius; - if (row[50] && strlen(row[50])) + if (row[51] && strlen(row[51])) tmpNPCType->bodytype = (uint8)atoi(row[51]); else tmpNPCType->bodytype = 0; @@ -1869,10 +1869,7 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) { tmpNPCType->armor_tint[0] |= (atoi(row[66]) & 0xFF); tmpNPCType->armor_tint[0] |= (tmpNPCType->armor_tint[0]) ? (0xFF << 24) : 0; - if (armor_tint_id == 0) - for (int index = MaterialChest; index <= EmuConstants::MATERIAL_END; index++) - tmpNPCType->armor_tint[index] = tmpNPCType->armor_tint[0]; - else if (tmpNPCType->armor_tint[0] == 0) + if (armor_tint_id != 0) { std::string armortint_query = StringFormat("SELECT red1h, grn1h, blu1h, " "red2c, grn2c, blu2c, " @@ -1887,23 +1884,34 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) { armor_tint_id); auto armortint_results = QueryDatabase(armortint_query); if (!armortint_results.Success() || armortint_results.RowCount() == 0) - armor_tint_id = 0; - else { + { + armor_tint_id = 0; + } + else + { auto armorTint_row = armortint_results.begin(); - for (int index = EmuConstants::MATERIAL_BEGIN; index <= EmuConstants::MATERIAL_END; index++) { + for (int index = EmuConstants::MATERIAL_BEGIN; index <= EmuConstants::MATERIAL_END; index++) + { tmpNPCType->armor_tint[index] = atoi(armorTint_row[index * 3]) << 16; tmpNPCType->armor_tint[index] |= atoi(armorTint_row[index * 3 + 1]) << 8; tmpNPCType->armor_tint[index] |= atoi(armorTint_row[index * 3 + 2]); tmpNPCType->armor_tint[index] |= (tmpNPCType->armor_tint[index]) ? (0xFF << 24) : 0; } } - } else - armor_tint_id = 0; + } + // Try loading npc_types tint fields if armor tint is 0 or query failed to get results + if (armor_tint_id == 0) + { + for (int index = MaterialChest; index < _MaterialCount; index++) + { + tmpNPCType->armor_tint[index] = tmpNPCType->armor_tint[0]; + } + } tmpNPCType->see_invis = atoi(row[67]); tmpNPCType->see_invis_undead = atoi(row[68]) == 0? false: true; // Set see_invis_undead flag - if (row[68] != nullptr) + if (row[69] != nullptr) strn0cpy(tmpNPCType->lastname, row[69], 32); tmpNPCType->qglobal = atoi(row[70]) == 0? false: true; // qglobal