(RoF+) Added herosforgemodel field to the npc_types table. Not fully functional yet for NPCs (currently only displays helm correctly).

(RoF2) Updated item links from #npcstat command output.
This commit is contained in:
Trevius 2014-12-24 02:31:37 -06:00
parent f6dc138dc8
commit c48d2d9888
10 changed files with 116 additions and 86 deletions

View File

@ -1,5 +1,9 @@
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: (RoF2) Updated item links from #npcstat command output.
== 12/23/2014 ==
Uleat: Tidied up some ItemInst* declarations and added some nullptr checks.
Trevius: (RoF+) Added support for Hero's Forge Robe Models. Set herosforgemodel field in items table to exact model such as 11607, 11707, etc.

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 9063
#define CURRENT_BINARY_DATABASE_VERSION 9064
#define COMPILE_DATE __DATE__
#define COMPILE_TIME __TIME__
#ifndef WIN32

View File

@ -317,6 +317,7 @@
9061|2014_12_13_inventory_table_update.sql|SHOW COLUMNS FROM `inventory` LIKE 'ornament_hero_model'|empty|
9062|2014_12_15_multiple_table_updates.sql|SHOW COLUMNS FROM `items` LIKE 'augslot6type'|empty|
9063|2014_12_24_npc_types_update.sql|SHOW COLUMNS FROM `npc_types` LIKE 'd_melee_texture1'|empty|
9064|2014_12_24_npc_types_table_update.sql|SHOW COLUMNS FROM `npc_types` LIKE 'herosforgemodel'|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 `npc_types` ADD `herosforgemodel` int( 11 ) NOT NULL DEFAULT '0' AFTER `helmtexture`;

View File

