From f88a6774a98eb49a7bbb9d60db245004dcc8af07 Mon Sep 17 00:00:00 2001 From: Allen Date: Wed, 12 Apr 2017 00:54:37 -0700 Subject: [PATCH 1/5] ** Fix for groups with multiple players and bots. * Fixes non-group leaders zoning with their bots. * Fixes non-bot owners attempting to load bots they don't own. * Sets bots that zone to follow owner not group leader. * Updates database call only load bots in group you own. * Tested on server 2 clients, 4 bots, all permutations of zoning. --- zone/bot.cpp | 17 ++++++++++------- zone/bot_database.cpp | 19 ++++++------------- zone/bot_database.h | 2 +- 3 files changed, 17 insertions(+), 21 deletions(-) diff --git a/zone/bot.cpp b/zone/bot.cpp index 5678a62d0..c66fdeb56 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -2995,7 +2995,8 @@ void Bot::LoadAndSpawnAllZonedBots(Client* botOwner) { if(g) { uint32 TempGroupId = g->GetID(); std::list ActiveBots; - if (!botdb.LoadGroupedBotsByGroupID(TempGroupId, ActiveBots)) { + // Modified LoadGroupedBotsByGroupID to require a CharacterID + if (!botdb.LoadGroupedBotsByGroupID(botOwner->CharacterID(), TempGroupId, ActiveBots)) { botOwner->Message(13, "%s", BotDatabase::fail::LoadGroupedBotsByGroupID()); return; } @@ -3007,8 +3008,9 @@ void Bot::LoadAndSpawnAllZonedBots(Client* botOwner) { if(activeBot) { activeBot->Spawn(botOwner); g->UpdatePlayer(activeBot); - if(g->GetLeader()) - activeBot->SetFollowID(g->GetLeader()->GetID()); + // follow the bot owner, not the group leader we just zoned with our owner. + if(g->IsGroupMember(botOwner) && g->IsGroupMember(activeBot)) + activeBot->SetFollowID(botOwner->GetID()); } if(activeBot && !botOwner->HasGroup()) @@ -7297,10 +7299,11 @@ void Bot::ProcessClientZoneChange(Client* botOwner) { if(tempBot) { if(tempBot->HasGroup()) { Group* g = tempBot->GetGroup(); - if(g && g->GetLeader()) { - Mob* tempGroupLeader = tempBot->GetGroup()->GetLeader(); - if(tempGroupLeader && tempGroupLeader->IsClient()) { - if(tempBot->GetBotOwnerCharacterID() == tempGroupLeader->CastToClient()->CharacterID()) + if(g && g->IsGroupMember(botOwner)) { + if(botOwner && botOwner->IsClient()) { + // Modified to not only zone bots if you're the leader. + // Also zone bots of the non-leader when they change zone. + if(tempBot->GetBotOwnerCharacterID() == botOwner->CharacterID() && g->IsGroupMember(botOwner)) tempBot->Zone(); else tempBot->Camp(); diff --git a/zone/bot_database.cpp b/zone/bot_database.cpp index 033984a93..d8511c54c 100644 --- a/zone/bot_database.cpp +++ b/zone/bot_database.cpp @@ -2459,9 +2459,10 @@ bool BotDatabase::LoadBotGroupsListByOwnerID(const uint32 owner_id, std::list& group_list) +// added owner ID to this function to fix groups with mulitple players grouped with bots. +bool BotDatabase::LoadGroupedBotsByGroupID(const uint32 owner_id, const uint32 group_id, std::list& group_list) { - if (!group_id) + if (!group_id || !owner_id) return false; query = StringFormat( @@ -2471,18 +2472,10 @@ bool BotDatabase::LoadGroupedBotsByGroupID(const uint32 group_id, std::list& group_list); + bool LoadGroupedBotsByGroupID(const uint32 owner_id, const uint32 group_id, std::list& group_list); /* Bot heal rotation functions */ From 21d3e5afacf32ebccb647694b5f266238a25ac24 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 13 Apr 2017 16:05:10 -0700 Subject: [PATCH 2/5] Adding AutoXTarget for bot owner when hate is added to bot's owner. Bots did not add XTargets, but add hate to client(). This ensures when bots generate hate for client() they also add the mob to the XTarget of the owning Client(). --- zone/attack.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/zone/attack.cpp b/zone/attack.cpp index 47e082747..37cdff710 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -2541,8 +2541,10 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b AddFeignMemory(other->CastToBot()->GetBotOwner()->CastToClient()); } else { - if(!hate_list.IsEntOnHateList(other->CastToBot()->GetBotOwner())) + if (!hate_list.IsEntOnHateList(other->CastToBot()->GetBotOwner())) { hate_list.AddEntToHateList(other->CastToBot()->GetBotOwner(), 0, 0, false, true); + other->CastToBot()->GetBotOwner()->CastToClient()->AddAutoXTarget(this); + } } } #endif //BOTS From cb8c3595b7f1dfe03e67ac68d0dd9a9083c49d9b Mon Sep 17 00:00:00 2001 From: E Spause Date: Mon, 13 Mar 2017 15:07:56 -0400 Subject: [PATCH 3/5] SoF-era con system. New rule, UseOldConSystem to disable this functionality. --- common/ruletypes.h | 2 + zone/aggro.cpp | 12 +- zone/attack.cpp | 2 +- zone/client.cpp | 2 +- zone/client_packet.cpp | 23 ++- zone/common.h | 4 +- zone/exp.cpp | 15 +- zone/fearpath.cpp | 5 +- zone/merc.cpp | 8 +- zone/mob.h | 2 +- zone/mob_ai.cpp | 353 +++++++++++++++++++++++------------------ 11 files changed, 259 insertions(+), 169 deletions(-) diff --git a/common/ruletypes.h b/common/ruletypes.h index a902109c3..e9599e09b 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -56,6 +56,7 @@ RULE_REAL(Character, GroupExpMultiplier, 0.5) RULE_REAL(Character, RaidExpMultiplier, 0.2) RULE_BOOL(Character, UseXPConScaling, true) RULE_INT(Character, ShowExpValues, 0) //0 - normal, 1 - Show raw experience values, 2 - Show raw experience values AND percent. +RULE_INT(Character, GreenModifier, 20) RULE_INT(Character, LightBlueModifier, 40) RULE_INT(Character, BlueModifier, 90) RULE_INT(Character, WhiteModifier, 100) @@ -149,6 +150,7 @@ RULE_INT(Character, AvoidanceCap, 750) // 750 Is a pretty good value, seen peopl RULE_BOOL(Character, AllowMQTarget, false) // Disables putting players in the 'hackers' list for targeting beyond the clip plane or attempting to target something untargetable RULE_BOOL(Character, UseOldBindWound, false) // Uses the original bind wound behavior RULE_BOOL(Character, GrantHoTTOnCreate, false) // Grant Health of Target's Target leadership AA on character creation +RULE_BOOL(Character, UseOldConSystem, false) // Grant Health of Target's Target leadership AA on character creation RULE_CATEGORY_END() RULE_CATEGORY(Mercs) diff --git a/zone/aggro.cpp b/zone/aggro.cpp index 0e9009072..06c78c999 100644 --- a/zone/aggro.cpp +++ b/zone/aggro.cpp @@ -158,7 +158,7 @@ void NPC::DescribeAggro(Client *towho, Mob *mob, bool verbose) { if (RuleB(Aggro, UseLevelAggro)) { - if (GetLevel() < 18 && mob->GetLevelCon(GetLevel()) == CON_GREEN && GetBodyType() != 3) + if (GetLevel() < 18 && mob->GetLevelCon(GetLevel()) == CON_GRAY && GetBodyType() != 3) { towho->Message(0, "...%s is red to me (basically)", mob->GetName(), dist2, iAggroRange2); return; @@ -166,7 +166,7 @@ void NPC::DescribeAggro(Client *towho, Mob *mob, bool verbose) { } else { - if(GetINT() > RuleI(Aggro, IntAggroThreshold) && mob->GetLevelCon(GetLevel()) == CON_GREEN ) { + if(GetINT() > RuleI(Aggro, IntAggroThreshold) && mob->GetLevelCon(GetLevel()) == CON_GRAY ) { towho->Message(0, "...%s is red to me (basically)", mob->GetName(), dist2, iAggroRange2); return; @@ -339,7 +339,7 @@ bool Mob::CheckWillAggro(Mob *mob) { ( GetLevel() >= 18 ) ||(GetBodyType() == 3) ||( mob->IsClient() && mob->CastToClient()->IsSitting() ) - ||( mob->GetLevelCon(GetLevel()) != CON_GREEN ) + ||( mob->GetLevelCon(GetLevel()) != CON_GRAY) ) && @@ -372,7 +372,7 @@ bool Mob::CheckWillAggro(Mob *mob) { ( ( GetINT() <= RuleI(Aggro, IntAggroThreshold) ) ||( mob->IsClient() && mob->CastToClient()->IsSitting() ) - ||( mob->GetLevelCon(GetLevel()) != CON_GREEN ) + ||( mob->GetLevelCon(GetLevel()) != CON_GRAY) ) && @@ -443,7 +443,7 @@ int EntityList::GetHatedCount(Mob *attacker, Mob *exclude) if (mob->IsFeared() || mob->IsMezzed()) continue; - if (attacker->GetLevelCon(mob->GetLevel()) == CON_GREEN) + if (attacker->GetLevelCon(mob->GetLevel()) == CON_GRAY) continue; if (!mob->CheckAggro(attacker)) @@ -502,7 +502,7 @@ void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) { { //if they are in range, make sure we are not green... //then jump in if they are our friend - if(mob->GetLevel() >= 50 || attacker->GetLevelCon(mob->GetLevel()) != CON_GREEN) + if(mob->GetLevel() >= 50 || attacker->GetLevelCon(mob->GetLevel()) != CON_GRAY) { bool useprimfaction = false; if(mob->GetPrimaryFaction() == sender->CastToNPC()->GetPrimaryFaction()) diff --git a/zone/attack.cpp b/zone/attack.cpp index 37cdff710..30526335d 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -2247,7 +2247,7 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQEmu::skills::Skil else { if (!IsLdonTreasure && MerchantType == 0) { int conlevel = give_exp->GetLevelCon(GetLevel()); - if (conlevel != CON_GREEN) { + if (conlevel != CON_GRAY) { if (!GetOwner() || (GetOwner() && !GetOwner()->IsClient())) { give_exp_client->AddEXP((finalxp), conlevel); if (killer_mob && (killer_mob->GetID() == give_exp_client->GetID() || killer_mob->GetUltimateOwner()->GetID() == give_exp_client->GetID())) diff --git a/zone/client.cpp b/zone/client.cpp index ca7df4643..5215db5ae 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -2344,7 +2344,7 @@ bool Client::CheckIncreaseSkill(EQEmu::skills::SkillType skillid, Mob *against_w if(against_who) { if(against_who->GetSpecialAbility(IMMUNE_AGGRO) || against_who->IsClient() || - GetLevelCon(against_who->GetLevel()) == CON_GREEN) + GetLevelCon(against_who->GetLevel()) == CON_GRAY) { //false by default if( !mod_can_increase_skill(skillid, against_who) ) { return(false); } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index c0fb14285..9e9047684 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4756,12 +4756,22 @@ void Client::Handle_OP_Consider(const EQApplicationPacket *app) else con->faction = 1; con->level = GetLevelCon(tmob->GetLevel()); + + if (ClientVersion() <= EQEmu::versions::ClientVersion::Titanium) { + if (con->level == CON_GRAY) { + con->level = CON_GREEN; + } + if (con->level == CON_WHITE) { + con->level = CON_WHITE_TITANIUM; + } + } + if (zone->IsPVPZone()) { if (!tmob->IsNPC()) con->pvpcon = tmob->CastToClient()->GetPVP(); } - // Mongrel: If we're feigned show NPC as indifferent + // If we're feigned show NPC as indifferent if (tmob->IsNPC()) { if (GetFeigned()) @@ -4807,6 +4817,7 @@ void Client::Handle_OP_Consider(const EQApplicationPacket *app) case CON_BLUE: color = 4; break; + case CON_WHITE_TITANIUM: case CON_WHITE: color = 10; break; @@ -4816,7 +4827,17 @@ void Client::Handle_OP_Consider(const EQApplicationPacket *app) case CON_RED: color = 13; break; + case CON_GRAY: + color = 6; + break; } + + if (ClientVersion() <= EQEmu::versions::ClientVersion::Titanium) { + if (color == 6) { + color = 2; + } + } + SendColoredText(color, std::string("This creature would take an army to defeat!")); } safe_delete(outapp); diff --git a/zone/common.h b/zone/common.h index 2ed076b6f..f1f965740 100644 --- a/zone/common.h +++ b/zone/common.h @@ -31,9 +31,11 @@ #define CON_GREEN 2 #define CON_LIGHTBLUE 18 #define CON_BLUE 4 -#define CON_WHITE 20 +#define CON_WHITE 10 +#define CON_WHITE_TITANIUM 20 #define CON_YELLOW 15 #define CON_RED 13 +#define CON_GRAY 6 #define DMG_BLOCKED -1 #define DMG_PARRIED -2 diff --git a/zone/exp.cpp b/zone/exp.cpp index 3dce744f5..044a102e0 100644 --- a/zone/exp.cpp +++ b/zone/exp.cpp @@ -101,9 +101,12 @@ uint32 Client::CalcEXP(uint8 conlevel) { if (conlevel != 0xFF) { switch (conlevel) { - case CON_GREEN: + case CON_GRAY: in_add_exp = 0; return 0; + case CON_GREEN: + in_add_exp = in_add_exp * RuleI(Character, GreenModifier) / 100; + break; case CON_LIGHTBLUE: in_add_exp = in_add_exp * RuleI(Character, LightBlueModifier)/100; break; @@ -206,10 +209,14 @@ void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) { if (conlevel != 0xFF && !resexp) { switch (conlevel) { - case CON_GREEN: + case CON_GRAY: add_exp = 0; add_aaxp = 0; return; + case CON_GREEN: + add_exp = add_exp * RuleI(Character, GreenModifier) / 100; + add_aaxp = add_aaxp * RuleI(Character, GreenModifier) / 100; + break; case CON_LIGHTBLUE: add_exp = add_exp * RuleI(Character, LightBlueModifier)/100; add_aaxp = add_aaxp * RuleI(Character, LightBlueModifier)/100; @@ -798,7 +805,7 @@ void Group::SplitExp(uint32 exp, Mob* other) { groupexp += (uint32)((float)exp * groupmod * (RuleR(Character, GroupExpMultiplier))); int conlevel = Mob::GetLevelCon(maxlevel, other->GetLevel()); - if(conlevel == CON_GREEN) + if(conlevel == CON_GRAY) return; //no exp for greenies... if (membercount == 0) @@ -845,7 +852,7 @@ void Raid::SplitExp(uint32 exp, Mob* other) { groupexp = (uint32)((float)groupexp * (1.0f-(RuleR(Character, RaidExpMultiplier)))); int conlevel = Mob::GetLevelCon(maxlevel, other->GetLevel()); - if(conlevel == CON_GREEN) + if(conlevel == CON_GRAY) return; //no exp for greenies... if (membercount == 0) diff --git a/zone/fearpath.cpp b/zone/fearpath.cpp index 10af1e3a2..ea5bb16d9 100644 --- a/zone/fearpath.cpp +++ b/zone/fearpath.cpp @@ -72,9 +72,12 @@ void Mob::CheckFlee() { float run_ratio; switch(con) { //these values are not 100% researched - case CON_GREEN: + case CON_GRAY: run_ratio = fleeratio; break; + case CON_GREEN: + run_ratio = fleeratio * 9 / 10; + break; case CON_LIGHTBLUE: run_ratio = fleeratio * 9 / 10; break; diff --git a/zone/merc.cpp b/zone/merc.cpp index ae68c1007..61e639125 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -4293,8 +4293,14 @@ bool Merc::CheckConfidence() { CurrentCon = this->GetLevelCon(mob->GetLevel()); switch(CurrentCon) { - case CON_GREEN: { + + case CON_GRAY: { ConRating = 0; + break; + } + + case CON_GREEN: { + ConRating = 0.1; break; } diff --git a/zone/mob.h b/zone/mob.h index 7e3535a73..4d43a9572 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -531,7 +531,7 @@ public: //AI static uint32 GetLevelCon(uint8 mylevel, uint8 iOtherLevel); inline uint32 GetLevelCon(uint8 iOtherLevel) const { - return this ? GetLevelCon(GetLevel(), iOtherLevel) : CON_GREEN; } + return this ? GetLevelCon(GetLevel(), iOtherLevel) : CON_GRAY; } virtual void AddToHateList(Mob* other, uint32 hate = 0, int32 damage = 0, bool iYellForHelp = true, bool bFrenzy = false, bool iBuffTic = false, uint16 spell_id = SPELL_UNKNOWN); bool RemoveFromHateList(Mob* mob); diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 798b5f2bd..58f8b3505 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -2032,166 +2032,215 @@ void Mob::AreaRampage(ExtraAttackOptions *opts) } uint32 Mob::GetLevelCon(uint8 mylevel, uint8 iOtherLevel) { - int16 diff = iOtherLevel - mylevel; - uint32 conlevel=0; - if (diff == 0) - return CON_WHITE; - else if (diff >= 1 && diff <= 2) - return CON_YELLOW; - else if (diff >= 3) - return CON_RED; + uint32 conlevel = 0; - if (mylevel <= 8) + if (RuleB(Character, UseOldConSystem)) { - if (diff <= -4) - conlevel = CON_GREEN; + int16 diff = iOtherLevel - mylevel; + + if (diff == 0) + return CON_WHITE; + else if (diff >= 1 && diff <= 2) + return CON_YELLOW; + else if (diff >= 3) + return CON_RED; + + if (mylevel <= 8) + { + if (diff <= -4) + conlevel = CON_GRAY; + else + conlevel = CON_BLUE; + } + else if (mylevel <= 9) + { + if (diff <= -6) + conlevel = CON_GRAY; + else if (diff <= -4) + conlevel = CON_LIGHTBLUE; + else + conlevel = CON_BLUE; + } + else if (mylevel <= 13) + { + if (diff <= -7) + conlevel = CON_GRAY; + else if (diff <= -5) + conlevel = CON_LIGHTBLUE; + else + conlevel = CON_BLUE; + } + else if (mylevel <= 15) + { + if (diff <= -7) + conlevel = CON_GRAY; + else if (diff <= -5) + conlevel = CON_LIGHTBLUE; + else + conlevel = CON_BLUE; + } + else if (mylevel <= 17) + { + if (diff <= -8) + conlevel = CON_GRAY; + else if (diff <= -6) + conlevel = CON_LIGHTBLUE; + else + conlevel = CON_BLUE; + } + else if (mylevel <= 21) + { + if (diff <= -9) + conlevel = CON_GRAY; + else if (diff <= -7) + conlevel = CON_LIGHTBLUE; + else + conlevel = CON_BLUE; + } + else if (mylevel <= 25) + { + if (diff <= -10) + conlevel = CON_GRAY; + else if (diff <= -8) + conlevel = CON_LIGHTBLUE; + else + conlevel = CON_BLUE; + } + else if (mylevel <= 29) + { + if (diff <= -11) + conlevel = CON_GRAY; + else if (diff <= -9) + conlevel = CON_LIGHTBLUE; + else + conlevel = CON_BLUE; + } + else if (mylevel <= 31) + { + if (diff <= -12) + conlevel = CON_GRAY; + else if (diff <= -9) + conlevel = CON_LIGHTBLUE; + else + conlevel = CON_BLUE; + } + else if (mylevel <= 33) + { + if (diff <= -13) + conlevel = CON_GRAY; + else if (diff <= -10) + conlevel = CON_LIGHTBLUE; + else + conlevel = CON_BLUE; + } + else if (mylevel <= 37) + { + if (diff <= -14) + conlevel = CON_GRAY; + else if (diff <= -11) + conlevel = CON_LIGHTBLUE; + else + conlevel = CON_BLUE; + } + else if (mylevel <= 41) + { + if (diff <= -16) + conlevel = CON_GRAY; + else if (diff <= -12) + conlevel = CON_LIGHTBLUE; + else + conlevel = CON_BLUE; + } + else if (mylevel <= 45) + { + if (diff <= -17) + conlevel = CON_GRAY; + else if (diff <= -13) + conlevel = CON_LIGHTBLUE; + else + conlevel = CON_BLUE; + } + else if (mylevel <= 49) + { + if (diff <= -18) + conlevel = CON_GRAY; + else if (diff <= -14) + conlevel = CON_LIGHTBLUE; + else + conlevel = CON_BLUE; + } + else if (mylevel <= 53) + { + if (diff <= -19) + conlevel = CON_GRAY; + else if (diff <= -15) + conlevel = CON_LIGHTBLUE; + else + conlevel = CON_BLUE; + } + else if (mylevel <= 55) + { + if (diff <= -20) + conlevel = CON_GRAY; + else if (diff <= -15) + conlevel = CON_LIGHTBLUE; + else + conlevel = CON_BLUE; + } else - conlevel = CON_BLUE; - } - else if (mylevel <= 9) - { - if (diff <= -6) - conlevel = CON_GREEN; - else if (diff <= -4) - conlevel = CON_LIGHTBLUE; - else - conlevel = CON_BLUE; - } - else if (mylevel <= 13) - { - if (diff <= -7) - conlevel = CON_GREEN; - else if (diff <= -5) - conlevel = CON_LIGHTBLUE; - else - conlevel = CON_BLUE; - } - else if (mylevel <= 15) - { - if (diff <= -7) - conlevel = CON_GREEN; - else if (diff <= -5) - conlevel = CON_LIGHTBLUE; - else - conlevel = CON_BLUE; - } - else if (mylevel <= 17) - { - if (diff <= -8) - conlevel = CON_GREEN; - else if (diff <= -6) - conlevel = CON_LIGHTBLUE; - else - conlevel = CON_BLUE; - } - else if (mylevel <= 21) - { - if (diff <= -9) - conlevel = CON_GREEN; - else if (diff <= -7) - conlevel = CON_LIGHTBLUE; - else - conlevel = CON_BLUE; - } - else if (mylevel <= 25) - { - if (diff <= -10) - conlevel = CON_GREEN; - else if (diff <= -8) - conlevel = CON_LIGHTBLUE; - else - conlevel = CON_BLUE; - } - else if (mylevel <= 29) - { - if (diff <= -11) - conlevel = CON_GREEN; - else if (diff <= -9) - conlevel = CON_LIGHTBLUE; - else - conlevel = CON_BLUE; - } - else if (mylevel <= 31) - { - if (diff <= -12) - conlevel = CON_GREEN; - else if (diff <= -9) - conlevel = CON_LIGHTBLUE; - else - conlevel = CON_BLUE; - } - else if (mylevel <= 33) - { - if (diff <= -13) - conlevel = CON_GREEN; - else if (diff <= -10) - conlevel = CON_LIGHTBLUE; - else - conlevel = CON_BLUE; - } - else if (mylevel <= 37) - { - if (diff <= -14) - conlevel = CON_GREEN; - else if (diff <= -11) - conlevel = CON_LIGHTBLUE; - else - conlevel = CON_BLUE; - } - else if (mylevel <= 41) - { - if (diff <= -16) - conlevel = CON_GREEN; - else if (diff <= -12) - conlevel = CON_LIGHTBLUE; - else - conlevel = CON_BLUE; - } - else if (mylevel <= 45) - { - if (diff <= -17) - conlevel = CON_GREEN; - else if (diff <= -13) - conlevel = CON_LIGHTBLUE; - else - conlevel = CON_BLUE; - } - else if (mylevel <= 49) - { - if (diff <= -18) - conlevel = CON_GREEN; - else if (diff <= -14) - conlevel = CON_LIGHTBLUE; - else - conlevel = CON_BLUE; - } - else if (mylevel <= 53) - { - if (diff <= -19) - conlevel = CON_GREEN; - else if (diff <= -15) - conlevel = CON_LIGHTBLUE; - else - conlevel = CON_BLUE; - } - else if (mylevel <= 55) - { - if (diff <= -20) - conlevel = CON_GREEN; - else if (diff <= -15) - conlevel = CON_LIGHTBLUE; - else - conlevel = CON_BLUE; + { + if (diff <= -21) + else if (diff <= -16) + conlevel = CON_LIGHTBLUE; + else + conlevel = CON_BLUE; + } } else { - if (diff <= -21) - conlevel = CON_GREEN; - else if (diff <= -16) - conlevel = CON_LIGHTBLUE; + int16 diff = iOtherLevel - mylevel; + uint32 conGrayLvl = mylevel - (int32)((mylevel + 5) / 3); + uint32 conGreenLvl = mylevel - (int32)((mylevel + 7) / 4); + + if (diff == 0) + return CON_WHITE; + else if (diff >= 1 && diff <= 3) + return CON_YELLOW; + else if (diff >= 4) + return CON_RED; + + if (mylevel <= 15) + { + if (diff <= -6) + conlevel = CON_GRAY; + else + conlevel = CON_BLUE; + } else - conlevel = CON_BLUE; + if (mylevel <= 20) + { + if (iOtherLevel <= conGrayLvl) + conlevel = CON_GRAY; + else + if (iOtherLevel <= conGreenLvl) + conlevel = CON_GREEN; + else + conlevel = CON_BLUE; + } + else + { + if (iOtherLevel <= conGrayLvl) + conlevel = CON_GRAY; + else + if (iOtherLevel <= conGreenLvl) + conlevel = CON_GREEN; + else + if (diff <= -6) + conlevel = CON_LIGHTBLUE; + else + conlevel = CON_BLUE; + } } return conlevel; } From 1f065d7d3d9be5442dd796025c984f6d1617054c Mon Sep 17 00:00:00 2001 From: E Spause Date: Mon, 13 Mar 2017 15:08:20 -0400 Subject: [PATCH 4/5] Woops --- zone/mob_ai.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 58f8b3505..53b51b816 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -2191,6 +2191,7 @@ uint32 Mob::GetLevelCon(uint8 mylevel, uint8 iOtherLevel) { else { if (diff <= -21) + conlevel = CON_GRAY; else if (diff <= -16) conlevel = CON_LIGHTBLUE; else From 7cedbb0b16b02f73492c6843866e0260b95d7dc0 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sat, 15 Apr 2017 14:31:36 -0400 Subject: [PATCH 5/5] Take into account world object's item if it has one for TS This might break some pre-existing combines ... --- zone/tradeskills.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/zone/tradeskills.cpp b/zone/tradeskills.cpp index ab9167a4b..262f46234 100644 --- a/zone/tradeskills.cpp +++ b/zone/tradeskills.cpp @@ -272,6 +272,12 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob c_type = worldo->m_type; inst = worldo->m_inst; worldcontainer=true; + // if we're a world container with an item, use that too + if (inst) { + const EQEmu::ItemData* item = inst->GetItem(); + if (item) + some_id = item->ID; + } } else { inst = user_inv.GetItem(in_combine->container_slot);