From bf4ff036413c3e3ff49e09109c0aace4ad187c02 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Fri, 8 May 2015 00:59:38 -0400 Subject: [PATCH] Use PlayerState to generate stun particles --- zone/bot.cpp | 11 ++++------- zone/client_packet.cpp | 1 - zone/client_process.cpp | 12 +++++------- zone/common.h | 14 +++++++++++++- zone/merc.cpp | 5 +---- zone/mob.cpp | 31 +++++++++++++++++++++++++++++-- zone/mob.h | 10 ++++++---- zone/npc.cpp | 15 +++++++-------- zone/spells.cpp | 5 +++-- 9 files changed, 68 insertions(+), 36 deletions(-) diff --git a/zone/bot.cpp b/zone/bot.cpp index ea48727ec..ba7624158 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -2858,10 +2858,7 @@ void Bot::SaveTimers() { bool Bot::Process() { if(IsStunned() && stunned_timer.Check()) - { - this->stunned = false; - this->stunned_timer.Disable(); - } + Mob::UnStun(); if(!GetBotOwner()) return false; @@ -11719,11 +11716,11 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) { const char* equipped[EmuConstants::EQUIPMENT_SIZE] = {"Charm", "Left Ear", "Head", "Face", "Right Ear", "Neck", "Shoulders", "Arms", "Back", "Left Wrist", "Right Wrist", "Range", "Hands", "Primary Hand", "Secondary Hand", "Left Finger", "Right Finger", "Chest", "Legs", "Feet", "Waist", "Ammo" }; - + const ItemInst* inst = nullptr; const Item_Struct* item = nullptr; bool is2Hweapon = false; - + std::string item_link; Client::TextLink linker; linker.SetLinkType(linker.linkItemInst); @@ -11753,7 +11750,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) { // I could not find a difference between the criteria positive code and the criteria negative code.. // ..so, I deleted the check (old criteria: i = { MainCharm, MainRange, MainPrimary, MainSecondary, MainAmmo }) - + linker.SetItemInst(inst); item_link = linker.GenerateLink(); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 317530110..73d028e68 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -10347,7 +10347,6 @@ void Client::Handle_OP_PlayerStateRemove(const EQApplicationPacket *app) PlayerState_Struct *ps = (PlayerState_Struct *)app->pBuffer; RemovePlayerState(ps->state); - // We should probably save it server side, but for now this works entity_list.QueueClients(this, app, true); } diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 40e8e6d1b..42681340b 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -197,10 +197,8 @@ bool Client::Process() { instalog = true; } - if (IsStunned() && stunned_timer.Check()) { - this->stunned = false; - this->stunned_timer.Disable(); - } + if (IsStunned() && stunned_timer.Check()) + Mob::UnStun(); if(!m_CheatDetectMoved) { @@ -262,7 +260,7 @@ bool Client::Process() { } if(light_update_timer.Check()) { - + UpdateEquipmentLight(); if(UpdateActiveLight()) { SendAppearancePacket(AT_Light, GetActiveLightType()); @@ -562,7 +560,7 @@ bool Client::Process() { } ProjectileAttack(); - + if(spellbonuses.GravityEffect == 1) { if(gravity_timer.Check()) DoGravityEffect(); @@ -793,7 +791,7 @@ void Client::OnDisconnect(bool hard_disconnect) { Mob *Other = trade->With(); if(Other) { - Log.Out(Logs::Detail, Logs::Trading, "Client disconnected during a trade. Returning their items."); + Log.Out(Logs::Detail, Logs::Trading, "Client disconnected during a trade. Returning their items."); FinishTrade(this); if(Other->IsClient()) diff --git a/zone/common.h b/zone/common.h index 56ab6f819..a7d9e2d99 100644 --- a/zone/common.h +++ b/zone/common.h @@ -173,6 +173,18 @@ enum class NumHit { // Numhits type OffensiveSpellProcs = 11 // Offensive buff procs }; +enum class PlayerState : uint32 { + None = 0, + Open = 1, + WeaponSheathed = 2, + Aggressive = 4, + ForcedAggressive = 8, + InstrumentEquipped = 16, + Stunned = 32, + PrimaryWeaponEquipped = 64, + SecondaryWeaponEquipped = 128 +}; + //this is our internal representation of the BUFF struct, can put whatever we want in it struct Buffs_Struct { uint16 spellid; @@ -438,7 +450,7 @@ struct StatBonuses { int32 ShieldEquipHateMod; // Hate mod when shield equiped. int32 ShieldEquipDmgMod[2]; // Damage mod when shield equiped. 0 = damage modifier 1 = Unknown bool TriggerOnValueAmount; // Triggers off various different conditions, bool to check if client has effect. - int8 StunBashChance; // chance to stun with bash. + int8 StunBashChance; // chance to stun with bash. int8 IncreaseChanceMemwipe; // increases chance to memory wipe int8 CriticalMend; // chance critical monk mend int32 ImprovedReclaimEnergy; // Modifies amount of mana returned from reclaim energy diff --git a/zone/merc.cpp b/zone/merc.cpp index 4609487cf..73f6b1fbf 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -1236,10 +1236,7 @@ void Merc::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) { bool Merc::Process() { if(IsStunned() && stunned_timer.Check()) - { - this->stunned = false; - this->stunned_timer.Disable(); - } + Mob::UnStun(); if (GetDepop()) { diff --git a/zone/mob.cpp b/zone/mob.cpp index 1c4c2a01e..b4c3370cb 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -148,7 +148,7 @@ Mob::Mob(const char* in_name, size = in_size; base_size = size; runspeed = in_runspeed; - PlayerState = 0; + m_PlayerState = 0; // sanity check @@ -916,7 +916,7 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) ns->spawn.class_ = class_; ns->spawn.gender = gender; ns->spawn.level = level; - ns->spawn.PlayerState = PlayerState; + ns->spawn.PlayerState = m_PlayerState; ns->spawn.deity = deity; ns->spawn.animation = 0; ns->spawn.findable = findable?1:0; @@ -5423,3 +5423,30 @@ bool Mob::CanClassEquipItem(uint32 item_id) else return true; } + +void Mob::SendAddPlayerState(PlayerState new_state) +{ + auto app = new EQApplicationPacket(OP_PlayerStateAdd, sizeof(PlayerState_Struct)); + auto ps = (PlayerState_Struct *)app->pBuffer; + + ps->spawn_id = GetID(); + ps->state = static_cast(new_state); + + AddPlayerState(ps->state); + entity_list.QueueClients(nullptr, app); + safe_delete(app); +} + +void Mob::SendRemovePlayerState(PlayerState old_state) +{ + auto app = new EQApplicationPacket(OP_PlayerStateRemove, sizeof(PlayerState_Struct)); + auto ps = (PlayerState_Struct *)app->pBuffer; + + ps->spawn_id = GetID(); + ps->state = static_cast(old_state); + + RemovePlayerState(ps->state); + entity_list.QueueClients(nullptr, app); + safe_delete(app); +} + diff --git a/zone/mob.h b/zone/mob.h index fc5e1d8e0..3b0702e60 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -1026,10 +1026,12 @@ protected: uint32 follow_dist; bool no_target_hotkey; - uint32 PlayerState; - uint32 GetPlayerState() { return PlayerState; } - void AddPlayerState(uint32 new_state) { PlayerState |= new_state; } - void RemovePlayerState(uint32 old_state) { PlayerState &= ~old_state; } + uint32 m_PlayerState; + uint32 GetPlayerState() { return m_PlayerState; } + void AddPlayerState(uint32 new_state) { m_PlayerState |= new_state; } + void RemovePlayerState(uint32 old_state) { m_PlayerState &= ~old_state; } + void SendAddPlayerState(PlayerState new_state); + void SendRemovePlayerState(PlayerState old_state); uint8 gender; uint16 race; diff --git a/zone/npc.cpp b/zone/npc.cpp index 4e69657cd..0ece7ab6c 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -522,7 +522,7 @@ void NPC::QueryLoot(Client* to) linker.SetItemData(item); auto item_link = linker.GenerateLink(); - + to->Message(0, "%s, ID: %u, Level: (min: %u, max: %u)", item_link.c_str(), item->ID, (*cur)->min_level, (*cur)->max_level); } @@ -569,8 +569,7 @@ bool NPC::Process() { if (IsStunned() && stunned_timer.Check()) { - this->stunned = false; - this->stunned_timer.Disable(); + Mob::UnStun(); this->spun_timer.Disable(); } @@ -724,7 +723,7 @@ void NPC::UpdateEquipmentLight() { m_Light.Type.Equipment = 0; m_Light.Level.Equipment = 0; - + for (int index = MAIN_BEGIN; index < EmuConstants::EQUIPMENT_SIZE; ++index) { if (index == MainAmmo) { continue; } @@ -1933,7 +1932,7 @@ void NPC::ModifyNPCStat(const char *identifier, const char *newValue) else if(id == "special_attacks") { NPCSpecialAttacks(val.c_str(), 0, 1); return; } else if(id == "special_abilities") { ProcessSpecialAbilities(val.c_str()); return; } else if(id == "attack_speed") { attack_speed = (float)atof(val.c_str()); CalcBonuses(); return; } - else if(id == "attack_delay") { attack_delay = atoi(val.c_str()); CalcBonuses(); return; } + else if(id == "attack_delay") { attack_delay = atoi(val.c_str()); CalcBonuses(); return; } else if(id == "atk") { ATK = atoi(val.c_str()); return; } else if(id == "accuracy") { accuracy_rating = atoi(val.c_str()); return; } else if(id == "avoidance") { avoidance_rating = atoi(val.c_str()); return; } @@ -2418,7 +2417,7 @@ void NPC::DoQuestPause(Mob *other) { } -void NPC::ChangeLastName(const char* in_lastname) +void NPC::ChangeLastName(const char* in_lastname) { EQApplicationPacket* outapp = new EQApplicationPacket(OP_GMLastName, sizeof(GMLastName_Struct)); @@ -2468,9 +2467,9 @@ void NPC::DepopSwarmPets() } if (IsPet() && GetPetType() == petTargetLock && GetPetTargetLockID()){ - + Mob *targMob = entity_list.GetMob(GetPetTargetLockID()); - + if(!targMob || (targMob && targMob->IsCorpse())){ Kill(); return; diff --git a/zone/spells.cpp b/zone/spells.cpp index 472a0ac9f..d93050746 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -4708,7 +4708,7 @@ void Mob::Stun(int duration) { stunned = true; stunned_timer.Start(duration); - SendStunAppearance(); + SendAddPlayerState(PlayerState::Stunned); } } @@ -4716,6 +4716,7 @@ void Mob::UnStun() { if(stunned && stunned_timer.Enabled()) { stunned = false; stunned_timer.Disable(); + SendRemovePlayerState(PlayerState::Stunned); } } @@ -5259,7 +5260,7 @@ void Client::SendBuffDurationPacket(Buffs_Struct &buff) if (IsEffectInSpell(buff.spellid, SE_TotalHP)) { // If any of the lower 6 bits are set, the GUI changes MAX_HP AGAIN. - // If its set to 0 the effect is cancelled. + // If its set to 0 the effect is cancelled. // 128 seems to work (ie: change only duration). sbf->effect = 128; }