game2005/server/gameserver/creature.cc
aozhiwei ad0e12835f 1
2021-03-18 14:40:38 +08:00

317 lines
8.8 KiB
C++

#include "precompile.h"
#include "creature.h"
#include "metamgr.h"
#include "room.h"
bool Creature::HasBuffEffect(int buff_effect_id)
{
return GetBuffByEffectId(buff_effect_id) != nullptr;
}
Buff* Creature::GetBuffByEffectId(int effect_id)
{
return IsValidBuffEffect(effect_id) ? buff_effect_[effect_id] : nullptr;
}
Buff* Creature::GetBuffById(int buff_id)
{
for (Buff& buff : buff_list_) {
if (buff.meta->i->buff_id() == buff_id) {
return &buff;
}
}
return nullptr;
}
void Creature::AddBuff(Creature* caster,
MetaData::Buff* buff_meta,
int skill_lv,
MetaData::Skill* buff_skill_meta)
{
if (GetBuffById(buff_meta->i->buff_id())) {
return;
}
if (IsImmuneBuffEffect(buff_meta->i->buff_effect())) {
return;
}
if (!buff_meta->EffectCanStack()) {
Buff* buff = GetBuffByEffectId(buff_meta->i->buff_effect());
if (buff) {
RemoveBuffById(buff->meta->i->buff_id());
}
}
if (buff_meta->i->buff_effect() == kBET_OnceChgAttr) {
if ((int)buff_meta->param1== kHAT_Hp) {
if ((int)buff_meta->param2 == 1) {
//绝对值
ability.hp += buff_meta->param3;
ability.hp = std::min(ability.max_hp, ability.hp);
} else if ((int)buff_meta->param2 == 2) {
//百分比
ability.hp *= 1 + buff_meta->param3;
ability.hp = std::min(ability.max_hp, ability.hp);
}
SyncAroundPlayers(__FILE__, __LINE__, __func__);
}
}
Buff* buff = &a8::FastAppend(buff_list_);
buff->skill_lv = skill_lv;
buff->owner = this;
buff->meta = buff_meta;
buff->skill_meta = buff_skill_meta;
buff->add_frameno = room->GetFrameNo();
buff->xtimer_attacher.xtimer = &room->xtimer;
buff_effect_[buff->meta->i->buff_effect()] = buff;
{
room->xtimer.AddDeadLineTimerAndAttach
(
buff_meta->i->duration_time() * SERVER_FRAME_RATE,
a8::XParams()
.SetSender(this)
.SetParam1(buff_meta->i->buff_id()),
[] (const a8::XParams& param)
{
Creature* c = (Creature*)param.sender.GetUserData();
c->RemoveBuffById(param.param1);
},
&buff->xtimer_attacher.timer_list_
);
}
AddBuffPostProc(caster, buff);
#ifdef DEBUG
SendDebugMsg(a8::Format("添加buff_id:%d buff_effect:%d",
{
buff_meta->i->buff_id(),
buff_meta->i->buff_effect()
}));
#endif
}
bool Creature::IsImmuneBuffEffect(int buff_effect)
{
for (auto itr = buff_list_.begin(); itr != buff_list_.end(); ++itr) {
if (itr->meta->IsImmuneBuffEffect(buff_effect)) {
return true;
}
}
return false;
}
void Creature::MustBeAddBuff(Creature* caster, int buff_id)
{
MetaData::Buff* buff_meta = MetaMgr::Instance()->GetBuff(buff_id);
if (!buff_meta) {
abort();
}
AddBuff(caster, buff_meta, 1);
}
void Creature::RemoveBuffById(int buff_id)
{
for (auto itr = buff_list_.begin(); itr != buff_list_.end(); ++itr) {
const Buff& buff = *itr;
if (buff.meta->i->buff_id() == buff_id) {
if (buff_effect_[buff.meta->i->buff_effect()] == &(*itr)) {
buff_effect_[buff.meta->i->buff_effect()] = nullptr;
}
OnBuffRemove(buff);
buff_list_.erase(itr);
break;
}
}
RecalcBuffAttr();
#ifdef DEBUG
SendDebugMsg(a8::Format("移除buff_id:%d",
{
buff_id
}));
#endif
}
void Creature::SendDebugMsg(const std::string& debug_msg)
{
}
void Creature::AddBuffPostProc(Creature* caster, Buff* buff)
{
}
void Creature::RecalcBuffAttr()
{
buff_attr_abs_ = {};
buff_attr_rate_ = {};
for (auto& buff : buff_list_) {
if (buff.meta->i->buff_effect() == kBET_ChgAttr ||
buff.meta->i->buff_effect() == kBET_Car) {
int attr_type = (int)buff.meta->param1;
int calc_type = (int)buff.meta->param2;
if (IsValidHumanAttr(attr_type)) {
if (calc_type == 1) {
buff_attr_abs_[attr_type] += buff.meta->param3;
} else if (calc_type == 2) {
buff_attr_rate_[attr_type] += buff.meta->param3;
}
}
}
}
}
void Creature::OnBuffRemove(const Buff& buff)
{
}
void Creature::RemoveBuffByEffectId(int buff_effect_id)
{
Buff* buff = GetBuffByEffectId(buff_effect_id);
if (buff) {
RemoveBuffById(buff->meta->i->buff_id());
}
}
void Creature::ClearBuffList()
{
for (auto itr = buff_list_.begin(); itr != buff_list_.end(); ++itr) {
if (buff_effect_[itr->meta->i->buff_effect()] == &(*itr)) {
buff_effect_[itr->meta->i->buff_effect()] = nullptr;
}
OnBuffRemove(*itr);
}
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(::google::protobuf::RepeatedPtrField<::cs::MFBuff>* pb_buff_list)
{
for (auto& itr : buff_list_) {
auto buff = pb_buff_list->Add();
itr.FillMFBuff(buff);
}
}
void Creature::AddPassiveSkill(MetaData::Skill* skill_meta)
{
if (!HasPassiveSkill(skill_meta)) {
xtimer_list* tmp_timer = room->xtimer.AddRepeatTimerAndAttach
(
SERVER_FRAME_RATE * skill_meta->i->skill_cd(),
a8::XParams()
.SetSender(this)
.SetParam1(skill_meta),
[] (const a8::XParams& param)
{
Creature* c = (Creature*)param.sender.GetUserData();
MetaData::Skill* skill_meta = (MetaData::Skill*)param.param1.GetUserData();
c->ClearPassiveSkillBuff(skill_meta);
c->AddPassiveSkillBuff(skill_meta);
},
&xtimer_attacher.timer_list_);
passive_skill_metas_[skill_meta] = tmp_timer;
AddPassiveSkillBuff(skill_meta);
if (skill_meta->i->skill_cd() > 10000) {
//永久被动被动技能
AddPassiveSkillBuff(skill_meta);
}
}
}
void Creature::RemovePassiveSkill(MetaData::Skill* skill_meta)
{
auto itr = passive_skill_metas_.find(skill_meta);
if (itr != passive_skill_metas_.end()) {
ClearPassiveSkillBuff(skill_meta);
room->xtimer.DeleteTimer(itr->second);
passive_skill_metas_.erase(itr);
}
}
void Creature::ClearPassiveSkill()
{
std::vector<MetaData::Skill*> del_skills;
del_skills.reserve(passive_skill_metas_.size());
for (auto& pair : passive_skill_metas_) {
del_skills.push_back(pair.first);
}
for (MetaData::Skill* skill_meta : del_skills) {
RemovePassiveSkill(skill_meta);
}
}
bool Creature::HasPassiveSkill(MetaData::Skill* skill_meta)
{
return passive_skill_metas_.find(skill_meta) != passive_skill_metas_.end();
}
void Creature::ClearPassiveSkillBuff(MetaData::Skill* skill_meta)
{
for (int buff_id : skill_meta->buff_list) {
Buff* buff = GetBuffById(buff_id);
if (buff &&
(buff->meta->i->buff_target() == kBuffTargetSelf ||
buff->meta->i->buff_target() == kBuffTargetFriendly)) {
RemoveBuffById(buff_id);
}
}
}
void Creature::AddPassiveSkillBuff(MetaData::Skill* skill_meta)
{
if (!skill_meta) {
return;
}
MetaData::Skill* old_curr_skill = skill_meta_;
int old_skill_target_id_ = skill_target_id_;
a8::Vec2 old_skill_target_pos_ = skill_target_pos_;
skill_meta_ = skill_meta;
skill_target_id_ = GetEntityUniId();
skill_target_pos_ = GetPos();
std::set<Entity*> target_list;
SelectSkillTargets(GetPos(), target_list);
TriggerBuff(target_list, kBTT_UseSkill);
skill_meta_= old_curr_skill;
skill_target_id_ = old_skill_target_id_;
skill_target_pos_ = old_skill_target_pos_;
}
void Creature::SelectSkillTargets(const a8::Vec2& target_pos, std::set<Entity*>& target_list)
{
}
void Creature::TriggerBuff(std::set<Entity*>& target_list, BuffTriggerType_e trigger_type)
{
for (Entity* entity : target_list) {
TriggerOneObjectBuff(entity, trigger_type);
}
}
void Creature::TriggerOneObjectBuff(Entity* target, BuffTriggerType_e trigger_type)
{
}