@ -978,7 +978,8 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
strn0cpy(ns->spawn.lastName, lastname, sizeof(ns->spawn.lastName));
for (i = 0; i < _MaterialCount; i++)
//for (i = 0; i < _MaterialCount; i++)
for (i = 0; i < 9; i++)
{
// Only Player Races Wear Armor
if (Mob::IsPlayerRace(race) || i > 6)
@ -2733,7 +2734,6 @@ int32 Mob::GetEquipmentMaterial(uint8 material_slot) const
int32 Mob::GetHerosForgeModel(uint8 material_slot) const
{
uint32 HeroModel = 0;
if (material_slot >= 0 && material_slot < MaterialPrimary)
{
@ -2744,7 +2744,7 @@ int32 Mob::GetHerosForgeModel(uint8 material_slot) const
if (item != 0 && invslot != INVALID_INDEX)
{
if (this->IsClient())
if (IsClient())
{
const ItemInst* inst = CastToClient()->m_inv[invslot];
if (inst)
@ -2766,6 +2766,16 @@ int32 Mob::GetHerosForgeModel(uint8 material_slot) const
HeroModel = item->HerosForgeModel;
}
}
if (IsNPC())
{
HeroModel = CastToNPC()->GetHeroForgeModel();
// Robes require full model number, and should only be sent to chest slot
if (HeroModel > 1000 && material_slot != 1)
{
HeroModel = 0;
}
}
}
// Auto-Convert Hero Model to match the slot

View File

@ -263,6 +263,8 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
d_melee_texture1 = d->d_melee_texture1;
d_melee_texture2 = d->d_melee_texture2;
herosforgemodel = d->herosforgemodel;
ammo_idfile = d->ammo_idfile;
memset(equipment, 0, sizeof(equipment));
prim_melee_type = d->prim_melee_type;
@ -508,7 +510,11 @@ void NPC::QueryLoot(Client* to) {
for(; cur != end; ++cur) {
const Item_Struct* item = database.GetItem((*cur)->item_id);
if (item)
if (to->GetClientVersion() >= EQClientRoF)
if (to->GetClientVersion() >= EQClientRoF2)
{
to->Message(0, "minlvl: %i maxlvl: %i %i: %c%06X00000000000000000000000000000000000000000000000000%s%c", (*cur)->min_level, (*cur)->max_level, (int)item->ID, 0x12, item->ID, item->Name, 0x12);
}
else if (to->GetClientVersion() >= EQClientRoF)
{
to->Message(0, "minlvl: %i maxlvl: %i %i: %c%06X0000000000000000000000000000000000000000000000000%s%c",(*cur)->min_level, (*cur)->max_level, (int) item->ID,0x12, item->ID, item->Name, 0x12);
}

View File

@ -403,6 +403,9 @@ public:
void mod_npc_killed(Mob* oos);
void AISpellsList(Client *c);
uint32 GetHeroForgeModel() const { return herosforgemodel; }
void SetHeroForgeModel(uint32 model) { herosforgemodel = model; }
bool IsRaidTarget() const { return raid_target; };
protected:
@ -492,6 +495,8 @@ protected:
uint16 skills[HIGHEST_SKILL+1];
uint32 equipment[EmuConstants::EQUIPMENT_SIZE]; //this is an array of item IDs
uint32 herosforgemodel; //this is the Hero Forge Armor Model (i.e 63 or 84 or 203)
uint16 d_melee_texture1; //this is an item Material value
uint16 d_melee_texture2; //this is an item Material value (offhand)
const char* ammo_idfile; //this determines projectile graphic "IT###" (see item field 'idfile')

View File

@ -393,6 +393,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
npc_type->gender = monster->gender;
npc_type->luclinface = monster->luclinface;
npc_type->helmtexture = monster->helmtexture;
npc_type->herosforgemodel = monster->herosforgemodel;
} else
LogFile->write(EQEMuLog::Error, "Error loading NPC data for monster summoning pet (NPC ID %d)", monsterid);

View File

@ -1740,7 +1740,7 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) {
// according to spawn2.
std::string query = StringFormat("SELECT npc_types.id, npc_types.name, npc_types.level, npc_types.race, "
"npc_types.class, npc_types.hp, npc_types.mana, npc_types.gender, "
"npc_types.texture, npc_types.helmtexture, npc_types.size, "
"npc_types.texture, npc_types.helmtexture, npc_types.herosforgemodel, npc_types.size, "
"npc_types.loottable_id, npc_types.merchant_id, npc_types.alt_currency_id, "
"npc_types.adventure_template_id, npc_types.trap_template, npc_types.attack_speed, "
"npc_types.STR, npc_types.STA, npc_types.DEX, npc_types.AGI, npc_types._INT, "
@ -1790,82 +1790,83 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) {
tmpNPCType->gender = atoi(row[7]);
tmpNPCType->texture = atoi(row[8]);
tmpNPCType->helmtexture = atoi(row[9]);
tmpNPCType->size = atof(row[10]);
tmpNPCType->loottable_id = atoi(row[11]);
tmpNPCType->merchanttype = atoi(row[12]);
tmpNPCType->alt_currency_type = atoi(row[13]);
tmpNPCType->adventure_template = atoi(row[14]);
tmpNPCType->trap_template = atoi(row[15]);
tmpNPCType->attack_speed = atof(row[16]);
tmpNPCType->STR = atoi(row[17]);
tmpNPCType->STA = atoi(row[18]);
tmpNPCType->DEX = atoi(row[19]);
tmpNPCType->AGI = atoi(row[20]);
tmpNPCType->INT = atoi(row[21]);
tmpNPCType->WIS = atoi(row[22]);
tmpNPCType->CHA = atoi(row[23]);
tmpNPCType->MR = atoi(row[24]);
tmpNPCType->CR = atoi(row[25]);
tmpNPCType->DR = atoi(row[26]);
tmpNPCType->FR = atoi(row[27]);
tmpNPCType->PR = atoi(row[28]);
tmpNPCType->Corrup = atoi(row[29]);
tmpNPCType->PhR = atoi(row[30]);
tmpNPCType->min_dmg = atoi(row[31]);
tmpNPCType->max_dmg = atoi(row[32]);
tmpNPCType->attack_count = atoi(row[33]);
tmpNPCType->herosforgemodel = atoi(row[10]);
tmpNPCType->size = atof(row[11]);
tmpNPCType->loottable_id = atoi(row[12]);
tmpNPCType->merchanttype = atoi(row[13]);
tmpNPCType->alt_currency_type = atoi(row[14]);
tmpNPCType->adventure_template = atoi(row[15]);
tmpNPCType->trap_template = atoi(row[16]);
tmpNPCType->attack_speed = atof(row[17]);
tmpNPCType->STR = atoi(row[18]);
tmpNPCType->STA = atoi(row[19]);
tmpNPCType->DEX = atoi(row[20]);
tmpNPCType->AGI = atoi(row[21]);
tmpNPCType->INT = atoi(row[22]);
tmpNPCType->WIS = atoi(row[23]);
tmpNPCType->CHA = atoi(row[24]);
tmpNPCType->MR = atoi(row[25]);
tmpNPCType->CR = atoi(row[26]);
tmpNPCType->DR = atoi(row[27]);
tmpNPCType->FR = atoi(row[28]);
tmpNPCType->PR = atoi(row[29]);
tmpNPCType->Corrup = atoi(row[30]);
tmpNPCType->PhR = atoi(row[31]);
tmpNPCType->min_dmg = atoi(row[32]);
tmpNPCType->max_dmg = atoi(row[33]);
tmpNPCType->attack_count = atoi(row[34]);
if (row[34] != nullptr)
strn0cpy(tmpNPCType->special_abilities, row[34], 512);
strn0cpy(tmpNPCType->special_abilities, row[35], 512);
else
tmpNPCType->special_abilities[0] = '\0';
tmpNPCType->npc_spells_id = atoi(row[35]);
tmpNPCType->npc_spells_effects_id = atoi(row[36]);
tmpNPCType->d_melee_texture1 = atoi(row[37]);
tmpNPCType->d_melee_texture2 = atoi(row[38]);
strn0cpy(tmpNPCType->ammo_idfile, row[39], 30);
tmpNPCType->prim_melee_type = atoi(row[40]);
tmpNPCType->sec_melee_type = atoi(row[41]);
tmpNPCType->ranged_type = atoi(row[42]);
tmpNPCType->runspeed= atof(row[43]);
tmpNPCType->findable = atoi(row[44]) == 0? false : true;
tmpNPCType->trackable = atoi(row[45]) == 0? false : true;
tmpNPCType->hp_regen = atoi(row[46]);
tmpNPCType->mana_regen = atoi(row[47]);
tmpNPCType->npc_spells_id = atoi(row[36]);
tmpNPCType->npc_spells_effects_id = atoi(row[37]);
tmpNPCType->d_melee_texture1 = atoi(row[38]);
tmpNPCType->d_melee_texture2 = atoi(row[39]);
strn0cpy(tmpNPCType->ammo_idfile, row[40], 30);
tmpNPCType->prim_melee_type = atoi(row[41]);
tmpNPCType->sec_melee_type = atoi(row[42]);
tmpNPCType->ranged_type = atoi(row[43]);
tmpNPCType->runspeed= atof(row[44]);
tmpNPCType->findable = atoi(row[45]) == 0? false : true;
tmpNPCType->trackable = atoi(row[46]) == 0? false : true;
tmpNPCType->hp_regen = atoi(row[47]);
tmpNPCType->mana_regen = atoi(row[48]);
// set defaultvalue for aggroradius
tmpNPCType->aggroradius = (int32)atoi(row[48]);
tmpNPCType->aggroradius = (int32)atoi(row[49]);
if (tmpNPCType->aggroradius <= 0)
tmpNPCType->aggroradius = 70;
tmpNPCType->assistradius = (int32)atoi(row[49]);
tmpNPCType->assistradius = (int32)atoi(row[50]);
if (tmpNPCType->assistradius <= 0)
tmpNPCType->assistradius = tmpNPCType->aggroradius;
if (row[50] && strlen(row[50]))
tmpNPCType->bodytype = (uint8)atoi(row[50]);
tmpNPCType->bodytype = (uint8)atoi(row[51]);
else
tmpNPCType->bodytype = 0;
tmpNPCType->npc_faction_id = atoi(row[51]);
tmpNPCType->npc_faction_id = atoi(row[52]);
tmpNPCType->luclinface = atoi(row[52]);
tmpNPCType->hairstyle = atoi(row[53]);
tmpNPCType->haircolor = atoi(row[54]);
tmpNPCType->eyecolor1 = atoi(row[55]);
tmpNPCType->eyecolor2 = atoi(row[56]);
tmpNPCType->beardcolor = atoi(row[57]);
tmpNPCType->beard = atoi(row[58]);
tmpNPCType->drakkin_heritage = atoi(row[59]);
tmpNPCType->drakkin_tattoo = atoi(row[60]);
tmpNPCType->drakkin_details = atoi(row[61]);
tmpNPCType->luclinface = atoi(row[53]);
tmpNPCType->hairstyle = atoi(row[54]);
tmpNPCType->haircolor = atoi(row[55]);
tmpNPCType->eyecolor1 = atoi(row[56]);
tmpNPCType->eyecolor2 = atoi(row[57]);
tmpNPCType->beardcolor = atoi(row[58]);
tmpNPCType->beard = atoi(row[59]);
tmpNPCType->drakkin_heritage = atoi(row[60]);
tmpNPCType->drakkin_tattoo = atoi(row[61]);
tmpNPCType->drakkin_details = atoi(row[62]);
uint32 armor_tint_id = atoi(row[62]);
uint32 armor_tint_id = atoi(row[63]);
tmpNPCType->armor_tint[0] = (atoi(row[63]) & 0xFF) << 16;
tmpNPCType->armor_tint[0] |= (atoi(row[64]) & 0xFF) << 8;
tmpNPCType->armor_tint[0] |= (atoi(row[65]) & 0xFF);
tmpNPCType->armor_tint[0] = (atoi(row[64]) & 0xFF) << 16;
tmpNPCType->armor_tint[0] |= (atoi(row[65]) & 0xFF) << 8;
tmpNPCType->armor_tint[0] |= (atoi(row[66]) & 0xFF);
tmpNPCType->armor_tint[0] |= (tmpNPCType->armor_tint[0]) ? (0xFF << 24) : 0;
if (armor_tint_id == 0)
@ -1900,32 +1901,32 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) {
} else
armor_tint_id = 0;
tmpNPCType->see_invis = atoi(row[66]);
tmpNPCType->see_invis_undead = atoi(row[67]) == 0? false: true; // Set see_invis_undead flag
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)
strn0cpy(tmpNPCType->lastname, row[68], 32);
strn0cpy(tmpNPCType->lastname, row[69], 32);
tmpNPCType->qglobal = atoi(row[69]) == 0? false: true; // qglobal
tmpNPCType->AC = atoi(row[70]);
tmpNPCType->npc_aggro = atoi(row[71]) == 0? false: true;
tmpNPCType->spawn_limit = atoi(row[72]);
tmpNPCType->see_hide = atoi(row[73]) == 0? false: true;
tmpNPCType->see_improved_hide = atoi(row[74]) == 0? false: true;
tmpNPCType->ATK = atoi(row[75]);
tmpNPCType->accuracy_rating = atoi(row[76]);
tmpNPCType->avoidance_rating = atoi(row[77]);
tmpNPCType->slow_mitigation = atoi(row[78]);
tmpNPCType->maxlevel = atoi(row[79]);
tmpNPCType->scalerate = atoi(row[80]);
tmpNPCType->private_corpse = atoi(row[81]) == 1 ? true: false;
tmpNPCType->unique_spawn_by_name = atoi(row[82]) == 1 ? true: false;
tmpNPCType->underwater = atoi(row[83]) == 1 ? true: false;
tmpNPCType->emoteid = atoi(row[84]);
tmpNPCType->spellscale = atoi(row[85]);
tmpNPCType->healscale = atoi(row[86]);
tmpNPCType->no_target_hotkey = atoi(row[87]) == 1 ? true: false;
tmpNPCType->raid_target = atoi(row[88]) == 0 ? false: true;
tmpNPCType->attack_delay = atoi(row[89]);
tmpNPCType->qglobal = atoi(row[70]) == 0? false: true; // qglobal
tmpNPCType->AC = atoi(row[71]);
tmpNPCType->npc_aggro = atoi(row[72]) == 0? false: true;
tmpNPCType->spawn_limit = atoi(row[73]);
tmpNPCType->see_hide = atoi(row[74]) == 0? false: true;
tmpNPCType->see_improved_hide = atoi(row[75]) == 0? false: true;
tmpNPCType->ATK = atoi(row[76]);
tmpNPCType->accuracy_rating = atoi(row[77]);
tmpNPCType->avoidance_rating = atoi(row[78]);
tmpNPCType->slow_mitigation = atoi(row[79]);
tmpNPCType->maxlevel = atoi(row[80]);
tmpNPCType->scalerate = atoi(row[81]);
tmpNPCType->private_corpse = atoi(row[82]) == 1 ? true: false;
tmpNPCType->unique_spawn_by_name = atoi(row[83]) == 1 ? true: false;
tmpNPCType->underwater = atoi(row[84]) == 1 ? true: false;
tmpNPCType->emoteid = atoi(row[85]);
tmpNPCType->spellscale = atoi(row[86]);
tmpNPCType->healscale = atoi(row[87]);
tmpNPCType->no_target_hotkey = atoi(row[88]) == 1 ? true: false;
tmpNPCType->raid_target = atoi(row[89]) == 0 ? false: true;
tmpNPCType->attack_delay = atoi(row[90]);
// If NPC with duplicate NPC id already in table,
// free item we attempted to add.

View File

@ -49,6 +49,7 @@ struct NPCType
uint32 npc_id;
uint8 texture;
uint8 helmtexture;
uint32 herosforgemodel;
uint32 loottable_id;
uint32 npc_spells_id;
uint32 npc_spells_effects_id;