diff --git a/server/gameserver/bullet.cc b/server/gameserver/bullet.cc index bb179de..4cfe72d 100644 --- a/server/gameserver/bullet.cc +++ b/server/gameserver/bullet.cc @@ -295,7 +295,14 @@ void Bullet::Check(float distance) std::set colliders; room->map_service->GetColliders(room, GetX(), GetY(), colliders); for (ColliderComponent* collider : colliders) { - if (TestCollision(room, collider) && !a8::HasBitFlag(collider->tag, kHalfWallTag)) { + if (TestCollision(room, collider) && + !a8::HasBitFlag(collider->tag, kHalfWallTag)) { + if (collider->owner->IsEntityType(ET_Obstacle)) { + Obstacle* obstacle = (Obstacle*)collider->owner; + if (obstacle->CanThroughable(this)) { + continue; + } + } objects.insert(collider->owner); } } diff --git a/server/gameserver/frag_mitask.cc b/server/gameserver/frag_mitask.cc index 16fe4b5..1d4cdd1 100644 --- a/server/gameserver/frag_mitask.cc +++ b/server/gameserver/frag_mitask.cc @@ -78,7 +78,7 @@ void FragMiTask::Done() } Obstacle* obstacle = (Obstacle*)target; if (!obstacle->IsDead(room) && - obstacle->Attackable() && + obstacle->Attackable(sender.Get()) && !obstacle->IsTerminatorAirDropBox(room)) { float dmg = GetAtk() * (1 + sender.Get()->GetAttrRate(kHAT_Atk)) + sender.Get()->GetAttrAbs(kHAT_Atk); diff --git a/server/gameserver/hero.cc b/server/gameserver/hero.cc index 8ec9377..21ccbe8 100644 --- a/server/gameserver/hero.cc +++ b/server/gameserver/hero.cc @@ -165,7 +165,7 @@ bool Hero::IsCollisionInMapService() return true; } if (!obstacle->IsDead(room) && - obstacle->Attackable() && + obstacle->Attackable(this) && obstacle->meta->i->drop() != 0 && obstacle->IsTouchInteraction() && room->GetGasData().gas_mode != GasInactive && diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index f04ea29..60fde21 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -525,7 +525,7 @@ bool Human::IsCollisionInMapService() return true; } if (!obstacle->IsDead(room) && - obstacle->Attackable() && + obstacle->Attackable(this) && obstacle->meta->i->drop() != 0 && obstacle->IsTouchInteraction() && room->GetGasData().gas_mode != GasInactive && diff --git a/server/gameserver/obstacle.cc b/server/gameserver/obstacle.cc index f90c55b..65ec2a3 100644 --- a/server/gameserver/obstacle.cc +++ b/server/gameserver/obstacle.cc @@ -355,7 +355,7 @@ void Obstacle::Explosion(Bullet* bullet) { Obstacle* obstacle = (Obstacle*)target; if (!obstacle->IsDead(room) && - obstacle->Attackable() && + obstacle->Attackable(this) && !obstacle->IsTerminatorAirDropBox(room)) { float dmg = meta->i->damage(); float def = 0; @@ -497,9 +497,30 @@ bool Obstacle::IsPermanent() return is_permanent; } -bool Obstacle::Attackable() +bool Obstacle::Attackable(Entity* sender) { - return meta->i->attack_type() == 1; + switch (meta->i->attack_type()) { + case 1: + { + return true; + } + break; + case 3: + { + //只有特定子弹 + if (sender->IsEntityType(ET_Bullet)) { + Bullet* bullet = (Bullet*)sender; + return ((bullet->gun_meta->special_damage_type & meta->receive_special_damage_type) != 0); + } + return false; + } + break; + default: + { + return false; + } + break; + } } bool Obstacle::Throughable() @@ -566,7 +587,7 @@ void Obstacle::SetMasterId(Room* room, int master_id) void Obstacle::OnBulletHit(Bullet* bullet) { if (!IsDead(bullet->room) && - Attackable() && + Attackable(bullet) && !IsTerminatorAirDropBox(bullet->room)) { if (meta->receive_special_damage_type != 0 && ((bullet->gun_meta->special_damage_type & meta->receive_special_damage_type) == 0)) { @@ -627,11 +648,18 @@ void Obstacle::OnBulletHit(Bullet* bullet) bool Obstacle::CanThroughable(Creature* c) { + if (meta->i->attack_type() == 3) { + return true; + } return false; } bool Obstacle::CanThroughable(Bullet* bullet) { + if (meta->i->attack_type() == 3) { + return meta->receive_special_damage_type != 0 && + ((bullet->gun_meta->special_damage_type & meta->receive_special_damage_type) == 0); + } return false; } diff --git a/server/gameserver/obstacle.h b/server/gameserver/obstacle.h index 935d9a3..dd43753 100644 --- a/server/gameserver/obstacle.h +++ b/server/gameserver/obstacle.h @@ -67,7 +67,7 @@ class Obstacle : public Entity int GetMasterId(Room* room); void SetMasterId(Room* room, int master_id); bool IsPermanent(); - bool Attackable(); + bool Attackable(Entity* sender); bool Throughable(); bool IsTouchInteraction(); bool IsOpenInteraction(); diff --git a/server/gameserver/roomobstacle.cc b/server/gameserver/roomobstacle.cc index 29b565a..83a97d1 100644 --- a/server/gameserver/roomobstacle.cc +++ b/server/gameserver/roomobstacle.cc @@ -241,7 +241,7 @@ void RoomObstacle::Explosion() { Obstacle* obstacle = (Obstacle*)target; if (!obstacle->IsDead(room) && - obstacle->Attackable() && + obstacle->Attackable(this) && !obstacle->IsTerminatorAirDropBox(room)) { float dmg = meta->i->damage(); float def = 0;