diff --git a/server/gameserver/buff/callfunc.cc b/server/gameserver/buff/callfunc.cc index c60ffae3..33c12c28 100644 --- a/server/gameserver/buff/callfunc.cc +++ b/server/gameserver/buff/callfunc.cc @@ -1446,16 +1446,60 @@ void CallFuncBuff::Shot() float z = meta->GetBuffParam5(this); const mt::Equip* bullet_meta = mt::Equip::GetById(id); if (bullet_meta) { - glm::vec3 target_pos = glm::vec3(x, y, z); - glm::vec3 attack_dir = target_pos - owner->GetPos().ToGlmVec3(); - glm::vec3 old_attack_dir = owner->GetAttackDir(); - float fly_distance = 0.0f; - if (GlmHelper::IsZero(attack_dir)) { - attack_dir = owner->GetAttackDir(); - } else { - GlmHelper::Normalize(attack_dir); + bool force_client_report = meta->_buff_param6_int_set.find(1) != meta->_buff_param6_int_set.end(); + bool spec_target_pos = meta->_buff_param6_int_set.find(2) != meta->_buff_param6_int_set.end(); + bool ignore_original_dmg = meta->_buff_param6_int_set.find(3) != meta->_buff_param6_int_set.end(); + bool no_adjust_attack_dir = meta->_buff_param6_int_set.find(4) != meta->_buff_param6_int_set.end(); + + if (force_client_report) { + owner->GetAbility()->IncSwitch(kForceClientReportBullet); + } + if (ignore_original_dmg) { + owner->GetAbility()->IncSwitch(kIgnoreOriginalDmg); + } + auto on_bullet_exit = + [] (Bullet* bullet) + { + + }; + glm::vec3 old_attack_dir = owner->GetAttackDir(); + if (spec_target_pos) { + glm::vec3 target_pos = glm::vec3(x, y, z); + glm::vec3 attack_dir = target_pos - owner->GetPos().ToGlmVec3(); + float fly_distance = 0.0f; + if (GlmHelper::IsZero(attack_dir)) { + attack_dir = owner->GetAttackDir(); + } else { + GlmHelper::Normalize(attack_dir); + } + fly_distance = std::max(1.0f, fly_distance); + InternalShot(owner, + owner->GetCurrWeapon()->meta, + bullet_meta, + skill_meta, + fly_distance, + owner->GetCurrWeapon()->weapon_uniid, + 0, + on_bullet_exit); + } else { + InternalShot(owner, + owner->GetCurrWeapon()->meta, + owner->GetCurrWeapon()->bullet_meta, + skill_meta, + 0, + owner->GetCurrWeapon()->weapon_uniid, + 0, + on_bullet_exit); + } + if (force_client_report) { + owner->GetAbility()->DecSwitch(kForceClientReportBullet); + } + if (ignore_original_dmg) { + owner->GetAbility()->DecSwitch(kIgnoreOriginalDmg); + } + if (!no_adjust_attack_dir) { + owner->SetAttackDir(old_attack_dir); } - owner->SetAttackDir(old_attack_dir); } } diff --git a/server/gameserver/constant.h b/server/gameserver/constant.h index b54cd49d..d5506ed9 100644 --- a/server/gameserver/constant.h +++ b/server/gameserver/constant.h @@ -511,6 +511,8 @@ enum SwitchTimesType_e kImmuneGasTimes, kAniHideTimes, kAccumulatePowerTimes, + kForceClientReportBullet, + kIgnoreOriginalDmg, kSwitchTimeEnd, }; diff --git a/server/gameserver/shot.cc b/server/gameserver/shot.cc index 5a680aa2..b7efe5d2 100644 --- a/server/gameserver/shot.cc +++ b/server/gameserver/shot.cc @@ -323,7 +323,8 @@ void InternalShot(Creature* c, const mt::Skill* skill_meta, float fly_distance, long long weapon_uniid, - int trace_target_uniid) + int trace_target_uniid, + std::function on_bullet_exit) { bool is_player = c->IsPlayer(); bool is_car = c->IsCar(); diff --git a/server/gameserver/shot.h b/server/gameserver/shot.h index c7d2dad0..e37cba0a 100644 --- a/server/gameserver/shot.h +++ b/server/gameserver/shot.h @@ -1,6 +1,7 @@ #pragma once class Creature; +class Bullet; void InternalShot(Creature* sender, const mt::Equip* weapon_meta, @@ -8,4 +9,5 @@ void InternalShot(Creature* sender, const mt::Skill* skill_meta, float fly_distance, long long weapon_uniid, - int trace_target_uniid); + int trace_target_uniid, + std::function on_bullet_exit = nullptr);