diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 6148c9b..88ba8a7 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -1990,6 +1990,11 @@ void Human::ChangeToRace(RaceType_e race, int level) exp_ = meta->i->exp(); skill_meta_ = MetaMgr::Instance()->GetSkill(meta->i->active_skill()); ResetSkill(); + MetaData::Skill* passive_skill_meta = MetaMgr::Instance()->GetSkill(meta->i->passive_skill()); + ClearPassiveSkill(); + if (passive_skill_meta) { + AddPassiveSkill(passive_skill_meta); + } } else if (race_ == kZombieRace) { meta = MetaMgr::Instance()->GetPlayer(ZOMBIE_RACE_META_START_ID + level_ - 1); if (!meta) { @@ -1998,6 +2003,11 @@ void Human::ChangeToRace(RaceType_e race, int level) exp_ = meta->i->exp(); skill_meta_ = MetaMgr::Instance()->GetSkill(meta->i->active_skill()); ResetSkill(); + MetaData::Skill* passive_skill_meta = MetaMgr::Instance()->GetSkill(meta->i->passive_skill()); + ClearPassiveSkill(); + if (passive_skill_meta) { + AddPassiveSkill(passive_skill_meta); + } } else { abort(); } @@ -2020,7 +2030,6 @@ void Human::WinExp(Human* sender, int exp) MetaData::Player* old_meta = meta; int start_meta_id = race_ == kHumanRace ? HUMAN_RACE_META_START_ID : ZOMBIE_RACE_META_START_ID; do { - MetaData::Player* tmp_meta = MetaMgr::Instance()->GetPlayer(start_meta_id + level_); if (!tmp_meta) { break; @@ -2035,7 +2044,12 @@ void Human::WinExp(Human* sender, int exp) } } while (true); if (old_meta != meta) { - room->frame_event.AddRaceChg(this); + room->frame_event.AddZombieIdChg(this); + MetaData::Skill* passive_skill_meta = MetaMgr::Instance()->GetSkill(meta->i->passive_skill()); + ClearPassiveSkill(); + if (passive_skill_meta) { + AddPassiveSkill(passive_skill_meta); + } } } @@ -3668,3 +3682,68 @@ void Human::ResetSkill() skill_param1 = 0.0f; playing_skill = false; } + +void Human::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) + { + Human* hum = (Human*)param.sender.GetUserData(); + MetaData::Skill* skill_meta = (MetaData::Skill*)param.param1.GetUserData(); + hum->ClearPassiveSkillBuff(skill_meta); + hum->AddPassiveSkillBuff(skill_meta); + }, + &xtimer_attacher.timer_list_); + passive_skill_metas_[skill_meta] = tmp_timer; + AddPassiveSkillBuff(skill_meta); + } +} + +void Human::RemovePassiveSkill(MetaData::Skill* skill_meta) +{ + auto itr = passive_skill_metas_.find(skill_meta); + if (itr != passive_skill_metas_.end()) { + ClearPassiveSkillBuff(skill_meta); + passive_skill_metas_.erase(itr); + } +} + +void Human::ClearPassiveSkill() +{ + std::vector 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 Human::HasPassiveSkill(MetaData::Skill* skill_meta) +{ + return passive_skill_metas_.find(skill_meta) != passive_skill_metas_.end(); +} + +void Human::ClearPassiveSkillBuff(MetaData::Skill* skill_meta) +{ + for (int buff_id : skill_meta->buff_list) { + RemoveBuffById(buff_id); + } +} + +void Human::AddPassiveSkillBuff(MetaData::Skill* skill_meta) +{ + for (int buff_id : skill_meta->buff_list) { + MetaData::Buff* buff_meta = MetaMgr::Instance()->GetBuff(buff_id); + if (buff_meta) { + AddBuff(buff_meta, buff_id); + } + } +} diff --git a/server/gameserver/human.h b/server/gameserver/human.h index 3a0f32e..4c55c65 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -320,6 +320,12 @@ private: std::set& dec_grids); void RemoveFromScene(); void ResetSkill(); + void AddPassiveSkill(MetaData::Skill* skill_meta); + void RemovePassiveSkill(MetaData::Skill* skill_meta); + void ClearPassiveSkill(); + bool HasPassiveSkill(MetaData::Skill* skill_meta); + void ClearPassiveSkillBuff(MetaData::Skill* skill_meta); + void AddPassiveSkillBuff(MetaData::Skill* skill_meta); protected: int level_ = 0; @@ -368,6 +374,7 @@ protected: HumanCar car_; MetaData::Skill* skill_meta_ = nullptr; + std::map passive_skill_metas_; private: RaceType_e race_ = kHumanRace;