mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-21 01:51:30 +00:00
Refactor loot response a bit
Invis is dropped after ALL error checking now Identified all the response types
This commit is contained in:
parent
3e0af2928b
commit
a64343689c
@ -9177,39 +9177,7 @@ void Client::Handle_OP_LootRequest(const EQApplicationPacket *app)
|
|||||||
if (ent->IsCorpse())
|
if (ent->IsCorpse())
|
||||||
{
|
{
|
||||||
SetLooting(ent->GetID()); //store the entity we are looting
|
SetLooting(ent->GetID()); //store the entity we are looting
|
||||||
Corpse *ent_corpse = ent->CastToCorpse();
|
|
||||||
if (DistanceSquaredNoZ(m_Position, ent_corpse->GetPosition()) > 625)
|
|
||||||
{
|
|
||||||
Message(13, "Corpse too far away.");
|
|
||||||
Corpse::SendLootReqErrorPacket(this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (invisible) {
|
|
||||||
BuffFadeByEffect(SE_Invisibility);
|
|
||||||
BuffFadeByEffect(SE_Invisibility2);
|
|
||||||
invisible = false;
|
|
||||||
}
|
|
||||||
if (invisible_undead) {
|
|
||||||
BuffFadeByEffect(SE_InvisVsUndead);
|
|
||||||
BuffFadeByEffect(SE_InvisVsUndead2);
|
|
||||||
invisible_undead = false;
|
|
||||||
}
|
|
||||||
if (invisible_animals){
|
|
||||||
BuffFadeByEffect(SE_InvisVsAnimals);
|
|
||||||
invisible_animals = false;
|
|
||||||
}
|
|
||||||
if (hidden || improved_hidden){
|
|
||||||
hidden = false;
|
|
||||||
improved_hidden = false;
|
|
||||||
auto outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
|
|
||||||
SpawnAppearance_Struct* sa_out = (SpawnAppearance_Struct*)outapp->pBuffer;
|
|
||||||
sa_out->spawn_id = GetID();
|
|
||||||
sa_out->type = 0x03;
|
|
||||||
sa_out->parameter = 0;
|
|
||||||
entity_list.QueueClients(this, outapp, true);
|
|
||||||
safe_delete(outapp);
|
|
||||||
}
|
|
||||||
ent->CastToCorpse()->MakeLootRequestPackets(this, app);
|
ent->CastToCorpse()->MakeLootRequestPackets(this, app);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -189,6 +189,16 @@ enum class PlayerState : uint32 {
|
|||||||
SecondaryWeaponEquipped = 128
|
SecondaryWeaponEquipped = 128
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class LootResponse : uint8 {
|
||||||
|
SomeoneElse = 0,
|
||||||
|
Normal = 1,
|
||||||
|
NotAtThisTime = 2,
|
||||||
|
Normal2 = 3, // acts exactly the same as Normal, maybe group vs ungroup? No idea
|
||||||
|
Hostiles = 4,
|
||||||
|
TooFar = 5,
|
||||||
|
LootAll = 6 // SoD+
|
||||||
|
};
|
||||||
|
|
||||||
//this is our internal representation of the BUFF struct, can put whatever we want in it
|
//this is our internal representation of the BUFF struct, can put whatever we want in it
|
||||||
struct Buffs_Struct {
|
struct Buffs_Struct {
|
||||||
uint16 spellid;
|
uint16 spellid;
|
||||||
|
|||||||
@ -64,10 +64,10 @@ void Corpse::SendEndLootErrorPacket(Client* client) {
|
|||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Corpse::SendLootReqErrorPacket(Client* client, uint8 response) {
|
void Corpse::SendLootReqErrorPacket(Client* client, LootResponse response) {
|
||||||
auto outapp = new EQApplicationPacket(OP_MoneyOnCorpse, sizeof(moneyOnCorpseStruct));
|
auto outapp = new EQApplicationPacket(OP_MoneyOnCorpse, sizeof(moneyOnCorpseStruct));
|
||||||
moneyOnCorpseStruct* d = (moneyOnCorpseStruct*) outapp->pBuffer;
|
moneyOnCorpseStruct* d = (moneyOnCorpseStruct*) outapp->pBuffer;
|
||||||
d->response = response;
|
d->response = static_cast<uint8>(response);
|
||||||
d->unknown1 = 0x5a;
|
d->unknown1 = 0x5a;
|
||||||
d->unknown2 = 0x40;
|
d->unknown2 = 0x40;
|
||||||
client->QueuePacket(outapp);
|
client->QueuePacket(outapp);
|
||||||
@ -876,7 +876,7 @@ void Corpse::AllowPlayerLoot(Mob *them, uint8 slot) {
|
|||||||
void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* app) {
|
void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* app) {
|
||||||
// Added 12/08. Started compressing loot struct on live.
|
// Added 12/08. Started compressing loot struct on live.
|
||||||
if(player_corpse_depop) {
|
if(player_corpse_depop) {
|
||||||
SendLootReqErrorPacket(client, 0);
|
SendLootReqErrorPacket(client, LootResponse::SomeoneElse);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -888,7 +888,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(is_locked && client->Admin() < 100) {
|
if(is_locked && client->Admin() < 100) {
|
||||||
SendLootReqErrorPacket(client, 0);
|
SendLootReqErrorPacket(client, LootResponse::SomeoneElse);
|
||||||
client->Message(13, "Error: Corpse locked by GM.");
|
client->Message(13, "Error: Corpse locked by GM.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -899,7 +899,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
|||||||
if(this->being_looted_by != 0xFFFFFFFF) {
|
if(this->being_looted_by != 0xFFFFFFFF) {
|
||||||
// lets double check....
|
// lets double check....
|
||||||
Entity* looter = entity_list.GetID(this->being_looted_by);
|
Entity* looter = entity_list.GetID(this->being_looted_by);
|
||||||
if(looter == 0)
|
if(looter == nullptr)
|
||||||
this->being_looted_by = 0xFFFFFFFF;
|
this->being_looted_by = 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -909,8 +909,14 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
|||||||
if(database.GetVariable("LootCoin", tmp))
|
if(database.GetVariable("LootCoin", tmp))
|
||||||
loot_coin = tmp[0] == 1 && tmp[1] == '\0';
|
loot_coin = tmp[0] == 1 && tmp[1] == '\0';
|
||||||
|
|
||||||
if (this->being_looted_by != 0xFFFFFFFF && this->being_looted_by != client->GetID()) {
|
if (DistanceSquaredNoZ(client->GetPosition(), m_Position) > 625) {
|
||||||
SendLootReqErrorPacket(client, 0);
|
SendLootReqErrorPacket(client, LootResponse::TooFar);
|
||||||
|
// not sure if we need to send the packet back in this case? Didn't before!
|
||||||
|
// Will just return for now
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (this->being_looted_by != 0xFFFFFFFF && this->being_looted_by != client->GetID()) {
|
||||||
|
SendLootReqErrorPacket(client, LootResponse::SomeoneElse);
|
||||||
Loot_Request_Type = 0;
|
Loot_Request_Type = 0;
|
||||||
}
|
}
|
||||||
else if (IsPlayerCorpse() && char_id == client->CharacterID()) {
|
else if (IsPlayerCorpse() && char_id == client->CharacterID()) {
|
||||||
@ -931,16 +937,17 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
|||||||
|
|
||||||
if (Loot_Request_Type == 1) {
|
if (Loot_Request_Type == 1) {
|
||||||
if (client->Admin() < 100 || !client->GetGM()) {
|
if (client->Admin() < 100 || !client->GetGM()) {
|
||||||
SendLootReqErrorPacket(client, 2);
|
SendLootReqErrorPacket(client, LootResponse::NotAtThisTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Loot_Request_Type >= 2 || (Loot_Request_Type == 1 && client->Admin() >= 100 && client->GetGM())) {
|
if(Loot_Request_Type >= 2 || (Loot_Request_Type == 1 && client->Admin() >= 100 && client->GetGM())) {
|
||||||
|
client->CommonBreakInvisible(); // we should be "all good" so lets break invis now instead of earlier before all error checking is done
|
||||||
this->being_looted_by = client->GetID();
|
this->being_looted_by = client->GetID();
|
||||||
auto outapp = new EQApplicationPacket(OP_MoneyOnCorpse, sizeof(moneyOnCorpseStruct));
|
auto outapp = new EQApplicationPacket(OP_MoneyOnCorpse, sizeof(moneyOnCorpseStruct));
|
||||||
moneyOnCorpseStruct* d = (moneyOnCorpseStruct*) outapp->pBuffer;
|
moneyOnCorpseStruct* d = (moneyOnCorpseStruct*) outapp->pBuffer;
|
||||||
|
|
||||||
d->response = 1;
|
d->response = static_cast<uint8>(LootResponse::Normal);
|
||||||
d->unknown1 = 0x42;
|
d->unknown1 = 0x42;
|
||||||
d->unknown2 = 0xef;
|
d->unknown2 = 0xef;
|
||||||
|
|
||||||
@ -1052,7 +1059,8 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
|||||||
|
|
||||||
// This is required for the 'Loot All' feature to work for SoD clients. I expect it is to tell the client that the
|
// This is required for the 'Loot All' feature to work for SoD clients. I expect it is to tell the client that the
|
||||||
// server has now sent all the items on the corpse.
|
// server has now sent all the items on the corpse.
|
||||||
if (client->ClientVersion() >= EQEmu::versions::ClientVersion::SoD) { SendLootReqErrorPacket(client, 6); }
|
if (client->ClientVersion() >= EQEmu::versions::ClientVersion::SoD)
|
||||||
|
SendLootReqErrorPacket(client, LootResponse::LootAll);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
||||||
@ -1092,7 +1100,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (is_locked && client->Admin() < 100) {
|
if (is_locked && client->Admin() < 100) {
|
||||||
SendLootReqErrorPacket(client, 0);
|
SendLootReqErrorPacket(client, LootResponse::SomeoneElse);
|
||||||
client->Message(13, "Error: Corpse locked by GM.");
|
client->Message(13, "Error: Corpse locked by GM.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,7 +37,7 @@ class Corpse : public Mob {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
static void SendEndLootErrorPacket(Client* client);
|
static void SendEndLootErrorPacket(Client* client);
|
||||||
static void SendLootReqErrorPacket(Client* client, uint8 response = 2);
|
static void SendLootReqErrorPacket(Client* client, LootResponse response = LootResponse::NotAtThisTime);
|
||||||
|
|
||||||
Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NPCType** in_npctypedata, uint32 in_decaytime = 600000);
|
Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NPCType** in_npctypedata, uint32 in_decaytime = 600000);
|
||||||
Corpse(Client* client, int32 in_rezexp);
|
Corpse(Client* client, int32 in_rezexp);
|
||||||
|
|||||||
17
zone/mob.cpp
17
zone/mob.cpp
@ -5854,6 +5854,23 @@ int Mob::CheckBaneDamage(const ItemInst *item)
|
|||||||
return damage;
|
return damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mob::CommonBreakInvisible()
|
||||||
|
{
|
||||||
|
BreakInvisibleSpells();
|
||||||
|
|
||||||
|
if (hidden || improved_hidden) {
|
||||||
|
hidden = false;
|
||||||
|
improved_hidden = false;
|
||||||
|
auto outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
|
||||||
|
SpawnAppearance_Struct* sa_out = (SpawnAppearance_Struct*)outapp->pBuffer;
|
||||||
|
sa_out->spawn_id = GetID();
|
||||||
|
sa_out->type = 0x03;
|
||||||
|
sa_out->parameter = 0;
|
||||||
|
entity_list.QueueClients(this, outapp, true);
|
||||||
|
safe_delete(outapp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
bool Mob::JoinHealRotationTargetPool(std::shared_ptr<HealRotation>* heal_rotation)
|
bool Mob::JoinHealRotationTargetPool(std::shared_ptr<HealRotation>* heal_rotation)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -173,6 +173,7 @@ public:
|
|||||||
void RogueEvade(Mob *other);
|
void RogueEvade(Mob *other);
|
||||||
void CommonOutgoingHitSuccess(Mob* defender, int32 &damage, EQEmu::skills::SkillType skillInUse, ExtraAttackOptions *opts = nullptr);
|
void CommonOutgoingHitSuccess(Mob* defender, int32 &damage, EQEmu::skills::SkillType skillInUse, ExtraAttackOptions *opts = nullptr);
|
||||||
void BreakInvisibleSpells();
|
void BreakInvisibleSpells();
|
||||||
|
void CommonBreakInvisible();
|
||||||
void CommonBreakInvisibleFromCombat();
|
void CommonBreakInvisibleFromCombat();
|
||||||
bool HasDied();
|
bool HasDied();
|
||||||
virtual bool CheckDualWield();
|
virtual bool CheckDualWield();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user