From 7ced148ff7adc039edb11a0a41e985270376f09c Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Fri, 30 Dec 2022 16:14:19 +0800 Subject: [PATCH] 1 --- server/gameserver/bullet.cc | 309 +++++++++++++++++++----------------- server/gameserver/bullet.h | 3 + 2 files changed, 164 insertions(+), 148 deletions(-) diff --git a/server/gameserver/bullet.cc b/server/gameserver/bullet.cc index b925803a..102223c5 100644 --- a/server/gameserver/bullet.cc +++ b/server/gameserver/bullet.cc @@ -29,6 +29,15 @@ #include "mt/Hero.h" #include "mt/MapThing.h" +struct BulletCheckResult +{ + int c_hit_num = 0; + int t_hit_num = 0; + int o_hit_num = 0; + bool eat = false; + std::set objects; +}; + Bullet::Bullet():MoveableEntity() { ++PerfMonitor::Instance()->entity_num[ET_Bullet]; @@ -253,17 +262,17 @@ void Bullet::ProcBomb() if (sender.Get() && sender.Get()->IsHuman()) { sender.Get()->AsHuman()->stats.IncWeaponUseTimes(gun_meta->id(), 1); } - #if 1 +#if 1 AddGunBuff(); ProcSmokeBomb(); - #else +#else a8::Vec2 bomb_pos = GetPos(); float time_addition = 0; if (IsCurrWeapon() && sender.Get()) { time_addition += sender.Get()->GetAbility()->GetAttrAbs(kHAT_WeaponExplosionContinueTime); } room->frame_event.AddSmoke(this, meta->id(), bomb_pos, time_addition); - #endif +#endif } break; case IS_POSION_GAS_BOMB: @@ -467,149 +476,13 @@ float Bullet::GetExplosionRange() void Bullet::Check(float distance) { - int c_hit_num = 0; - int t_hit_num = 0; - int o_hit_num = 0; - std::set objects; - { - std::set colliders; - room->map_service->GetColliders(room, GetPos().GetX(), GetPos().GetY(), colliders); - for (ColliderComponent* collider : colliders) { - if (collider->owner->IsEntityType(ET_Dummy)) { - if (a8::HasBitFlag(collider->tag, kHalfWallTag)) { - continue; - } - if (TestCollision(room, collider)) { - ++o_hit_num; - objects.insert(collider->owner); - } - } else if (collider->owner->IsEntityType(ET_Obstacle)) { - Obstacle* obstacle = (Obstacle*)collider->owner; - if (gun_meta->is_penetrate_thing() && - hit_objects_.find(obstacle->GetUniId()) != hit_objects_.end()) { - //穿物件 - continue; - } - if (!obstacle->CanThroughable(this)) { - if (TestCollision(room, collider)) { - objects.insert(collider->owner); - if (gun_meta->is_penetrate_thing()) { - ++t_hit_num; - ++o_hit_num; - hit_objects_.insert(collider->owner->GetUniId()); - } - } - } else if (obstacle->meta->thing_type() == kObstacleStrengthenWall) { - if (!strengthened_ && sender.Get() && - sender.Get()->team_id == obstacle->GetTeamId(room)) { - bool ret = Check2dRotationRectangle - (GetPos().x, - GetPos().y, - gun_meta->bullet_rad(), - obstacle->GetPos().x, - obstacle->GetPos().y, - obstacle->meta->width(), - obstacle->meta->height(), - obstacle->GetRotate() * 180.0f - ); - if (ret) { - strengthened_ = true; - OnStrengthen(obstacle); -#ifdef DEBUG - a8::XPrintf("命中能量墙\n", {}); -#endif - } - } - } - } - } - } - bool eat = false; - if (o_hit_num <= 0) { - room->grid_service->TraverseCreatures - (room->GetRoomIdx(), - GetGridList(), - [this, &objects, &c_hit_num, &eat] (Creature* c, bool& stop) - { - bool no_teammate = IsFlyHook(); - if (sender.Get()->IsProperTarget(c, no_teammate)) { - if (gun_meta->ispenetrate() && - hit_objects_.find(c->GetUniId()) != hit_objects_.end()) { - //穿人 - return; - } - if (c->HasBuffEffect(kBET_BulletThrough)) { - return; - } - { - Buff* hold_shield_buff = c->GetBuffByEffectId(kBET_HoldShield); - if (hold_shield_buff && !IsBomb() && !c->dead && c != sender.Get()) { - // 999 - #if 0 - //param2是距离 param4是宽度 - a8::Vec2 shield_pos = c->GetPos() + c->GetAttackDir() * hold_shield_buff->meta->param2; - bool ret = Check2dRotationRectangle(GetPos().x, - GetPos().y, - //10, - gun_meta->bullet_rad(), - shield_pos.x, - shield_pos.y, - hold_shield_buff->meta->param4, - MetaMgr::Instance()->bullet_planck_step_length, - c->GetAttackDirRotate() * 180.0f - ); - if (ret) { - float finaly_dmg = c->GetBattleContext()->CalcDmg(c, this); - c->shield_hp_ = std::max(0.0f, c->shield_hp_ - finaly_dmg); -#ifdef DEBUG - a8::XPrintf("命中盾牌 finally_dmg:%f shield_hp:%f\n", - { - finaly_dmg, - c->shield_hp_ - }); -#endif - room->frame_event.AddPropChg(c->GetWeakPtrRef(), - kPropShieldHp, - c->shield_max_hp_, - c->shield_hp_); - if (c->shield_hp_ <= 0) { -#ifdef DEBUG - a8::XPrintf("shiled destory\n", {}); -#endif - c->GetTrigger()->ShieldDestory(); - c->RemoveBuffByUniId(hold_shield_buff->buff_uniid); - } - eat = true; - stop = true; - return; - } - #endif - } - } - AabbCollider aabb_box; - c->GetHitAabbBox(aabb_box); - if (c != sender.Get() && !c->dead && TestCollision(room, &aabb_box)) { - if (meta->_inventory_slot() == IS_C4) { - if (!c->IsHuman()) { - objects.insert(c); - if (gun_meta->ispenetrate()) { - ++c_hit_num; - hit_objects_.insert(c->GetUniId()); - } - } - } else { - objects.insert(c); - if (gun_meta->ispenetrate()) { - ++c_hit_num; - hit_objects_.insert(c->GetUniId()); - } - } - } - } - }); + BulletCheckResult result; + GetHitThings(result); + if (result.o_hit_num <= 0) { + GetHitCreatures(result); } float bullet_range = gun_meta->range(); - if (!objects.empty() || (!IsBomb() && distance > bullet_range) || eat || + if (!result.objects.empty() || (!IsBomb() && distance > bullet_range) || result.eat || (gun_meta->id() == 30918 && distance >= fly_distance) || (IsBomb() && meta->_inventory_slot() != IS_RPG && distance >= fly_distance) ) { @@ -617,16 +490,16 @@ void Bullet::Check(float distance) ProcBomb(); } else { bool hited = false; - if (!eat && !objects.empty()) { + if (!result.eat && !result.objects.empty()) { hited = true; - OnHit(objects); + OnHit(result.objects); } bool need_remove = true; if (distance < bullet_range) { if (!gun_meta->is_penetrate_thing() && !gun_meta->ispenetrate()) { } else { - if ((!gun_meta->is_penetrate_thing() && (t_hit_num > 0)) || - (!gun_meta->ispenetrate() && (c_hit_num > 0))) { + if ((!gun_meta->is_penetrate_thing() && (result.t_hit_num > 0)) || + (!gun_meta->ispenetrate() && (result.c_hit_num > 0))) { } else { need_remove = false; } @@ -935,3 +808,143 @@ bool Bullet::IsFlyHook() { return gun_meta->equip_subtype() == GUN_SUB_EQUIP_TYPE_FLY_HOOk; } + +void Bullet::GetHitThings(BulletCheckResult& result) +{ + std::set colliders; + room->map_service->GetColliders(room, GetPos().GetX(), GetPos().GetY(), colliders); + for (ColliderComponent* collider : colliders) { + if (collider->owner->IsEntityType(ET_Dummy)) { + if (a8::HasBitFlag(collider->tag, kHalfWallTag)) { + continue; + } + if (TestCollision(room, collider)) { + ++result.o_hit_num; + result.objects.insert(collider->owner); + } + } else if (collider->owner->IsEntityType(ET_Obstacle)) { + Obstacle* obstacle = (Obstacle*)collider->owner; + if (gun_meta->is_penetrate_thing() && + hit_objects_.find(obstacle->GetUniId()) != hit_objects_.end()) { + //穿物件 + continue; + } + if (!obstacle->CanThroughable(this)) { + if (TestCollision(room, collider)) { + result.objects.insert(collider->owner); + if (gun_meta->is_penetrate_thing()) { + ++result.t_hit_num; + ++result.o_hit_num; + hit_objects_.insert(collider->owner->GetUniId()); + } + } + } else if (obstacle->meta->thing_type() == kObstacleStrengthenWall) { + if (!strengthened_ && sender.Get() && + sender.Get()->team_id == obstacle->GetTeamId(room)) { + bool ret = Check2dRotationRectangle + (GetPos().x, + GetPos().y, + gun_meta->bullet_rad(), + obstacle->GetPos().x, + obstacle->GetPos().y, + obstacle->meta->width(), + obstacle->meta->height(), + obstacle->GetRotate() * 180.0f + ); + if (ret) { + strengthened_ = true; + OnStrengthen(obstacle); +#ifdef DEBUG + a8::XPrintf("命中能量墙\n", {}); +#endif + } + } + } + } + } +} + +void Bullet::GetHitCreatures(BulletCheckResult& result) +{ + room->grid_service->TraverseCreatures + (room->GetRoomIdx(), + GetGridList(), + [this, &result] (Creature* c, bool& stop) + { + bool no_teammate = IsFlyHook(); + if (sender.Get()->IsProperTarget(c, no_teammate)) { + if (gun_meta->ispenetrate() && + hit_objects_.find(c->GetUniId()) != hit_objects_.end()) { + //穿人 + return; + } + if (c->HasBuffEffect(kBET_BulletThrough)) { + return; + } + { + Buff* hold_shield_buff = c->GetBuffByEffectId(kBET_HoldShield); + if (hold_shield_buff && !IsBomb() && !c->dead && c != sender.Get()) { + // 999 +#if 0 + //param2是距离 param4是宽度 + a8::Vec2 shield_pos = c->GetPos() + c->GetAttackDir() * hold_shield_buff->meta->param2; + bool ret = Check2dRotationRectangle(GetPos().x, + GetPos().y, + //10, + gun_meta->bullet_rad(), + shield_pos.x, + shield_pos.y, + hold_shield_buff->meta->param4, + MetaMgr::Instance()->bullet_planck_step_length, + c->GetAttackDirRotate() * 180.0f + ); + if (ret) { + float finaly_dmg = c->GetBattleContext()->CalcDmg(c, this); + c->shield_hp_ = std::max(0.0f, c->shield_hp_ - finaly_dmg); +#ifdef DEBUG + a8::XPrintf("命中盾牌 finally_dmg:%f shield_hp:%f\n", + { + finaly_dmg, + c->shield_hp_ + }); +#endif + room->frame_event.AddPropChg(c->GetWeakPtrRef(), + kPropShieldHp, + c->shield_max_hp_, + c->shield_hp_); + if (c->shield_hp_ <= 0) { +#ifdef DEBUG + a8::XPrintf("shiled destory\n", {}); +#endif + c->GetTrigger()->ShieldDestory(); + c->RemoveBuffByUniId(hold_shield_buff->buff_uniid); + } + eat = true; + stop = true; + return; + } +#endif + } + } + AabbCollider aabb_box; + c->GetHitAabbBox(aabb_box); + if (c != sender.Get() && !c->dead && TestCollision(room, &aabb_box)) { + if (meta->_inventory_slot() == IS_C4) { + if (!c->IsHuman()) { + result.objects.insert(c); + if (gun_meta->ispenetrate()) { + ++result.c_hit_num; + hit_objects_.insert(c->GetUniId()); + } + } + } else { + result.objects.insert(c); + if (gun_meta->ispenetrate()) { + ++result.c_hit_num; + hit_objects_.insert(c->GetUniId()); + } + } + } + } + }); +} diff --git a/server/gameserver/bullet.h b/server/gameserver/bullet.h index 9fda1007..06411b2c 100644 --- a/server/gameserver/bullet.h +++ b/server/gameserver/bullet.h @@ -3,6 +3,7 @@ #include "moveableentity.h" #include "weakptr.h" +struct BulletCheckResult; class Human; class Obstacle; class Creature; @@ -75,6 +76,8 @@ protected: void OnKillTarget(Entity* target); void OnStrengthen(Obstacle* ob); void ClearBuffList(); + void GetHitThings(BulletCheckResult& result); + void GetHitCreatures(BulletCheckResult& result); private: CircleCollider* self_collider_ = nullptr;