From 115d0d14ac462ef1725d4f9e66f169646ec2a3e5 Mon Sep 17 00:00:00 2001 From: Paul Coene Date: Sun, 1 Feb 2015 09:31:07 -0500 Subject: [PATCH 1/3] Fix issues with faction where chars were not allowed to earn faction to offset starting faction values. --- zone/client.cpp | 85 +++++++++++++++++++++++++++++++++++++------------ zone/client.h | 4 +-- 2 files changed, 66 insertions(+), 23 deletions(-) diff --git a/zone/client.cpp b/zone/client.cpp index 8246f9707..20263ff07 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -7522,19 +7522,38 @@ void Client::SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, ui { int32 faction_before_hit; int32 faction_to_use_for_messaging; + FactionMods fm; + int32 this_faction_max; + int32 this_faction_min; if (faction_id[i] <= 0) continue; + // Find out starting faction for this faction + // It needs to be used to adj max and min personal + // The range is still the same, 1200-3000(4200), but adjusted for base + database.GetFactionData(&fm, GetClass(), GetRace(), GetDeity(), + faction_id[i]); + + // Adjust the amount you can go up or down so the resulting range + // is PERSONAL_MAX - PERSONAL_MIN + // + // Adjust these values for cases where starting faction is below + // min or above max by not allowing any earn in those directions. + this_faction_min = MIN_PERSONAL_FACTION - fm.base; + this_faction_min = std::min(0, this_faction_min); + this_faction_max = MAX_PERSONAL_FACTION - fm.base; + this_faction_max = std::max(0, this_faction_max); + // Get the characters current value with that faction current_value = GetCharacterFactionLevel(faction_id[i]); faction_before_hit = current_value; - change = UpdatePersonalFaction(char_id, npc_value[i], faction_id[i], ¤t_value, temp[i]); + change = UpdatePersonalFaction(char_id, npc_value[i], faction_id[i], ¤t_value, temp[i], this_faction_min, this_faction_max); if (change) { - SendFactionMessage(npc_value[i], faction_id[i], faction_before_hit, current_value, temp[i]); + SendFactionMessage(npc_value[i], faction_id[i], faction_before_hit, current_value, temp[i], this_faction_min, this_faction_max); } } return; @@ -7548,16 +7567,37 @@ void Client::SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class //Get the npc faction list if(faction_id > 0 && value != 0) { int32 faction_before_hit; + FactionMods fm; + int32 this_faction_max; + int32 this_faction_min; + + // Find out starting faction for this faction + // It needs to be used to adj max and min personal + // The range is still the same, 1200-3000(4200), but adjusted for base + database.GetFactionData(&fm, GetClass(), GetRace(), GetDeity(), + faction_id); + + // Adjust the amount you can go up or down so the resulting range + // is PERSONAL_MAX - PERSONAL_MIN + // + // Adjust these values for cases where starting faction is below + // min or above max by not allowing any earn/loss in those directions. + // At least one faction starts out way below min, so we don't want + // to allow loses in those cases, just massive gains. + this_faction_min = MIN_PERSONAL_FACTION - fm.base; + this_faction_min = std::min(0, this_faction_min); + this_faction_max = MAX_PERSONAL_FACTION - fm.base; + this_faction_max = std::max(0, this_faction_max); //Get the faction modifiers current_value = GetCharacterFactionLevel(faction_id); faction_before_hit = current_value; - change = UpdatePersonalFaction(char_id, value, faction_id, ¤t_value, temp); + change = UpdatePersonalFaction(char_id, value, faction_id, ¤t_value, temp, this_faction_min, this_faction_max); if (change) { - SendFactionMessage(value, faction_id, faction_before_hit, current_value, temp); + SendFactionMessage(value, faction_id, faction_before_hit, current_value, temp, this_faction_min, this_faction_max); } } @@ -7580,7 +7620,7 @@ int32 Client::GetCharacterFactionLevel(int32 faction_id) // Checks for bottom out and max faction and old faction db entries // Updates the faction if we are not minned, maxed or we need to repair -bool Client::UpdatePersonalFaction(int32 char_id, int32 npc_value, int32 faction_id, int32 *current_value, int32 temp) +bool Client::UpdatePersonalFaction(int32 char_id, int32 npc_value, int32 faction_id, int32 *current_value, int32 temp, int32 this_faction_min, int32 this_faction_max) { bool repair = false; bool change = false; @@ -7598,26 +7638,29 @@ bool Client::UpdatePersonalFaction(int32 char_id, int32 npc_value, int32 faction npc_value *= 2; } } + // Set flag when to update db - if (*current_value > MAX_PERSONAL_FACTION) + // Repair needed, as db changes could modify a base value for a faction + // and we need to auto correct when that happens. + if (*current_value > this_faction_max) { - *current_value = MAX_PERSONAL_FACTION; + *current_value = this_faction_max; repair = true; } - else if (*current_value < MIN_PERSONAL_FACTION) + else if (*current_value < this_faction_min) { - *current_value = MIN_PERSONAL_FACTION; + *current_value = this_faction_min; repair = true; } - else if ((m_pp.gm != 1) && (npc_value != 0) && ((*current_value != MAX_PERSONAL_FACTION) || (*current_value != MIN_PERSONAL_FACTION))) + else if ((m_pp.gm != 1) && (npc_value != 0) && ((*current_value != this_faction_max) || (*current_value != this_faction_min))) change = true; *current_value += npc_value; - if (*current_value > MAX_PERSONAL_FACTION) - *current_value = MAX_PERSONAL_FACTION; - else if (*current_value < MIN_PERSONAL_FACTION) - *current_value = MIN_PERSONAL_FACTION; + if (*current_value > this_faction_max) + *current_value = this_faction_max; + else if (*current_value < this_faction_min) + *current_value = this_faction_min; if (change || repair) { @@ -7705,7 +7748,7 @@ void Client::MerchantRejectMessage(Mob *merchant, int primaryfaction) //o-------------------------------------------------------------- //| Purpose: Send faction change message to client //o-------------------------------------------------------------- -void Client::SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 faction_before_hit, int32 totalvalue, uint8 temp) +void Client::SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 faction_before_hit, int32 totalvalue, uint8 temp, int32 this_faction_min, int32 this_faction_max) { char name[50]; int32 faction_value; @@ -7718,8 +7761,8 @@ void Client::SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 faction_ // hit. For example, if we go from 1199 to 1200 which is the MAX // we still want to say faction got better this time around. - if ( (faction_before_hit == MAX_PERSONAL_FACTION) || - (faction_before_hit == MIN_PERSONAL_FACTION)) + if ( (faction_before_hit == this_faction_max) || + (faction_before_hit == this_faction_min)) faction_value = totalvalue; else faction_value = faction_before_hit; @@ -7730,13 +7773,13 @@ void Client::SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 faction_ if (tmpvalue == 0 || temp == 1 || temp == 2) return; - else if (faction_value >= MAX_PERSONAL_FACTION) + else if (faction_value >= this_faction_max) Message_StringID(15, FACTION_BEST, name); - else if (faction_value <= MIN_PERSONAL_FACTION) + else if (faction_value <= this_faction_min) Message_StringID(15, FACTION_WORST, name); - else if (tmpvalue > 0 && faction_value < MAX_PERSONAL_FACTION && !RuleB(Client, UseLiveFactionMessage)) + else if (tmpvalue > 0 && faction_value < this_faction_max && !RuleB(Client, UseLiveFactionMessage)) Message_StringID(15, FACTION_BETTER, name); - else if (tmpvalue < 0 && faction_value > MIN_PERSONAL_FACTION && !RuleB(Client, UseLiveFactionMessage)) + else if (tmpvalue < 0 && faction_value > this_faction_min && !RuleB(Client, UseLiveFactionMessage)) Message_StringID(15, FACTION_WORSE, name); else if (RuleB(Client, UseLiveFactionMessage)) Message(15, "Your faction standing with %s has been adjusted by %i.", name, tmpvalue); //New Live faction message (14261) diff --git a/zone/client.h b/zone/client.h index f7fe0a2f6..84823085c 100644 --- a/zone/client.h +++ b/zone/client.h @@ -606,9 +606,9 @@ public: int32 GetCharacterFactionLevel(int32 faction_id); int32 GetModCharacterFactionLevel(int32 faction_id); void MerchantRejectMessage(Mob *merchant, int primaryfaction); - void SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 faction_before_hit, int32 totalvalue, uint8 temp); + void SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 faction_before_hit, int32 totalvalue, uint8 temp, int32 this_faction_min, int32 this_faction_max); - bool UpdatePersonalFaction(int32 char_id, int32 npc_value, int32 faction_id, int32 *current_value, int32 temp); + bool UpdatePersonalFaction(int32 char_id, int32 npc_value, int32 faction_id, int32 *current_value, int32 temp, int32 this_faction_min, int32 this_faction_max); void SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, uint8 char_race, uint8 char_deity); void SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class, uint8 char_race, uint8 char_deity, int32 value, uint8 temp); int32 GetRawItemAC(); From 614014a23814e95f644af724e934c9c43e97faa0 Mon Sep 17 00:00:00 2001 From: Paul Coene Date: Sun, 1 Feb 2015 15:02:14 -0500 Subject: [PATCH 2/3] Faction update --- zone/client.cpp | 52 ++++++++++++++++++++++++------------------------- zone/client.h | 2 +- zone/zonedb.cpp | 30 +++++++++++----------------- 3 files changed, 38 insertions(+), 46 deletions(-) diff --git a/zone/client.cpp b/zone/client.cpp index 5ceafec49..9d159ce77 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -7516,7 +7516,6 @@ void Client::SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, ui int32 npc_value[MAX_NPC_FACTIONS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; uint8 temp[MAX_NPC_FACTIONS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int32 current_value; - bool change = false; // Get the npc faction list if (!database.GetNPCFactionList(npc_id, faction_id, npc_value, temp)) @@ -7552,20 +7551,19 @@ void Client::SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, ui current_value = GetCharacterFactionLevel(faction_id[i]); faction_before_hit = current_value; - change = UpdatePersonalFaction(char_id, npc_value[i], faction_id[i], ¤t_value, temp[i], this_faction_min, this_faction_max); + UpdatePersonalFaction(char_id, npc_value[i], faction_id[i], ¤t_value, temp[i], this_faction_min, this_faction_max); - if (change) - { - SendFactionMessage(npc_value[i], faction_id[i], faction_before_hit, current_value, temp[i], this_faction_min, this_faction_max); - } + //Message(14, "Min(%d) Max(%d) Before(%d), After(%d)\n", this_faction_min, this_faction_max, faction_before_hit, current_value); + + SendFactionMessage(npc_value[i], faction_id[i], faction_before_hit, current_value, temp[i], this_faction_min, this_faction_max); } + return; } void Client::SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class, uint8 char_race, uint8 char_deity, int32 value, uint8 temp) { int32 current_value; - bool change=false; //Get the npc faction list if(faction_id > 0 && value != 0) { @@ -7596,12 +7594,11 @@ void Client::SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class current_value = GetCharacterFactionLevel(faction_id); faction_before_hit = current_value; - change = UpdatePersonalFaction(char_id, value, faction_id, ¤t_value, temp, this_faction_min, this_faction_max); + UpdatePersonalFaction(char_id, value, faction_id, ¤t_value, temp, this_faction_min, this_faction_max); - if (change) - { - SendFactionMessage(value, faction_id, faction_before_hit, current_value, temp, this_faction_min, this_faction_max); - } + //Message(14, "Min(%d) Max(%d) Before(%d), After(%d)\n", this_faction_min, this_faction_max, faction_before_hit, current_value); + + SendFactionMessage(value, faction_id, faction_before_hit, current_value, temp, this_faction_min, this_faction_max); } return; @@ -7623,10 +7620,11 @@ int32 Client::GetCharacterFactionLevel(int32 faction_id) // Checks for bottom out and max faction and old faction db entries // Updates the faction if we are not minned, maxed or we need to repair -bool Client::UpdatePersonalFaction(int32 char_id, int32 npc_value, int32 faction_id, int32 *current_value, int32 temp, int32 this_faction_min, int32 this_faction_max) +void Client::UpdatePersonalFaction(int32 char_id, int32 npc_value, int32 faction_id, int32 *current_value, int32 temp, int32 this_faction_min, int32 this_faction_max) { bool repair = false; bool change = false; + int32 faction_before_hit = *current_value - npc_value; if (this->itembonuses.HeroicCHA) { @@ -7655,22 +7653,24 @@ bool Client::UpdatePersonalFaction(int32 char_id, int32 npc_value, int32 faction *current_value = this_faction_min; repair = true; } - else if ((m_pp.gm != 1) && (npc_value != 0) && ((*current_value != this_faction_max) || (*current_value != this_faction_min))) + else if ((m_pp.gm != 1) && (npc_value != 0) && + ((npc_value > 0 && faction_before_hit != this_faction_max) || + ((npc_value < 0 && faction_before_hit != this_faction_min)))) change = true; - *current_value += npc_value; - - if (*current_value > this_faction_max) - *current_value = this_faction_max; - else if (*current_value < this_faction_min) - *current_value = this_faction_min; - if (change || repair) { + *current_value += npc_value; + + if (*current_value > this_faction_max) + *current_value = this_faction_max; + else if (*current_value < this_faction_min) + *current_value = this_faction_min; + database.SetCharacterFactionLevel(char_id, faction_id, *current_value, temp, factionvalues); } -return (repair || change); +return; } // returns the character's faction level, adjusted for racial, class, and deity modifiers @@ -7756,16 +7756,16 @@ void Client::SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 faction_ char name[50]; int32 faction_value; - // If we're dropping from MAX or raising from MIN, we should - // base the message on the new updated value so we don't show + // If we're dropping from MAX or raising from MIN or repairing, + // we should base the message on the new updated value so we don't show // a min MAX message // // If we're changing any other place, we use the value before the // hit. For example, if we go from 1199 to 1200 which is the MAX // we still want to say faction got better this time around. - if ( (faction_before_hit == this_faction_max) || - (faction_before_hit == this_faction_min)) + if ( (faction_before_hit >= this_faction_max) || + (faction_before_hit <= this_faction_min)) faction_value = totalvalue; else faction_value = faction_before_hit; diff --git a/zone/client.h b/zone/client.h index fa7da0fc0..9248fb742 100644 --- a/zone/client.h +++ b/zone/client.h @@ -609,7 +609,7 @@ public: void MerchantRejectMessage(Mob *merchant, int primaryfaction); void SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 faction_before_hit, int32 totalvalue, uint8 temp, int32 this_faction_min, int32 this_faction_max); - bool UpdatePersonalFaction(int32 char_id, int32 npc_value, int32 faction_id, int32 *current_value, int32 temp, int32 this_faction_min, int32 this_faction_max); + void UpdatePersonalFaction(int32 char_id, int32 npc_value, int32 faction_id, int32 *current_value, int32 temp, int32 this_faction_min, int32 this_faction_max); void SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, uint8 char_race, uint8 char_deity); void SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class, uint8 char_race, uint8 char_deity, int32 value, uint8 temp); int32 GetRawItemAC(); diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 56236f1b8..e90016dfb 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -3212,16 +3212,7 @@ bool ZoneDatabase::GetNPCFactionList(uint32 npcfaction_id, int32* faction_id, in bool ZoneDatabase::SetCharacterFactionLevel(uint32 char_id, int32 faction_id, int32 value, uint8 temp, faction_map &val_list) { - std::string query = StringFormat("DELETE FROM faction_values " - "WHERE char_id=%i AND faction_id = %i", - char_id, faction_id); - auto results = QueryDatabase(query); - if (!results.Success()) { - return false; - } - - if(value == 0) - return true; + std::string query; if(temp == 2) temp = 0; @@ -3229,17 +3220,18 @@ bool ZoneDatabase::SetCharacterFactionLevel(uint32 char_id, int32 faction_id, in if(temp == 3) temp = 1; - query = StringFormat("INSERT INTO faction_values (char_id, faction_id, current_value, temp) " - "VALUES (%i, %i, %i, %i)", char_id, faction_id, value, temp); - results = QueryDatabase(query); - if (!results.Success()) { + query = StringFormat("INSERT INTO `faction_values` " + "(`char_id`, `faction_id`, `current_value`, `temp`) " + "VALUES (%i, %i, %i, %i) " + "ON DUPLICATE KEY UPDATE `current_value`=%i,`temp`=%i", + char_id, faction_id, value, temp, value, temp); + auto results = QueryDatabase(query); + + if (!results.Success()) return false; - } + else + val_list[faction_id] = value; - if (results.RowsAffected() == 0) - return false; - - val_list[faction_id] = value; return true; } From 1d40f20da007ae37d8c068fa290b0b9883618ba9 Mon Sep 17 00:00:00 2001 From: Paul Coene Date: Sun, 1 Feb 2015 16:14:05 -0500 Subject: [PATCH 3/3] Remove incorrect use of before_hit --- zone/client.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/zone/client.cpp b/zone/client.cpp index 9d159ce77..5cc5ae309 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -7624,7 +7624,6 @@ void Client::UpdatePersonalFaction(int32 char_id, int32 npc_value, int32 faction { bool repair = false; bool change = false; - int32 faction_before_hit = *current_value - npc_value; if (this->itembonuses.HeroicCHA) { @@ -7654,8 +7653,8 @@ void Client::UpdatePersonalFaction(int32 char_id, int32 npc_value, int32 faction repair = true; } else if ((m_pp.gm != 1) && (npc_value != 0) && - ((npc_value > 0 && faction_before_hit != this_faction_max) || - ((npc_value < 0 && faction_before_hit != this_faction_min)))) + ((npc_value > 0 && *current_value != this_faction_max) || + ((npc_value < 0 && *current_value != this_faction_min)))) change = true; if (change || repair)