diff --git a/server/gameserver/bullet.cc b/server/gameserver/bullet.cc index 02721a8..da36d76 100644 --- a/server/gameserver/bullet.cc +++ b/server/gameserver/bullet.cc @@ -313,15 +313,13 @@ 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 (collider->owner->IsEntityType(ET_Obstacle)) { - Obstacle* obstacle = (Obstacle*)collider->owner; - if (obstacle->CanThroughable(this)) { - continue; + if (collider->owner->IsEntityType(ET_Obstacle)) { + Obstacle* obstacle = (Obstacle*)collider->owner; + if (!obstacle->CanThroughable(this)) { + if (TestCollision(room, collider)) { + objects.insert(collider->owner); } } - objects.insert(collider->owner); } } } diff --git a/server/gameserver/car.cc b/server/gameserver/car.cc index 31e1e8d..f0b4cef 100644 --- a/server/gameserver/car.cc +++ b/server/gameserver/car.cc @@ -12,6 +12,7 @@ #include "typeconvert.h" #include "bullet.h" #include "explosion.h" +#include "obstacle.h" Car::Car():Creature() { @@ -343,6 +344,7 @@ void Car::BeKill(int killer_id, const std::string& killer_name, int weapon_id) meta->i->explosion_effect(), meta->i->atk() ); + room->NotifyUiUpdate(); } void Car::GetAabbBox(AabbCollider& aabb_box) @@ -392,3 +394,10 @@ float Car::GetMaxOil() { return meta->i->max_oil(); } + +void Car::DropItems(Obstacle* obstacle) +{ + if (obstacle->meta->i->drop() != 0) { + room->ScatterDrop(obstacle->GetPos(), obstacle->meta->i->drop()); + } +} diff --git a/server/gameserver/car.h b/server/gameserver/car.h index 36ddc4e..a7edae4 100644 --- a/server/gameserver/car.h +++ b/server/gameserver/car.h @@ -43,6 +43,7 @@ class Car : public Creature virtual void DecHP(float dec_hp, int killer_id, const std::string& killer_name, int weapon_id) override; virtual void SendDebugMsg(const std::string& debug_msg) override; virtual void SetAttackDir(const a8::Vec2& attack_dir) override; + virtual void DropItems(Obstacle* obstacle) override; private: int AllocSeat(); diff --git a/server/gameserver/explosion.cc b/server/gameserver/explosion.cc index 2918cbb..68b16e5 100644 --- a/server/gameserver/explosion.cc +++ b/server/gameserver/explosion.cc @@ -73,6 +73,9 @@ void Explosion::InternalAttack() grid_list, [this, &objects] (Creature* c, bool& stop) { + if (c->GetUniId() == exclude_uniid) { + return; + } if (!c->Attackable(room_)) { return; } @@ -98,6 +101,9 @@ void Explosion::InternalAttack() grid_list, [this, &objects] (Entity* entity, bool& stop) { + if (entity->GetUniId() == exclude_uniid) { + return; + } if (!entity->Attackable(room_)) { return; } diff --git a/server/gameserver/explosion.h b/server/gameserver/explosion.h index 92b3966..4856975 100644 --- a/server/gameserver/explosion.h +++ b/server/gameserver/explosion.h @@ -6,6 +6,7 @@ class Room; class Explosion { public: + int exclude_uniid = 0; Room* GetRoom() { return room_; }; CreatureWeakPtr GetSender() { return sender_; }; diff --git a/server/gameserver/obstacle.cc b/server/gameserver/obstacle.cc index 3b464f4..d730135 100644 --- a/server/gameserver/obstacle.cc +++ b/server/gameserver/obstacle.cc @@ -469,6 +469,9 @@ void Obstacle::SetMasterId(Room* room, int master_id) void Obstacle::OnBulletHit(Bullet* bullet) { + if (meta->i->bullet_hit() == kBulletHitEatDmg) { + return; + } if (!IsDead(bullet->room) && !IsTerminatorAirDropBox(bullet->room)) { if (meta->receive_special_damage_type != 0 && @@ -510,6 +513,17 @@ void Obstacle::OnBulletHit(Bullet* bullet) if (IsDead(bullet->room)) { ProcDieExplosion(bullet->room); bullet->sender.Get()->DropItems(this); + if (meta->i->thing_type() == kObstacleOilBucket) { + MetaData::MapThing* bomb_meta = MetaMgr::Instance()->GetMapThing(meta->int_param1); + if (bomb_meta) { + RoomObstacle* obstacle = bullet->room->CreateObstacle + ( + bomb_meta->i->thing_id(), + GetPos().x, + GetPos().y + ); + } + } } BroadcastFullState(bullet->room); #ifdef DEBUG @@ -553,6 +567,17 @@ void Obstacle::OnExplosionHit(Explosion* e) if (meta->i->drop() != 0) { e->GetRoom()->ScatterDrop(GetPos(), meta->i->drop()); } + if (meta->i->thing_type() == kObstacleOilBucket) { + MetaData::MapThing* bomb_meta = MetaMgr::Instance()->GetMapThing(meta->int_param1); + if (bomb_meta) { + RoomObstacle* obstacle = e->GetRoom()->CreateObstacle + ( + bomb_meta->i->thing_id(), + GetPos().x, + GetPos().y + ); + } + } } BroadcastFullState(e->GetRoom()); } diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index 3f9538a..a76f37f 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -3969,14 +3969,16 @@ void Room::AirRaid(int airraid_id) ); a8::Vec2 dir = a8::Vec2::UP; dir.Rotate(a8::RandAngle()); - a8::Vec2 pos = center + dir * (50 + rand() % 100);; - RoomObstacle* obstacle = room->CreateObstacle - ( - raid_meta->i->bomb_id(), - pos.x, - pos.y - ); - obstacle->Active(); + a8::Vec2 pos = center + dir * (50 + rand() % 100); + if (room->grid_service->CanAdd(pos.x, pos.y)) { + RoomObstacle* obstacle = room->CreateObstacle + ( + raid_meta->i->bomb_id(), + pos.x, + pos.y + ); + obstacle->Active(); + } }; Room* room = (Room*)param.sender.GetUserData(); if (room->IsGameOver()) { diff --git a/server/gameserver/roomobstacle.cc b/server/gameserver/roomobstacle.cc index af8a9ec..75531e4 100644 --- a/server/gameserver/roomobstacle.cc +++ b/server/gameserver/roomobstacle.cc @@ -183,14 +183,17 @@ void RoomObstacle::SpecExplosion() bomb_born_offset.Rotate(a8::RandAngle()); bomb_born_offset = bomb_born_offset * a8::RandEx(1, std::max(2, meta->i->explosion_float())); a8::Vec2 bomb_pos = GetPos() + bomb_born_offset; - Explosion explosion; - explosion.IndifferenceAttack( - room, - bomb_pos, - meta->i->damage_dia(), - meta->i->explosion_effect(), - meta->i->damage() - ); + if (room->grid_service->CanAdd(bomb_pos.x, bomb_pos.y)) { + Explosion explosion; + explosion.exclude_uniid = GetUniId(); + explosion.IndifferenceAttack( + room, + bomb_pos, + meta->i->damage_dia(), + meta->i->explosion_effect(), + meta->i->damage() + ); + } } if (explosion_times_ >= meta->i->explosion_times()) { room->xtimer.DeleteTimer(room->xtimer.GetRunningTimer());