diff --git a/server/gameserver/buff.cc b/server/gameserver/buff.cc index 52039db..0968202 100644 --- a/server/gameserver/buff.cc +++ b/server/gameserver/buff.cc @@ -173,14 +173,61 @@ void Buff::ProcBecome(Creature* caster) { caster->second_weapon = Weapon(); if (caster->IsHuman() && meta->param2 > 0.01) { - MetaData::Equip* second_weapon_meta = MetaMgr::Instance()->GetEquip(meta->param2); - if (second_weapon_meta) { - caster->second_weapon.weapon_idx = 100; - caster->second_weapon.weapon_id = second_weapon_meta->i->id(); - caster->second_weapon.weapon_lv = 1; - caster->second_weapon.meta = second_weapon_meta; - caster->second_weapon.Recalc(); - caster->second_weapon.ammo = caster->second_weapon.GetClipVolume(); - } + std::vector strings; + a8::Split(meta->i->buff_param2(), strings, ':'); + if (strings.size() >= 3) { + for (size_t i = 0; i < strings.size(); ++i) { + int weapon_id = a8::XValue(strings[i]); + MetaData::Equip* weapon_meta = MetaMgr::Instance()->GetEquip(weapon_id); + if (weapon_meta) { + Weapon* weapon = nullptr; + switch (i) { + case 0: + { + weapon = &caster->weapons[0]; + } + break; + case 1: + { + weapon = &caster->weapons[GUN_SLOT1]; + } + break; + case 2: + { + weapon = &caster->weapons[GUN_SLOT2]; + } + break; + default: + { + } + break; + } + hold_weapons_.push_back(*weapon); + weapon->weapon_idx = i; + weapon->weapon_id = weapon_meta->i->id(); + weapon->weapon_lv = 1; + weapon->meta = weapon_meta; + weapon->Recalc(); + #if 1 + weapon->ammo = 10000000; + #else + weapon->ammo = weapon->GetClipVolume(); + #endif + } + } + }//end if + caster->need_sync_active_player = true; + caster->SyncAroundPlayers(__FILE__, __LINE__, __func__); } } + +void Buff::ProcRemoveBecome(Creature* caster) +{ + for (auto& weapon : hold_weapons_) { + if (weapon.weapon_idx >= 0 && + weapon.weapon_idx <= GUN_SLOT2) { + caster->weapons[weapon.weapon_idx] = weapon; + } + } + hold_weapons_.clear(); +} diff --git a/server/gameserver/buff.h b/server/gameserver/buff.h index 557ec5c..92e9b73 100644 --- a/server/gameserver/buff.h +++ b/server/gameserver/buff.h @@ -38,7 +38,11 @@ class Buff void ProcSummonHero(Creature* caster); void ProcBeRecycle(Creature* caster); void ProcBecome(Creature* caster); + void ProcRemoveBecome(Creature* caster); private: void InternalTimerAddBuff(Creature* caster); + +private: + std::list hold_weapons_; }; diff --git a/server/gameserver/creature.cc b/server/gameserver/creature.cc index 09f88fe..a3d20d2 100644 --- a/server/gameserver/creature.cc +++ b/server/gameserver/creature.cc @@ -233,7 +233,7 @@ void Creature::RemoveBuffById(int buff_id) { std::vector removed_buffs; for (auto itr = buff_list_.begin(); itr != buff_list_.end(); ++itr) { - const Buff& buff = *itr; + 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; @@ -306,7 +306,7 @@ void Creature::RecalcBuffAttr() } } -void Creature::OnBuffRemove(const Buff& buff) +void Creature::OnBuffRemove(Buff& buff) { } diff --git a/server/gameserver/creature.h b/server/gameserver/creature.h index c30d6f0..0bae52d 100644 --- a/server/gameserver/creature.h +++ b/server/gameserver/creature.h @@ -149,7 +149,7 @@ class Creature : public MoveableEntity private: virtual void AddBuffPostProc(Creature* caster, Buff* buff); - virtual void OnBuffRemove(const Buff& buff); + virtual void OnBuffRemove(Buff& buff); virtual void DoSkillPreProc(int skill_id, int target_id, const a8::Vec2& target_pos); virtual void DoSkillPostProc(bool used, int skill_id, int target_id, const a8::Vec2& target_pos); diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 7039589..f6f8c45 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -3211,7 +3211,7 @@ void Human::ProcReloadAction() } } -void Human::OnBuffRemove(const Buff& buff) +void Human::OnBuffRemove(Buff& buff) { switch (buff.meta->i->buff_effect()) { case kBET_Jump: @@ -3232,7 +3232,7 @@ void Human::OnBuffRemove(const Buff& buff) break; case kBET_Become: { - second_weapon = Weapon(); + buff.ProcRemoveBecome(this); } break; default: diff --git a/server/gameserver/human.h b/server/gameserver/human.h index 32918b3..c3d25eb 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -285,7 +285,7 @@ private: void OnLeaveSpecMapArea(int tag, SpecMapObject& map_obj); void ClearSpecMapAreaTimer(SpecMapObject& map_obj); virtual void AddBuffPostProc(Creature* caster, Buff* buff) override; - virtual void OnBuffRemove(const Buff& buff) override; + virtual void OnBuffRemove(Buff& buff) override; virtual void DoSkillPreProc(int skill_id, int target_id, const a8::Vec2& target_pos) override; virtual void DoSkillPostProc(bool used, int skill_id, int target_id, const a8::Vec2& target_pos) override; diff --git a/server/gameserver/metadata.cc b/server/gameserver/metadata.cc index f0a5183..720c66c 100644 --- a/server/gameserver/metadata.cc +++ b/server/gameserver/metadata.cc @@ -515,7 +515,11 @@ namespace MetaData for (int buff_id : buff_list) { MetaData::Buff* buff_meta = MetaMgr::Instance()->GetBuff(buff_id); if (!buff_meta) { + #if 1 + return; + #else abort(); + #endif } auto itr = trigger_type_buffs.find(buff_meta->i->trigger_type()); if (itr != trigger_type_buffs.end()) {