diff --git a/common/version.h b/common/version.h index 925292555..7044ba6e5 100644 --- a/common/version.h +++ b/common/version.h @@ -30,7 +30,7 @@ Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9071 +#define CURRENT_BINARY_DATABASE_VERSION 9072 #define COMPILE_DATE __DATE__ #define COMPILE_TIME __TIME__ #ifndef WIN32 diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index 90a67a789..3104d3e4b 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -325,6 +325,7 @@ 9069|2015_01_25_logsys_Mercenaries_category.sql|SELECT * FROM `logsys_categories` WHERE `log_category_description` LIKE 'Mercenaries'|empty| 9070|2015_01_28_quest_debug_log_category.sql|SELECT * FROM `logsys_categories` WHERE `log_category_description` LIKE 'Quest Debug'|empty| 9071|2015_01_29_merc_stats_table_update.sql|SHOW COLUMNS FROM `merc_stats` LIKE 'statscale'|empty| +9072|2015_01_30_attack_delay.sql|SHOW COLUMNS FROM `merc_stats` LIKE 'attack_delay'|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/2015_01_30_merc_attack_delay.sql b/utils/sql/git/required/2015_01_30_merc_attack_delay.sql new file mode 100644 index 000000000..6aa63e61f --- /dev/null +++ b/utils/sql/git/required/2015_01_30_merc_attack_delay.sql @@ -0,0 +1,3 @@ +ALTER TABLE `merc_stats` ADD `attack_delay` TINYINT(3) UNSIGNED DEFAULT '30' NOT NULL AFTER `attack_speed`; +UPDATE `merc_stats` SET `attack_delay` = 36 + 36 * (`attack_speed` / 100); +UPDATE `merc_stats` SET `attack_delay` = 30 WHERE `attack_speed` = 0; diff --git a/zone/merc.cpp b/zone/merc.cpp index 86225e6ab..2fea4aba4 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -4837,18 +4837,19 @@ void Merc::UpdateMercInfo(Client *c) { c->GetMercInfo().drakkinDetails = drakkin_details; } -void Merc::UpdateMercStats(Client *c, bool setmax) { - if(c->GetMercInfo().MercTemplateID > 0) - { - Log.Out(Logs::General, Logs::Mercenaries, "Updating Mercenary Stats for %s (%s).", GetName(), c->GetName()); - const NPCType* npc_type = database.GetMercType( zone->GetMercTemplate(c->GetMercInfo().MercTemplateID)->MercNPCID, GetRace(), c->GetLevel()); - if (npc_type) - { +void Merc::UpdateMercStats(Client *c, bool setmax) +{ + if (c->GetMercInfo().MercTemplateID > 0) { + Log.Out(Logs::General, Logs::Mercenaries, "Updating Mercenary Stats for %s (%s).", GetName(), + c->GetName()); + const NPCType *npc_type = database.GetMercType( + zone->GetMercTemplate(c->GetMercInfo().MercTemplateID)->MercNPCID, GetRace(), c->GetLevel()); + if (npc_type) { max_hp = npc_type->max_hp; base_hp = npc_type->max_hp; max_mana = npc_type->Mana; base_mana = npc_type->Mana; - max_end = npc_type->max_hp; // Hack since Endurance does not exist for NPCType yet + max_end = npc_type->max_hp; // Hack since Endurance does not exist for NPCType yet base_end = npc_type->max_hp; // Hack since Endurance does not exist for NPCType yet hp_regen = npc_type->hp_regen; mana_regen = npc_type->mana_regen; @@ -4871,14 +4872,14 @@ void Merc::UpdateMercStats(Client *c, bool setmax) { _basePR = npc_type->PR; _baseCR = npc_type->CR; _baseCorrup = npc_type->Corrup; - + uint32 scalepercent = (int)(npc_type->scalerate * RuleI(Mercs, ScaleRate) / 100); - + ScaleStats(scalepercent, setmax); level = npc_type->level; attack_count = npc_type->attack_count; - attack_speed = npc_type->attack_speed; + attack_delay = npc_type->attack_delay; spellscale = npc_type->spellscale; healscale = npc_type->healscale; diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 7f80c7b6f..bb81a0fc4 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -1937,8 +1937,8 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) { return npc; } -const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 clientlevel) { - +const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 clientlevel) +{ //need to save based on merc_npc_type & client level uint32 merc_type_id = id * 100 + clientlevel; @@ -1963,7 +1963,7 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client "0 AS gender, " "m_armorinfo.texture, " "m_armorinfo.helmtexture, " - "m_stats.attack_speed, " + "m_stats.attack_delay, " "m_stats.STR, " "m_stats.STA, " "m_stats.DEX, " @@ -2015,125 +2015,125 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client "WHERE m_templates.merc_npc_type_id = %d AND m_stats.clientlevel = %d AND m_types.race_id = %d", id, clientlevel, raceid); //dual primary keys. one is ID, one is level. - auto results = QueryDatabase(query); - if (!results.Success()) { - return nullptr; - } + auto results = QueryDatabase(query); + if (!results.Success()) { + return nullptr; + } - const NPCType *npc; + const NPCType *npc; - // Process each row returned. - for (auto row = results.begin(); row != results.end(); ++row) { - NPCType *tmpNPCType; - tmpNPCType = new NPCType; - memset (tmpNPCType, 0, sizeof *tmpNPCType); + // Process each row returned. + for (auto row = results.begin(); row != results.end(); ++row) { + NPCType *tmpNPCType; + tmpNPCType = new NPCType; + memset(tmpNPCType, 0, sizeof *tmpNPCType); - tmpNPCType->npc_id = atoi(row[0]); + tmpNPCType->npc_id = atoi(row[0]); - strn0cpy(tmpNPCType->name, row[1], 50); + strn0cpy(tmpNPCType->name, row[1], 50); - tmpNPCType->level = atoi(row[2]); - tmpNPCType->race = atoi(row[3]); - tmpNPCType->class_ = atoi(row[4]); - tmpNPCType->max_hp = atoi(row[5]); - tmpNPCType->cur_hp = tmpNPCType->max_hp; - tmpNPCType->Mana = atoi(row[6]); - tmpNPCType->gender = atoi(row[7]); - tmpNPCType->texture = atoi(row[8]); - tmpNPCType->helmtexture = atoi(row[9]); - tmpNPCType->attack_speed = atof(row[10]); - tmpNPCType->STR = atoi(row[11]); - tmpNPCType->STA = atoi(row[12]); - tmpNPCType->DEX = atoi(row[13]); - tmpNPCType->AGI = atoi(row[14]); - tmpNPCType->INT = atoi(row[15]); - tmpNPCType->WIS = atoi(row[16]); - tmpNPCType->CHA = atoi(row[17]); - tmpNPCType->MR = atoi(row[18]); - tmpNPCType->CR = atoi(row[19]); - tmpNPCType->DR = atoi(row[20]); - tmpNPCType->FR = atoi(row[21]); - tmpNPCType->PR = atoi(row[22]); - tmpNPCType->Corrup = atoi(row[23]); - tmpNPCType->min_dmg = atoi(row[24]); - tmpNPCType->max_dmg = atoi(row[25]); - tmpNPCType->attack_count = atoi(row[26]); + tmpNPCType->level = atoi(row[2]); + tmpNPCType->race = atoi(row[3]); + tmpNPCType->class_ = atoi(row[4]); + tmpNPCType->max_hp = atoi(row[5]); + tmpNPCType->cur_hp = tmpNPCType->max_hp; + tmpNPCType->Mana = atoi(row[6]); + tmpNPCType->gender = atoi(row[7]); + tmpNPCType->texture = atoi(row[8]); + tmpNPCType->helmtexture = atoi(row[9]); + tmpNPCType->attack_delay = atoi(row[10]); + tmpNPCType->STR = atoi(row[11]); + tmpNPCType->STA = atoi(row[12]); + tmpNPCType->DEX = atoi(row[13]); + tmpNPCType->AGI = atoi(row[14]); + tmpNPCType->INT = atoi(row[15]); + tmpNPCType->WIS = atoi(row[16]); + tmpNPCType->CHA = atoi(row[17]); + tmpNPCType->MR = atoi(row[18]); + tmpNPCType->CR = atoi(row[19]); + tmpNPCType->DR = atoi(row[20]); + tmpNPCType->FR = atoi(row[21]); + tmpNPCType->PR = atoi(row[22]); + tmpNPCType->Corrup = atoi(row[23]); + tmpNPCType->min_dmg = atoi(row[24]); + tmpNPCType->max_dmg = atoi(row[25]); + tmpNPCType->attack_count = atoi(row[26]); if (row[27] != nullptr) strn0cpy(tmpNPCType->special_abilities, row[27], 512); else tmpNPCType->special_abilities[0] = '\0'; - tmpNPCType->d_melee_texture1 = atoi(row[28]); - tmpNPCType->d_melee_texture2 = atoi(row[29]); - tmpNPCType->prim_melee_type = atoi(row[30]); - tmpNPCType->sec_melee_type = atoi(row[31]); - tmpNPCType->runspeed= atof(row[32]); + tmpNPCType->d_melee_texture1 = atoi(row[28]); + tmpNPCType->d_melee_texture2 = atoi(row[29]); + tmpNPCType->prim_melee_type = atoi(row[30]); + tmpNPCType->sec_melee_type = atoi(row[31]); + tmpNPCType->runspeed = atof(row[32]); - tmpNPCType->hp_regen = atoi(row[33]); - tmpNPCType->mana_regen = atoi(row[34]); + tmpNPCType->hp_regen = atoi(row[33]); + tmpNPCType->mana_regen = atoi(row[34]); - tmpNPCType->aggroradius = RuleI(Mercs, AggroRadius); + tmpNPCType->aggroradius = RuleI(Mercs, AggroRadius); - if (row[35] && strlen(row[35])) - tmpNPCType->bodytype = (uint8)atoi(row[35]); - else - tmpNPCType->bodytype = 1; + if (row[35] && strlen(row[35])) + tmpNPCType->bodytype = (uint8)atoi(row[35]); + else + tmpNPCType->bodytype = 1; - uint32 armor_tint_id = atoi(row[36]); - tmpNPCType->armor_tint[0] = (atoi(row[37]) & 0xFF) << 16; - tmpNPCType->armor_tint[0] |= (atoi(row[38]) & 0xFF) << 8; - tmpNPCType->armor_tint[0] |= (atoi(row[39]) & 0xFF); - tmpNPCType->armor_tint[0] |= (tmpNPCType->armor_tint[0]) ? (0xFF << 24) : 0; + uint32 armor_tint_id = atoi(row[36]); + tmpNPCType->armor_tint[0] = (atoi(row[37]) & 0xFF) << 16; + tmpNPCType->armor_tint[0] |= (atoi(row[38]) & 0xFF) << 8; + tmpNPCType->armor_tint[0] |= (atoi(row[39]) & 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) { - std::string armorTint_query = StringFormat("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); - auto armorTint_results = QueryDatabase(armorTint_query); - if (!results.Success() || results.RowCount() == 0) - armor_tint_id = 0; - else { - auto armorTint_row = results.begin(); + 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) { + std::string armorTint_query = StringFormat("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); + auto armorTint_results = QueryDatabase(armorTint_query); + if (!results.Success() || results.RowCount() == 0) + armor_tint_id = 0; + else { + auto armorTint_row = results.begin(); - 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; + 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; - tmpNPCType->AC = atoi(row[40]); - tmpNPCType->ATK = atoi(row[41]); - tmpNPCType->accuracy_rating = atoi(row[42]); + tmpNPCType->AC = atoi(row[40]); + tmpNPCType->ATK = atoi(row[41]); + tmpNPCType->accuracy_rating = atoi(row[42]); tmpNPCType->scalerate = atoi(row[43]); - tmpNPCType->spellscale = atoi(row[44]); - tmpNPCType->healscale = atoi(row[45]); + tmpNPCType->spellscale = atoi(row[44]); + tmpNPCType->healscale = atoi(row[45]); - // If Merc with duplicate NPC id already in table, - // free item we attempted to add. + // If Merc with duplicate NPC id already in table, + // free item we attempted to add. if (zone->merctable.find(merc_type_id) != zone->merctable.end()) { - delete tmpNPCType; - return nullptr; - } + delete tmpNPCType; + return nullptr; + } zone->merctable[merc_type_id] = tmpNPCType; - npc = tmpNPCType; - } + npc = tmpNPCType; + } return npc; }