Merge remote-tracking branch 'upstream/master' into Warning_Cleanup

Conflicts:
	zone/client_packet.cpp
This commit is contained in:
Arthur Dene Ice 2014-05-19 22:23:03 -07:00
commit a5020ad844
12 changed files with 145 additions and 68 deletions

View File

@ -1,5 +1,12 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 05/17/2014 ==
Secrets: Identified the opcode/struct for guild ranks in Rain of Fear+ clients.
Secrets: Implemented a work-around for Rain of Fear clients to have all guild permissions until proper database support is added for newer ranks.
== 05/14/2014 ==
Kayen: Rooted NPC's will no longer target players with Divine Aura effect if they are the closest target and other targets exist on the hate list.
== 05/12/2014 ==
Uleat: Re-arranged functions in Item.cpp to somewhat match the order they are declared in Item.h. Should make finding their location a little easier when using declarations as a guide. (This will facilitate readability of an upcoming change...)

View File

@ -3163,6 +3163,26 @@ struct GuildUpdateURLAndChannel_Struct
/*4176*/
};
//Case 5 in Rain of Fear and higher clients for guild permissions.
//RankID is the internal guild rank. There are 8 in Rain of Fear as opposed to the 3 in Titanium.
//PermissionID is the type of permission. There are 32 total, with some unused. Live May 2014 sends and uses 26 of them. Varies through client version.
//Permission value is a char that is either 0 or 1. Enabled for that rank/disabled for that rank.
//The client sends this struct on changing a guild rank. The server sends each rank in 32 or less packets upon zonein if you are in a guild.
struct GuildUpdateRanks_Struct
{
/*0000*/ uint32 Action; // 0 = Update URL, 1 = Update Channel, 5 = RoF Ranks
/*0004*/ uint32 Unknown0004; //Seen 00 00 00 00
/*0008*/ uint32 Unknown0008; //Seen 96 29 00 00
/*0008*/ char Unknown0012[64]; //Seen "CharacterName"
/*0076*/ uint32 GuildID; //Guild ID of "CharacterName"
/*0080*/ uint32 RankID;
/*0084*/ uint32 PermissionID;
/*0088*/ char PermissionVal;
/*0089*/ char Unknown0089[3]; //Seen 2c 01 00 ?
/*0092*/
};
struct GuildStatus_Struct
{
/*000*/ char Name[64];

View File

@ -0,0 +1 @@
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:FocusCombatProcs', 'false', 'Allow all combat procs to receive focus (ignores focus limit).');

View File

@ -2149,28 +2149,40 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_LimitHPPercent:
{
if(newbon->HPPercCap != 0 && newbon->HPPercCap > effect_value)
newbon->HPPercCap = effect_value;
else if(newbon->HPPercCap == 0)
newbon->HPPercCap = effect_value;
if(newbon->HPPercCap[0] != 0 && newbon->HPPercCap[0] > effect_value){
newbon->HPPercCap[0] = effect_value;
newbon->HPPercCap[1] = base2;
}
else if(newbon->HPPercCap[0] == 0){
newbon->HPPercCap[0] = effect_value;
newbon->HPPercCap[1] = base2;
}
break;
}
case SE_LimitManaPercent:
{
if(newbon->ManaPercCap != 0 && newbon->ManaPercCap > effect_value)
newbon->ManaPercCap = effect_value;
else if(newbon->ManaPercCap == 0)
newbon->ManaPercCap = effect_value;
if(newbon->ManaPercCap[0] != 0 && newbon->ManaPercCap[0] > effect_value){
newbon->ManaPercCap[0] = effect_value;
newbon->ManaPercCap[1] = base2;
}
else if(newbon->ManaPercCap[0] == 0) {
newbon->ManaPercCap[0] = effect_value;
newbon->ManaPercCap[1] = base2;
}
break;
}
case SE_LimitEndPercent:
{
if(newbon->EndPercCap != 0 && newbon->EndPercCap > effect_value)
newbon->EndPercCap = effect_value;
else if(newbon->EndPercCap == 0)
newbon->EndPercCap = effect_value;
if(newbon->EndPercCap[0] != 0 && newbon->EndPercCap[0] > effect_value) {
newbon->EndPercCap[0] = effect_value;
newbon->EndPercCap[1] = base2;
}
else if(newbon->EndPercCap[0] == 0){
newbon->EndPercCap[0] = effect_value;
newbon->EndPercCap[1] = base2;
}
break;
}

View File

@ -10649,10 +10649,10 @@ int32 Bot::CalcMaxHP() {
if (cur_hp > max_hp)
cur_hp = max_hp;
int hp_perc_cap = spellbonuses.HPPercCap;
int hp_perc_cap = spellbonuses.HPPercCap[0];
if(hp_perc_cap) {
int curHP_cap = (max_hp * hp_perc_cap) / 100;
if (cur_hp > curHP_cap)
if (cur_hp > curHP_cap || (spellbonuses.HPPercCap[1] && cur_hp > spellbonuses.HPPercCap[1]))
cur_hp = curHP_cap;
}
@ -10671,10 +10671,10 @@ int32 Bot::CalcMaxEndurance()
cur_end = max_end;
}
int end_perc_cap = spellbonuses.EndPercCap;
int end_perc_cap = spellbonuses.EndPercCap[0];
if(end_perc_cap) {
int curEnd_cap = (max_end * end_perc_cap) / 100;
if (cur_end > curEnd_cap)
if (cur_end > curEnd_cap || (spellbonuses.EndPercCap[1] && cur_end > spellbonuses.EndPercCap[1]))
cur_end = curEnd_cap;
}

View File

@ -621,6 +621,7 @@ public:
void SendGuildURL();
void SendGuildChannel();
void SendGuildSpawnAppearance();
void SendGuildRanks();
void SendGuildMembers();
void SendGuildList();
void SendGuildJoin(GuildJoin_Struct* gj);

View File

@ -255,10 +255,10 @@ int32 Client::CalcMaxHP() {
if (cur_hp > max_hp)
cur_hp = max_hp;
int hp_perc_cap = spellbonuses.HPPercCap;
int hp_perc_cap = spellbonuses.HPPercCap[0];
if(hp_perc_cap) {
int curHP_cap = (max_hp * hp_perc_cap) / 100;
if (cur_hp > curHP_cap)
if (cur_hp > curHP_cap || (spellbonuses.HPPercCap[1] && cur_hp > spellbonuses.HPPercCap[1]))
cur_hp = curHP_cap;
}
@ -950,10 +950,10 @@ int32 Client::CalcMaxMana()
cur_mana = max_mana;
}
int mana_perc_cap = spellbonuses.ManaPercCap;
int mana_perc_cap = spellbonuses.ManaPercCap[0];
if(mana_perc_cap) {
int curMana_cap = (max_mana * mana_perc_cap) / 100;
if (cur_mana > curMana_cap)
if (cur_mana > curMana_cap || (spellbonuses.ManaPercCap[1] && cur_mana > spellbonuses.ManaPercCap[1]))
cur_mana = curMana_cap;
}
@ -1890,10 +1890,10 @@ void Client::CalcMaxEndurance()
cur_end = max_end;
}
int end_perc_cap = spellbonuses.EndPercCap;
int end_perc_cap = spellbonuses.EndPercCap[0];
if(end_perc_cap) {
int curEnd_cap = (max_end * end_perc_cap) / 100;
if (cur_end > curEnd_cap)
if (cur_end > curEnd_cap || (spellbonuses.EndPercCap[1] && cur_end > spellbonuses.EndPercCap[1]))
cur_end = curEnd_cap;
}
}

