diff --git a/server/gameserver/bullet.cc b/server/gameserver/bullet.cc index 4cfe72d..5ebdbf5 100644 --- a/server/gameserver/bullet.cc +++ b/server/gameserver/bullet.cc @@ -14,6 +14,7 @@ #include "frag_mitask.h" #include "creature.h" #include "roomobstacle.h" +#include "car.h" Bullet::Bullet():MoveableEntity() { @@ -59,31 +60,46 @@ void Bullet::ProcBomb() { self_collider_->rad = gun_meta->i->explosion_range(); std::set objects; - TraverseAllLayerHumanList + Car* c4_target = nullptr; + TraverseCreatures ( - [this, &objects] (Human* hum, bool& stop) + [this, &objects, &c4_target] (Creature* c, bool& stop) { - if (!is_tank_skin || sender.Get()->team_id != hum->team_id) { + if (c->dead) { + return; + } + if (!is_tank_skin || sender.Get()->team_id != c->team_id) { //友军火箭筒伤害取消 if ((meta->i->_inventory_slot() == 4 || meta->i->_inventory_slot() == 5) && - sender.Get()->team_id == hum->team_id) { + sender.Get()->team_id == c->team_id) { return; } if (meta->i->_inventory_slot() == IS_C4) { - if (hum->IsHuman()) { + if (!objects.empty()) { + stop = true; return; } + if (!c->IsCar()) { + return; + } + c4_target = c->AsCar(); } - if (TestCollision(room, hum)) { - objects.insert(hum); + if (TestCollision(room, c)) { + objects.insert(c); } } }); TraverseAllLayerEntityList ( - [this, &objects] (Entity* entity, bool& stop) + [this, &objects, c4_target] (Entity* entity, bool& stop) { + if (meta->i->_inventory_slot() == IS_C4) { + if (c4_target) { + stop = true; + return; + } + } switch (entity->GetEntityType()) { case ET_Obstacle: case ET_Building: @@ -151,7 +167,7 @@ void Bullet::ProcBomb() { //c4 delay_time = gun_meta->i->missiles_time(); - ProcC4Bomb(delay_time); + ProcC4Bomb(c4_target, delay_time); } break; case IS_SINGAL_GUN: @@ -387,13 +403,16 @@ void Bullet::ProcMolotorCocktailBomb(int delay_time) } } -void Bullet::ProcC4Bomb(int delay_time) +void Bullet::ProcC4Bomb(Car* target, int delay_time) { if (sender.Get()) { FragMiTask* task = new FragMiTask(); task->room = room; task->sender.Attach(sender.Get()); task->bomb_pos = GetPos(); + if (target) { + task->follow_target.Attach(target); + } task->gun_meta = gun_meta; task->meta = meta; task->atk = GetAtk(); diff --git a/server/gameserver/bullet.h b/server/gameserver/bullet.h index bb3d12c..bae5a82 100644 --- a/server/gameserver/bullet.h +++ b/server/gameserver/bullet.h @@ -15,6 +15,7 @@ class Obstacle; class Creature; class CircleCollider; class MovementComponent; +class Car; class Bullet : public MoveableEntity { public: @@ -49,7 +50,7 @@ protected: void ProcFragBomb(int delay_time); void ProcPosionGasBomb(int delay_time); void ProcMolotorCocktailBomb(int delay_time); - void ProcC4Bomb(int delay_time); + void ProcC4Bomb(Car* target, int delay_time); void ProcSignalGunBomb(int delay_time); void ProcShieldWallBomb(int delay_time); void ProcOilBucketBomb(int delay_time); diff --git a/server/gameserver/creature.h b/server/gameserver/creature.h index 9f2aacb..2dcfa67 100644 --- a/server/gameserver/creature.h +++ b/server/gameserver/creature.h @@ -39,6 +39,7 @@ class Obstacle; class RoomObstacle; class Hero; class Team; +class Car; class Creature : public MoveableEntity { public: @@ -135,6 +136,7 @@ class Creature : public MoveableEntity bool IsHuman() const; bool IsCar() const; Human* AsHuman() { return IsHuman() ? (Human*)this : nullptr; }; + Car* AsCar() { return IsCar() ? (Car*)this : nullptr; }; virtual void DecHP(float dec_hp, int killer_id, const std::string& killer_name, int weapon_id) {}; void AddHp(float hp); diff --git a/server/gameserver/frag_mitask.cc b/server/gameserver/frag_mitask.cc index 1d4cdd1..ca3eb3b 100644 --- a/server/gameserver/frag_mitask.cc +++ b/server/gameserver/frag_mitask.cc @@ -14,6 +14,9 @@ void FragMiTask::Done() if (!sender.Get()) { return; } + if (follow_target.Get()) { + bomb_pos = follow_target.Get()->GetPos(); + } room->frame_event.AddExplosionEx(sender, meta->i->id(), bomb_pos, diff --git a/server/gameserver/frag_mitask.h b/server/gameserver/frag_mitask.h index b402645..08683eb 100644 --- a/server/gameserver/frag_mitask.h +++ b/server/gameserver/frag_mitask.h @@ -16,6 +16,7 @@ class FragMiTask : public MicroTask Room* room = nullptr; a8::Vec2 bomb_pos; CreatureWeakPtr sender; + CreatureWeakPtr follow_target; MetaData::Equip* gun_meta = nullptr; MetaData::Equip* meta = nullptr; float atk = 0;