From d302d22ce2b27b47a03745e5f8a0b25872ee563d Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Tue, 29 Jun 2021 08:22:20 +0000 Subject: [PATCH] add ability --- server/gameserver/ability.cc | 82 +++++++++++++++++++++++++++++++++++ server/gameserver/ability.h | 21 +++++++++ server/gameserver/creature.cc | 75 ++++++++++---------------------- server/gameserver/creature.h | 8 ++-- server/gameserver/human.cc | 3 +- 5 files changed, 133 insertions(+), 56 deletions(-) create mode 100644 server/gameserver/ability.cc create mode 100644 server/gameserver/ability.h diff --git a/server/gameserver/ability.cc b/server/gameserver/ability.cc new file mode 100644 index 0000000..16f5a13 --- /dev/null +++ b/server/gameserver/ability.cc @@ -0,0 +1,82 @@ +#include "precompile.h" + +#include "ability.h" +#include "metamgr.h" +#include "buff.h" +#include "creature.h" + +float Ability::GetAttrAbs(int attr_id) +{ + float attr_abs_val = GetBuffAttrAbs(attr_id); + if (attr_id == kHAT_Atk || attr_id == kHAT_Def) { + if (owner.Get()) { + Buff* buff = owner.Get()->GetBuffByEffectId(kBET_Car); + if (buff) { + MetaData::Equip* equip_meta = MetaMgr::Instance()->GetEquip(buff->meta->param4); + if (equip_meta) { + switch (attr_id) { + case kHAT_Atk: + { + attr_abs_val += equip_meta->i->atk(); + } + break; + case kHAT_Def: + { + attr_abs_val += equip_meta->i->def(); + } + break; + default: + { + } + break; + } + } + } + } + } + return attr_abs_val; +} + +float Ability::GetAttrRate(int attr_id) +{ + float attr_rate_val = GetBuffAttrRate(attr_id); + return attr_rate_val; +} + +float Ability::GetBuffAttrAbs(int attr_id) +{ + if (IsValidHumanAttr(attr_id)) { + return buff_attr_abs_[attr_id]; + } + return 0; +} + +float Ability::GetBuffAttrRate(int attr_id) +{ + if (IsValidHumanAttr(attr_id)) { + return buff_attr_rate_[attr_id]; + } + return 0; +} + +void Ability::Clear() +{ + buff_attr_abs_ = {}; + buff_attr_rate_ = {}; +} + +float* Ability::GetBuffAttrAbsPtr(int attr_id) +{ + if (!IsValidHumanAttr(attr_id)) { + return nullptr; + } + return &buff_attr_abs_[attr_id]; +} + +float* Ability::GetBuffAttrRatePtr(int attr_id) +{ + if (!IsValidHumanAttr(attr_id)) { + return nullptr; + } + return &buff_attr_rate_[attr_id]; +} diff --git a/server/gameserver/ability.h b/server/gameserver/ability.h new file mode 100644 index 0000000..730bac9 --- /dev/null +++ b/server/gameserver/ability.h @@ -0,0 +1,21 @@ +#pragma once + +#include "weakptr.h" + +class Ability +{ + public: + CreatureWeakPtr owner; + + void Clear(); + float GetAttrAbs(int attr_id); + float GetAttrRate(int attr_id); + float GetBuffAttrAbs(int attr_id); + float GetBuffAttrRate(int attr_id); + float* GetBuffAttrAbsPtr(int attr_id); + float* GetBuffAttrRatePtr(int attr_id); + + private: + std::array buff_attr_abs_ = {}; + std::array buff_attr_rate_ = {}; +}; diff --git a/server/gameserver/creature.cc b/server/gameserver/creature.cc index acdb517..8c84989 100644 --- a/server/gameserver/creature.cc +++ b/server/gameserver/creature.cc @@ -100,8 +100,11 @@ void InternalShot(Creature* c, Creature::Creature():MoveableEntity() { + weak_ptr_chunk_.Set(this); trigger_ = new Trigger(this); trigger_->Init(); + ability_ = std::make_shared(); + ability_->owner = GetWeakPtrRef(); weapons.reserve(MAX_WEAPON_NUM); for (size_t i = 0; i < MAX_WEAPON_NUM; ++i) { auto& weapon = a8::FastAppend(weapons); @@ -117,7 +120,6 @@ Creature::Creature():MoveableEntity() inventory_[i].num = 0; } - weak_ptr_chunk_.Set(this); inventory_[IS_1XSCOPE].num = 1; } @@ -355,8 +357,8 @@ void Creature::AddBuffPostProc(Creature* caster, Buff* buff) void Creature::RecalcBuffAttr() { - buff_attr_abs_ = {}; - buff_attr_rate_ = {}; + CheckAbilityUsed(); + ability_->Clear(); for (auto& buff : buff_list_) { if (buff.meta->i->buff_effect() == kBET_ChgAttr || buff.meta->i->buff_effect() == kBET_Car || @@ -365,9 +367,15 @@ void Creature::RecalcBuffAttr() int calc_type = (int)buff.meta->param2; if (IsValidHumanAttr(attr_type)) { if (calc_type == 1) { - buff_attr_abs_[attr_type] += buff.meta->param3; + float* p = ability_->GetBuffAttrAbsPtr(attr_type); + if (p) { + *p += buff.meta->param3; + } } else if (calc_type == 2) { - buff_attr_rate_[attr_type] += buff.meta->param3; + float* p = ability_->GetBuffAttrRatePtr(attr_type); + if (p) { + *p += buff.meta->param3; + } } } } @@ -396,27 +404,9 @@ void Creature::ClearBuffList() } buff_list_.clear(); buff_effect_ = {}; - buff_attr_abs_ = {}; - buff_attr_rate_ = {}; RecalcBuffAttr(); } -float Creature::GetBuffAttrAbs(int attr_type) -{ - if (IsValidHumanAttr(attr_type)) { - return buff_attr_abs_[attr_type]; - } - return 0; -} - -float Creature::GetBuffAttrRate(int attr_type) -{ - if (IsValidHumanAttr(attr_type)) { - return buff_attr_rate_[attr_type]; - } - return 0; -} - void Creature::FillBuffList(Human* hum, ::google::protobuf::RepeatedPtrField<::cs::MFBuff>* pb_buff_list) { for (auto& itr : buff_list_) { @@ -1065,38 +1055,12 @@ bool Creature::CanSee(const Creature* c) const float Creature::GetAttrAbs(int attr_id) { - float attr_abs_val = GetBuffAttrAbs(attr_id); - if (attr_id == kHAT_Atk || attr_id == kHAT_Def) { - Buff* buff = GetBuffByEffectId(kBET_Car); - if (buff) { - MetaData::Equip* equip_meta = MetaMgr::Instance()->GetEquip(buff->meta->param4); - if (equip_meta) { - switch (attr_id) { - case kHAT_Atk: - { - attr_abs_val += equip_meta->i->atk(); - } - break; - case kHAT_Def: - { - attr_abs_val += equip_meta->i->def(); - } - break; - default: - { - } - break; - } - } - } - } - return attr_abs_val; + return ability_->GetAttrAbs(attr_id); } float Creature::GetAttrRate(int attr_id) { - float attr_rate_val = GetBuffAttrRate(attr_id); - return attr_rate_val; + return ability_->GetAttrRate(attr_id); } bool Creature::IsPlayer() const @@ -2143,3 +2107,12 @@ bool Creature::CheckCollision() } return false; } + +void Creature::CheckAbilityUsed() +{ + if (ability_.use_count() > 1) { + std::shared_ptr old_val = ability_; + ability_ = std::make_shared(); + *ability_.get() = *(old_val.get()); + } +} diff --git a/server/gameserver/creature.h b/server/gameserver/creature.h index 0af24df..514c220 100644 --- a/server/gameserver/creature.h +++ b/server/gameserver/creature.h @@ -5,6 +5,7 @@ #include "buff.h" #include "weakptr.h" #include "trigger.h" +#include "ability.h" #include "cs_proto.pb.h" @@ -102,8 +103,6 @@ class Creature : public MoveableEntity void RecalcBuffAttr(); void RemoveBuffByEffectId(int buff_effect_id); void ClearBuffList(); - float GetBuffAttrAbs(int attr_id); - float GetBuffAttrRate(int attr_id); void FillBuffList(Human* hum, ::google::protobuf::RepeatedPtrField<::cs::MFBuff>* pb_buff_list); void FillSkillList(::google::protobuf::RepeatedPtrField< cs::MFSkill >* pb_skill_list); void TriggerBuff(Skill* skill, std::set& target_list, BuffTriggerType_e trigger_type); @@ -199,6 +198,7 @@ class Creature : public MoveableEntity void SetLastCollisionDoor(Entity* door) { last_collision_door_ = door; } bool CheckCollision(); Trigger* GetTrigger() { return trigger_; }; + std::shared_ptr& GetAbility() { return ability_; }; protected: @@ -218,6 +218,7 @@ private: void RemovePassiveSkill(int skill_id); void RemoveSurplusHero(int buff_id, int id, int num); void RemoveSurplusObstacle(int buff_id, int id, int num); + void CheckAbilityUsed(); protected: RaceType_e race_ = kHumanRace; @@ -238,8 +239,7 @@ private: Team* team_ = nullptr; Weapon* curr_weapon_ = nullptr; CreatureWeakPtrChunk weak_ptr_chunk_; - std::array buff_attr_abs_ = {}; - std::array buff_attr_rate_ = {}; + std::shared_ptr ability_; std::array buff_effect_ = {}; std::array depend_effect_ = {}; std::array cond_buffs_ = {}; diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 0a0cac5..7bb82f4 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -116,7 +116,8 @@ float Human::GetSpeed() return std::max(1, meta->i->reload_speed()); } float speed = meta->i->move_speed(); - speed = (speed + GetBuffAttrAbs(kHAT_Speed)) * (1 + GetBuffAttrRate(kHAT_Speed)); + speed = (speed + GetAbility()->GetBuffAttrAbs(kHAT_Speed)) * + (1 + GetAbility()->GetBuffAttrRate(kHAT_Speed)); if (a8::HasBitFlag(cell_flags_, kColliderTag_Water)) { speed *= MetaMgr::Instance()->water_move_coefficient; }