View File

@ -1267,7 +1267,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
PlayerPositionUpdateServer_Struct* ppu = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer;
MakeSpawnUpdate(ppu);
if (gmhideme)
entity_list.QueueClientsStatus(this,outapp,true,(uint8)Admin(),250);
entity_list.QueueClientsStatus(this,outapp,true,Admin(),250);
else
entity_list.QueueCloseClients(this,outapp,true,300,nullptr,false);
safe_delete(outapp);
@ -3416,8 +3416,8 @@ void Client::Handle_OP_Sneak(const EQApplicationPacket *app)
else {
CheckIncreaseSkill(SkillSneak, nullptr, 5);
}
float hidechance = ((GetSkill(SkillSneak)/300.0f) + .25f) * 1000.f;
float random = (float)MakeRandomFloat(0, 99);
float hidechance = ((GetSkill(SkillSneak)/300.0f) + .25) * 100;
float random = MakeRandomFloat(0, 99);
if(!was && random < hidechance) {
sneaking = true;
}
@ -3458,8 +3458,8 @@ void Client::Handle_OP_Hide(const EQApplicationPacket *app)
int reuse = HideReuseTime - GetAA(209);
p_timers.Start(pTimerHide, reuse-1);
float hidechance = ((GetSkill(SkillHide)/250.0f) + .25f) * 100.0f;
float random = (float)MakeRandomFloat(0, 100);
float hidechance = ((GetSkill(SkillHide)/250.0f) + .25) * 100;
float random = MakeRandomFloat(0, 100);
CheckIncreaseSkill(SkillHide, nullptr, 5);
if (random < hidechance) {
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
@ -4010,7 +4010,7 @@ void Client::Handle_OP_GuildManageBanker(const EQApplicationPacket *app)
bool NewBankerStatus = gmb->enabled & 0x01;
bool NewAltStatus = (gmb->enabled & 0x02) != 0;
bool NewAltStatus = gmb->enabled & 0x02;
if((IsCurrentlyABanker != NewBankerStatus) && !guild_mgr.IsGuildLeader(GuildID(), CharacterID()))
{
@ -4668,7 +4668,7 @@ void Client::Handle_OP_DeleteItem(const EQApplicationPacket *app)
if(GetClientVersion() < EQClientSoD)
IntoxicationIncrease = (200 - AlcoholTolerance) * 30 / 200 + 10;
else
IntoxicationIncrease = (int16)((270 - AlcoholTolerance) * 0.111111108 + 10.0);
IntoxicationIncrease = (270 - AlcoholTolerance) * 0.111111108 + 10;
if(IntoxicationIncrease < 0)
IntoxicationIncrease = 1;
@ -5242,7 +5242,7 @@ void Client::Handle_OP_LFGCommand(const EQApplicationPacket *app)
}
LFGFromLevel = lfg->FromLevel;
LFGToLevel = lfg->ToLevel;
LFGMatchFilter = lfg->MatchFilter != 0;
LFGMatchFilter = lfg->MatchFilter;
strcpy(LFGComments, lfg->Comments);
break;
default:
@ -5573,8 +5573,8 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app)
}
if(tmpmer_used && (mp->quantity > prevcharges || item->MaxCharges > 1))
{
if((int32)prevcharges > item->MaxCharges && item->MaxCharges > 1)
mp->quantity =(uint8)item->MaxCharges;
if(prevcharges > item->MaxCharges && item->MaxCharges > 1)
mp->quantity = item->MaxCharges;
else
mp->quantity = prevcharges;
}
@ -5597,9 +5597,9 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app)
int SinglePrice = 0;
if (RuleB(Merchant, UsePriceMod))
SinglePrice = (int)(item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate * Client::CalcPriceMod(tmp, false));
SinglePrice = (item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate * Client::CalcPriceMod(tmp, false));
else
SinglePrice = (int)(item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate);
SinglePrice = (item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate);
if(item->MaxCharges > 1)
mpo->price = SinglePrice;
@ -5801,10 +5801,10 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
if(charges > 0 && (freeslot = zone->SaveTempItem(vendor->CastToNPC()->MerchantType, vendor->GetNPCTypeID(),itemid,charges,true)) > 0){
ItemInst* inst2 = inst->Clone();
if (RuleB(Merchant, UsePriceMod)){
inst2->SetPrice((uint32)(item->Price*(RuleR(Merchant, SellCostMod))*item->SellRate*Client::CalcPriceMod(vendor,false)));
inst2->SetPrice(item->Price*(RuleR(Merchant, SellCostMod))*item->SellRate*Client::CalcPriceMod(vendor,false));
}
else
inst2->SetPrice((uint32)(item->Price*(RuleR(Merchant, SellCostMod))*item->SellRate));
inst2->SetPrice(item->Price*(RuleR(Merchant, SellCostMod))*item->SellRate);
inst2->SetMerchantSlot(freeslot);
uint32 MerchantQuantity = zone->GetTempMerchantQuantity(vendor->GetNPCTypeID(), freeslot);
@ -7970,10 +7970,10 @@ void Client::Handle_OP_GMFind(const EQApplicationPacket *app)
Mob* gt = entity_list.GetMob(request->charname);
if (gt != 0) {
foundplayer->success=1;
foundplayer->x=gt->GetX();
foundplayer->y=gt->GetY();
foundplayer->x=(int32)gt->GetX();
foundplayer->y=(int32)gt->GetY();
foundplayer->z=gt->GetZ();
foundplayer->z=(int32)gt->GetZ();
foundplayer->zoneID=zone->GetZoneID();
}
//Send the packet...
@ -8979,7 +8979,7 @@ bool Client::FinishConnState2(DBAsyncWork* dbaw) {
database.LoadBuffs(this);
uint32 max_slots = GetMaxBuffSlots();
for(uint32 i = 0; i < max_slots; i++) {
for(int i = 0; i < max_slots; i++) {
if(buffs[i].spellid != SPELL_UNKNOWN) {
m_pp.buffs[i].spellid = buffs[i].spellid;
m_pp.buffs[i].bard_modifier = 10;
@ -9134,7 +9134,7 @@ bool Client::FinishConnState2(DBAsyncWork* dbaw) {
m_pp.timeentitledonaccount = database.GetTotalTimeEntitledOnAccount(AccountID()) / 1440;
if(m_pp.RestTimer > (uint32)RuleI(Character, RestRegenTimeToActivate))
if(m_pp.RestTimer > RuleI(Character, RestRegenTimeToActivate))
m_pp.RestTimer = 0;
//This checksum should disappear once dynamic structs are in... each struct strategy will do it
@ -9603,7 +9603,7 @@ void Client::CompleteConnect()
if(IsInAGuild())
{
guild_mgr.SendGuildMemberUpdateToWorld(GetName(), GuildID(), zone->GetZoneID(), (uint32)time(nullptr));
guild_mgr.SendGuildMemberUpdateToWorld(GetName(), GuildID(), zone->GetZoneID(), time(nullptr));
guild_mgr.RequestOnlineGuildMembers(this->CharacterID(), this->GuildID());
}
@ -9798,7 +9798,7 @@ void Client::Handle_OP_BankerChange(const EQApplicationPacket *app)
cp/=10;
m_pp.gold=cp%10;
cp/=10;
m_pp.platinum=(int32)cp;
m_pp.platinum=cp;
cp = static_cast<uint64>(m_pp.copper_bank) +
(static_cast<uint64>(m_pp.silver_bank) * 10) +
@ -9811,7 +9811,7 @@ void Client::Handle_OP_BankerChange(const EQApplicationPacket *app)
cp/=10;
m_pp.gold_bank=cp%10;
cp/=10;
m_pp.platinum_bank=(int32)cp;
m_pp.platinum_bank=cp;
bc->copper=m_pp.copper;
bc->silver=m_pp.silver;
@ -11263,7 +11263,7 @@ void Client::Handle_OP_AdventureMerchantSell(const EQApplicationPacket *app)
}
else
{
if((uint32)inst->GetCharges() < ams_in->charges)
if(inst->GetCharges() < ams_in->charges)
{
ams_in->charges = inst->GetCharges();
}
@ -11475,9 +11475,9 @@ void Client::Handle_OP_SetStartCity(const EQApplicationPacket *app)
if(zoneid == StartCity) {
ValidCity = true;
x = (float)atof(row[2]);
y = (float)atof(row[3]);
z = (float)atof(row[4]);
x = atof(row[2]);
y = atof(row[3]);
z = atof(row[4]);
}
}
@ -11649,7 +11649,7 @@ void Client::Handle_OP_GMSearchCorpse(const EQApplicationPacket *app)
EscSearchString, MaxResults), errbuf, &Result))
{
int NumberOfRows = (int)mysql_num_rows(Result);
int NumberOfRows = mysql_num_rows(Result);
if(NumberOfRows == MaxResults)
Message(clientMessageError, "Your search found too many results; some are not displayed.");
@ -11679,14 +11679,14 @@ void Client::Handle_OP_GMSearchCorpse(const EQApplicationPacket *app)
uint32 ZoneID = atoi(Row[1]);
float CorpseX = (float)atof(Row[2]);
float CorpseY = (float)atof(Row[3]);
float CorpseZ = (float)atof(Row[4]);
float CorpseX = atof(Row[2]);
float CorpseY = atof(Row[3]);
float CorpseZ = atof(Row[4]);
strn0cpy(TimeOfDeath, Row[5], sizeof(TimeOfDeath));
bool CorpseRezzed = atoi(Row[6]) != 0;
bool CorpseBuried = atoi(Row[7]) != 0;
bool CorpseRezzed = atoi(Row[6]);
bool CorpseBuried = atoi(Row[7]);
sprintf(Buffer, "<tr><td>%s</td><td>%s</td><td>%8.0f</td><td>%8.0f</td><td>%8.0f</td><td>%s</td><td>%s</td><td>%s</td></tr>",
CharName, StaticGetZoneName(ZoneID), CorpseX, CorpseY, CorpseZ, TimeOfDeath,
@ -12331,7 +12331,7 @@ void Client::Handle_OP_ClearBlockedBuffs(const EQApplicationPacket *app)
return;
}
bool Pet = app->pBuffer[0] != 0;
bool Pet = app->pBuffer[0];
if(Pet)
PetBlockedBuffs.clear();
@ -12860,7 +12860,7 @@ void Client::Handle_OP_AltCurrencySell(const EQApplicationPacket *app) {
}
else
{
if((uint32)inst->GetCharges() < sell->charges)
if(inst->GetCharges() < sell->charges)
{
sell->charges = inst->GetCharges();
}
@ -13302,7 +13302,7 @@ void Client::Handle_OP_XTargetAutoAddHaters(const EQApplicationPacket *app)
return;
}
XTargetAutoAddHaters = app->ReadUInt8(0) != 0;
XTargetAutoAddHaters = app->ReadUInt8(0);
}
void Client::Handle_OP_ItemPreview(const EQApplicationPacket *app)

View File

@ -310,9 +310,9 @@ struct StatBonuses {
int16 IncreaseBlockChance; // overall block chance modifier
uint16 PersistantCasting; // chance to continue casting through a stun
int XPRateMod; //i
int HPPercCap; //Spell effect that limits you to being healed/regening beyond a % of your max
int ManaPercCap; // ^^
int EndPercCap; // ^^
int HPPercCap[2]; //Spell effect that limits you to being healed/regening beyond a % of your max
int ManaPercCap[2]; // ^^ 0 = % Cap 1 = Flat Amount Cap
int EndPercCap[2]; // ^^
bool BlockNextSpell; // Indicates whether the client can block a spell or not
//uint16 BlockSpellEffect[EFFECT_COUNT]; // Prevents spells with certain effects from landing on you *no longer used
bool ImmuneToFlee; // Bypass the fleeing flag

View File

@ -115,6 +115,42 @@ void Client::SendGuildChannel()
}
}
void Client::SendGuildRanks()
{
if(GetClientVersion() < EQClientRoF)
return;
int permissions = 30 + 1; //Static number of permissions in all EQ clients as of May 2014
int ranks = 8 + 1; // Static number of RoF+ ranks as of May 2014
int j = 1;
int i = 1;
if(IsInAGuild())
{
while(j < ranks)
{
while(i < permissions)
{
EQApplicationPacket *outapp = new EQApplicationPacket(OP_GuildUpdateURLAndChannel, sizeof(GuildUpdateRanks_Struct));
GuildUpdateRanks_Struct *guuacs = (GuildUpdateRanks_Struct*) outapp->pBuffer;
//guuacs->Unknown0008 = this->GuildID();
strncpy(guuacs->Unknown0012, this->GetCleanName(), 64);
guuacs->Action = 5;
guuacs->RankID = j;
guuacs->GuildID = this->GuildID();
guuacs->PermissionID = i;
guuacs->PermissionVal = 1;
guuacs->Unknown0089[0] = 0x2c;
guuacs->Unknown0089[1] = 0x01;
guuacs->Unknown0089[2] = 0x00;
FastQueuePacket(&outapp);
i++;
}
j++;
i = 1;
}
}
}
void Client::SendGuildSpawnAppearance() {
if (!IsInAGuild()) {
// clear guildtag

View File

@ -163,7 +163,7 @@ Mob* HateList::GetClosest(Mob *hater) {
++iterator;
}
if (close == 0 && hater->IsNPC())
if (close == 0 && hater->IsNPC() || close->DivineAura())
close = hater->CastToNPC()->GetHateTop();
return close;

View File

@ -917,10 +917,10 @@ int32 Merc::CalcMaxHP() {
if (cur_hp > max_hp)
cur_hp = max_hp;
int hp_perc_cap = spellbonuses.HPPercCap;
int hp_perc_cap = spellbonuses.HPPercCap[0];
if(hp_perc_cap) {
int curHP_cap = (max_hp * hp_perc_cap) / 100;
if (cur_hp > curHP_cap)
if (cur_hp > curHP_cap || (spellbonuses.HPPercCap[1] && cur_hp > spellbonuses.HPPercCap[1]))
cur_hp = curHP_cap;
}
@ -959,10 +959,10 @@ int32 Merc::CalcMaxMana()
cur_mana = max_mana;
}
int mana_perc_cap = spellbonuses.ManaPercCap;
int mana_perc_cap = spellbonuses.ManaPercCap[0];
if(mana_perc_cap) {
int curMana_cap = (max_mana * mana_perc_cap) / 100;
if (cur_mana > curMana_cap)
if (cur_mana > curMana_cap || (spellbonuses.ManaPercCap[1] && cur_mana > spellbonuses.ManaPercCap[1]))
cur_mana = curMana_cap;
}
@ -1054,10 +1054,10 @@ void Merc::CalcMaxEndurance()
cur_end = max_end;
}
int end_perc_cap = spellbonuses.EndPercCap;
int end_perc_cap = spellbonuses.EndPercCap[0];
if(end_perc_cap) {
int curEnd_cap = (max_end * end_perc_cap) / 100;
if (cur_end > curEnd_cap)
if (cur_end > curEnd_cap || (spellbonuses.EndPercCap[1] && cur_end > spellbonuses.EndPercCap[1]))
cur_end = curEnd_cap;
}
}