diff --git a/server/gameserver/bullet.cc b/server/gameserver/bullet.cc index 5ebdbf5..02721a8 100644 --- a/server/gameserver/bullet.cc +++ b/server/gameserver/bullet.cc @@ -132,7 +132,9 @@ void Bullet::ProcBomb() { //榴弹炮 a8::Vec2 bomb_pos = GetPos(); - room->frame_event.AddExplosionEx(sender, meta->i->id(), bomb_pos, + room->frame_event.AddExplosionEx(sender, + meta->i->id(), + bomb_pos, gun_meta->i->explosion_effect()); OnHit(objects); } diff --git a/server/gameserver/car.cc b/server/gameserver/car.cc index 7c0bca5..1e9a618 100644 --- a/server/gameserver/car.cc +++ b/server/gameserver/car.cc @@ -11,6 +11,7 @@ #include "perfmonitor.h" #include "typeconvert.h" #include "bullet.h" +#include "explosion.h" Car::Car():Creature() { @@ -334,7 +335,13 @@ void Car::BeKill(int killer_id, const std::string& killer_name, int weapon_id) passenger->RemoveBuffByEffectId(kBET_Passenger); room->frame_event.AddCarChg(passenger->GetWeakPtrRef()); } - Explosion(team_id); + Explosion explosion; + explosion.IndifferenceAttack( + room, + GetPos(), + meta->i->explosion_range(), + meta->i->atk(), + meta->i->explosion_effect()); } void Car::GetAabbBox(AabbCollider& aabb_box) @@ -347,46 +354,6 @@ void Car::GetAabbBox(AabbCollider& aabb_box) aabb_box._max.y = hero_meta_->i->radius(); } -void Car::Explosion(int team_id) -{ - if (meta->i->explosion_range() <= 0) { - return; - } - std::set objects; - TraverseProperTargetsNoTeammate - ( - [this, &objects, team_id] (Creature* c, bool& stop) - { - float distance = (c->GetPos() - GetPos()).Norm(); - if (distance < meta->i->explosion_range()) { - objects.insert(c); - } - }); - room->frame_event.AddExplosionEx(GetWeakPtrRef(), - 0, - GetPos(), - meta->i->explosion_effect()); - for (auto& target : objects) { - switch (target->GetEntityType()) { - case ET_Player: - { - Human* hum = (Human*)target; - if (!hum->dead) { - float dmg = meta->i->atk(); - float def = hum->ability.def; - float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K); - hum->DecHP(finaly_dmg, VP_Mine, TEXT("battle_server_killer_mine", "地雷"), VW_Mine); - } - } - break; - default: - { - } - break; - } - } -} - void Car::SendDebugMsg(const std::string& debug_msg) { #if 1 diff --git a/server/gameserver/car.h b/server/gameserver/car.h index 50052d3..36ddc4e 100644 --- a/server/gameserver/car.h +++ b/server/gameserver/car.h @@ -47,7 +47,6 @@ class Car : public Creature private: int AllocSeat(); void BeKill(int killer_id, const std::string& killer_name, int weapon_id); - void Explosion(int team_id); bool IsPassenger(Human* hum); private: long long born_frameno_ = 0; diff --git a/server/gameserver/constant.h b/server/gameserver/constant.h index c7f8843..e876b9e 100755 --- a/server/gameserver/constant.h +++ b/server/gameserver/constant.h @@ -347,6 +347,30 @@ enum OptResult kOptBreak = 2 }; +enum BulletHit_e +{ + kBulletHitPass = 1, + kBulletHitAnyDmg = 2, + kBulletHitOnlySpecDmg = 3, + kBulletHitEatDmg = 4, +}; + +enum CollisionHit_e +{ + kCollisionHitPass = 1, + kCollisionHitBlock = 2, + kCollisionHitDeadAndDrop = 3, + kCollisionHitSpecEvent = 4, +}; + +enum ExplosionHit_e +{ + kExplosionHitPass = 1, + kExplosionHitAnyDmg = 2, + kExplosionHitOnlySpecDmg = 3, + kExplosionHitEatDmg = 4, +}; + const char* const PROJ_NAME_FMT = "game%d_gameserver"; const char* const PROJ_ROOT_FMT = "/data/logs/%s"; diff --git a/server/gameserver/entity.h b/server/gameserver/entity.h index fd33088..1494a16 100644 --- a/server/gameserver/entity.h +++ b/server/gameserver/entity.h @@ -12,6 +12,7 @@ class AabbCollider; class CircleCollider; class Human; class Bullet; +class Explosion; class Entity { public: @@ -33,6 +34,7 @@ class Entity virtual void OnPreCollision(Room* room) {}; virtual void RecalcSelfCollider() {}; virtual void OnBulletHit(Bullet* bullet) {}; + virtual void OnExplosionHit(Explosion* explosion) {}; virtual void OnAddToTargetPartObject(Entity* target) {}; virtual void OnRemoveFromTargetPartObject(Entity* target) {}; virtual bool CanSeeMe(Human* hum) { return true; }; diff --git a/server/gameserver/explosion.cc b/server/gameserver/explosion.cc new file mode 100644 index 0000000..4fe45cf --- /dev/null +++ b/server/gameserver/explosion.cc @@ -0,0 +1,110 @@ +#include "precompile.h" + +#include "explosion.h" + +void Explosion::IndifferenceAttack(Room* room, + const a8::Vec2& center, + float range, + int explosion_effect, + float dmg) +{ +#if 0 + if (meta->i->explosion_range() <= 0) { + return; + } + std::set objects; + TraverseProperTargetsNoTeammate + ( + [this, &objects, team_id] (Creature* c, bool& stop) + { + float distance = (c->GetPos() - GetPos()).Norm(); + if (distance < meta->i->explosion_range()) { + objects.insert(c); + } + }); + room->frame_event.AddExplosionEx(GetWeakPtrRef(), + 0, + GetPos(), + meta->i->explosion_effect()); + for (auto& target : objects) { + switch (target->GetEntityType()) { + case ET_Player: + { + Human* hum = (Human*)target; + if (!hum->dead) { + float dmg = meta->i->atk(); + float def = hum->ability.def; + float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K); + hum->DecHP(finaly_dmg, VP_Mine, TEXT("battle_server_killer_mine", "地雷"), VW_Mine); + } + } + break; + default: + { + } + break; + } + } +#endif +} + +void Explosion::EnemyAndObstacleAttack(CreatureWeakPtr& sender, + const a8::Vec2& center, + float range, + int explosion_effect, + float dmg) +{ + #if 0 + if (!sender.Get()) { + return; + } + + if (follow_target.Get()) { + bomb_pos = follow_target.Get()->GetPos(); + } + room->frame_event.AddExplosionEx(sender, + meta->i->id(), + bomb_pos, + gun_meta->i->explosion_effect()); + std::set grid_list; + sender.Get()->room->grid_service->GetAllCellsByXy + ( + sender.Get()->room, + bomb_pos.x, + bomb_pos.y, + grid_list + ); + std::set objects; + sender.Get()->room->grid_service->TraverseCreatures + ( + sender.Get()->room->GetRoomIdx(), + grid_list, + [this, &objects] (Creature* c, bool& stop) + { + if (sender.Get()->IsProperTarget(c)) { + if (bomb_pos.Distance(c->GetPos()) < meta->i->explosion_range()) { + objects.insert(c); + } + } + } + ); + std::set entitys; + sender.Get()->room->grid_service->TraverseAllLayerEntityList + ( + sender.Get()->room->GetRoomIdx(), + grid_list, + [this, &entitys] (Entity* entity, bool& stop) + { + } + ); + + Explosion explosion; + for (auto& target : objects) { + target->OnExplosionHit(&explosion); + } + + for (auto& target : entitys) { + target->OnExplosionHit(&explosion); + } + #endif +} diff --git a/server/gameserver/explosion.h b/server/gameserver/explosion.h new file mode 100644 index 0000000..414697e --- /dev/null +++ b/server/gameserver/explosion.h @@ -0,0 +1,19 @@ +#pragma once + +#include "weakptr.h" + +class Room; +class Explosion +{ + public: + void IndifferenceAttack(Room* room, + const a8::Vec2& center, + float range, + int explosion_effect, + float dmg); + void EnemyAndObstacleAttack(CreatureWeakPtr& sender, + const a8::Vec2& center, + float range, + int explosion_effect, + float dmg); +}; diff --git a/server/gameserver/frag_mitask.cc b/server/gameserver/frag_mitask.cc index ca3eb3b..43e4d05 100644 --- a/server/gameserver/frag_mitask.cc +++ b/server/gameserver/frag_mitask.cc @@ -8,100 +8,19 @@ #include "gridservice.h" #include "creature.h" #include "obstacle.h" +#include "explosion.h" void FragMiTask::Done() { - if (!sender.Get()) { - return; - } + a8::Vec2 center = bomb_pos; if (follow_target.Get()) { bomb_pos = follow_target.Get()->GetPos(); } - room->frame_event.AddExplosionEx(sender, - meta->i->id(), - bomb_pos, - gun_meta->i->explosion_effect()); - std::set grid_list; - sender.Get()->room->grid_service->GetAllCellsByXy - ( - sender.Get()->room, - bomb_pos.x, - bomb_pos.y, - grid_list - ); - std::set objects; - sender.Get()->room->grid_service->TraverseCreatures - ( - sender.Get()->room->GetRoomIdx(), - grid_list, - [this, &objects] (Creature* c, bool& stop) - { - if (sender.Get()->IsProperTarget(c)) { - if (bomb_pos.Distance(c->GetPos()) < meta->i->explosion_range()) { - objects.insert(c); - } - } - } - ); - std::set entitys; - sender.Get()->room->grid_service->TraverseAllLayerEntityList - ( - sender.Get()->room->GetRoomIdx(), - grid_list, - [this, &entitys] (Entity* entity, bool& stop) - { - } - ); - - for (auto& target : objects) { - if (target->IsInvincible()) { - continue; - } - if (sender.Get()->room->GetRoomMode() == kZombieMode && - sender.Get()->GetRace() == target->GetRace()) { - continue; - } - if (!target->dead) { - float dmg = GetAtk() * (1 + sender.Get()->GetAttrRate(kHAT_Atk)) + - sender.Get()->GetAttrAbs(kHAT_Atk); - float def = target->ability.def * (1 + target->GetAttrRate(kHAT_Def)) + - target->GetAttrAbs(kHAT_Def); - float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K); - finaly_dmg = std::max(finaly_dmg, 0.0f); - target->DecHP(finaly_dmg, - sender.Get()->GetUniId(), - sender.Get()->GetName(), - gun_meta->i->id()); - } - } - - for (auto& target : entitys) { - if (target->GetEntityType() != ET_Obstacle) { - continue; - } - Obstacle* obstacle = (Obstacle*)target; - if (!obstacle->IsDead(room) && - obstacle->Attackable(sender.Get()) && - !obstacle->IsTerminatorAirDropBox(room)) { - float dmg = GetAtk() * (1 + sender.Get()->GetAttrRate(kHAT_Atk)) + - sender.Get()->GetAttrAbs(kHAT_Atk); - float def = 0; - float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K); - obstacle->SetHealth(room, std::max(0.0f, obstacle->GetHealth(room) - finaly_dmg)); - if (obstacle->GetHealth(room) <= 0.01f) { - obstacle->Die(room); - } - if (obstacle->IsDead(room)) { - if (obstacle->meta->i->damage_dia() > 0.01f && - obstacle->meta->i->damage() > 0.01f) { - #if 0 - obstacle->Explosion(this); - #endif - } - sender.Get()->DropItems(obstacle); - } - obstacle->BroadcastFullState(room); - } - } + Explosion explosion; + explosion.EnemyAndObstacleAttack(sender, + center, + meta->i->explosion_range(), + gun_meta->i->explosion_effect(), + GetAtk()); } diff --git a/server/gameserver/hero.cc b/server/gameserver/hero.cc index 21ccbe8..30afa18 100644 --- a/server/gameserver/hero.cc +++ b/server/gameserver/hero.cc @@ -165,7 +165,9 @@ bool Hero::IsCollisionInMapService() return true; } if (!obstacle->IsDead(room) && + #if 0 obstacle->Attackable(this) && + #endif 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 41176d1..a06d6ba 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -525,7 +525,9 @@ bool Human::IsCollisionInMapService() return true; } if (!obstacle->IsDead(room) && + #if 0 obstacle->Attackable(this) && + #endif obstacle->meta->i->drop() != 0 && obstacle->IsTouchInteraction() && room->GetGasData().gas_mode != GasInactive && @@ -3598,6 +3600,37 @@ void Human::OnBulletHit(Bullet* bullet) } } +void Human::OnExplosionHit(Explosion* explosion) +{ + if (IsInvincible()) { + return; + } + if (dead) { + return; + } +#if 0 + if (target->IsInvincible()) { + continue; + } + if (sender.Get()->room->GetRoomMode() == kZombieMode && + sender.Get()->GetRace() == target->GetRace()) { + continue; + } + if (!target->dead) { + float dmg = GetAtk() * (1 + sender.Get()->GetAttrRate(kHAT_Atk)) + + sender.Get()->GetAttrAbs(kHAT_Atk); + float def = target->ability.def * (1 + target->GetAttrRate(kHAT_Def)) + + target->GetAttrAbs(kHAT_Def); + float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K); + finaly_dmg = std::max(finaly_dmg, 0.0f); + target->DecHP(finaly_dmg, + sender.Get()->GetUniId(), + sender.Get()->GetName(), + gun_meta->i->id()); + } +#endif +} + void Human::SendRollMsgEx(KillInfo& info, const char* fmt, std::initializer_list args diff --git a/server/gameserver/human.h b/server/gameserver/human.h index 539cf4f..2311c02 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -141,6 +141,7 @@ class Human : public Creature virtual bool IsDead(Room* room) override; virtual long long GetDeadFrameNo(Room* room) override; virtual void OnBulletHit(Bullet* bullet) override; + virtual void OnExplosionHit(Explosion* explosion) override; void FillItemList(::google::protobuf::RepeatedPtrField<::cs::MFPair>* pb_item_list); long long GetRealDeadFrameNo(Room* room); void FillMFTeamData(cs::MFTeamData* team_data, bool is_game_over); diff --git a/server/gameserver/mapinstance.cc b/server/gameserver/mapinstance.cc index 929227c..bfa5927 100644 --- a/server/gameserver/mapinstance.cc +++ b/server/gameserver/mapinstance.cc @@ -356,6 +356,7 @@ Obstacle* MapInstance::InternalCreateObstacle(int id, float x, float y, int coll grid_service_->AddPermanentEntity(entity); } { + #if 0 switch (thing->i->attack_type()) { case 0: { @@ -377,6 +378,7 @@ Obstacle* MapInstance::InternalCreateObstacle(int id, float x, float y, int coll } break; } + #endif ++obstacle_num_; } return entity; diff --git a/server/gameserver/obstacle.cc b/server/gameserver/obstacle.cc index 78dc622..6297a3e 100644 --- a/server/gameserver/obstacle.cc +++ b/server/gameserver/obstacle.cc @@ -12,6 +12,7 @@ #include "perfmonitor.h" #include "roomobstacle.h" #include "loot.h" +#include "explosion.h" enum ObstacleDataFlags_e { @@ -108,7 +109,7 @@ void Obstacle::RecalcSelfCollider() collider->tag = collider_tag; collider->param1 = collider_param1; collider->param2 = collider_param2; - if (meta->i->attack_type() == 3) { + if (IsHalfWallCollider()) { a8::SetBitFlag(collider->tag, kHalfWallTag); } } @@ -289,112 +290,6 @@ void Obstacle::OnPreCollision(Room* room) } } -void Obstacle::Explosion(Bullet* bullet) -{ - Room* room = bullet->room; - float old_rad = self_collider_->rad; - if (self_collider_) { - self_collider_->rad = meta->i->damage_dia(); - } - if (meta->i->damage_dia() > 0.01f && - meta->i->damage() > 0.01f) { - std::set objects; - std::set tmp_grids; - room->grid_service->GetAllCellsByXy(room, GetX(), GetY(), tmp_grids); - room->grid_service->TraverseAllLayerHumanList - ( - room->GetRoomIdx(), - tmp_grids, - [this, room, &objects] (Human* hum, bool& stop) - { - if (TestCollision(room, hum)) { - objects.insert(hum); - } - }); - room->grid_service->TraverseAllLayerEntityList - ( - room->GetRoomIdx(), - tmp_grids, - [this, room, &objects] (Entity* entity, bool& stop) - { - switch (entity->GetEntityType()) { - case ET_Obstacle: - case ET_Building: - { - if (entity != this && TestCollision(room, entity)) { - objects.insert(entity); - } - } - break; - default: - { - } - break; - } - }); - a8::Vec2 bomb_pos = GetPos(); - #if 1 - room->frame_event.AddExplosionEx(bullet->sender, - meta->i->thing_id(), - bomb_pos, - meta->i->explosion_effect()); - #else - room->frame_event.AddExplosion(bullet, meta->i->thing_id(), bomb_pos); - #endif - for (auto& target : objects) { - switch (target->GetEntityType()) { - case ET_Player: - { - Human* hum = (Human*)target; - if (!hum->dead && hum->team_id != team_id_) { - float dmg = meta->i->damage(); - float def = hum->ability.def; - float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K); - if (GetMasterId(bullet->room)) { - Human* master = bullet->room->GetHumanByUniId(GetMasterId(bullet->room)); - if (master) { - hum->DecHP(finaly_dmg, master->GetUniId(), master->GetName(), VW_Mine); - } else { - hum->DecHP(finaly_dmg, VP_Mine, TEXT("battle_server_killer_mine", "地雷"), VW_Mine); - } - } else { - hum->DecHP(finaly_dmg, VP_Mine, TEXT("battle_server_killer_mine", "地雷"), VW_Mine); - } - } - } - break; - case ET_Obstacle: - { - Obstacle* obstacle = (Obstacle*)target; - if (!obstacle->IsDead(room) && - obstacle->Attackable(this) && - !obstacle->IsTerminatorAirDropBox(room)) { - float dmg = meta->i->damage(); - float def = 0; - float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K); - - obstacle->SetHealth(room, - std::max(0.0f, obstacle->health_ - finaly_dmg)); - if (obstacle->GetHealth(room) <= 0.01f) { - obstacle->Die(room); - } - if (obstacle->IsDead(room)) { - bullet->sender.Get()->DropItems(obstacle); - } - obstacle->BroadcastFullState(room); - } - } - break; - default: - break; - } - } - } - if (self_collider_) { - self_collider_->rad = old_rad; - } -} - void Obstacle::SetDoorInfo(Building* building, int door_id_x) { MetaData::Building::Door* door_meta = &building->meta->doors[door_id_x]; @@ -509,35 +404,11 @@ bool Obstacle::IsPermanent() return is_permanent; } -bool Obstacle::Attackable(Entity* sender) -{ - switch (meta->i->attack_type()) { - case 1: - { - return true; - } - break; - case 4: - { - //只有特定子弹 - 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() { + #if 0 return meta->i->attack_type() == 2; + #endif } int Obstacle::GetTeamId(Room* room) @@ -599,7 +470,6 @@ void Obstacle::SetMasterId(Room* room, int master_id) void Obstacle::OnBulletHit(Bullet* bullet) { if (!IsDead(bullet->room) && - Attackable(bullet) && !IsTerminatorAirDropBox(bullet->room)) { if (meta->receive_special_damage_type != 0 && ((bullet->gun_meta->special_damage_type & meta->receive_special_damage_type) == 0)) { @@ -640,7 +510,13 @@ void Obstacle::OnBulletHit(Bullet* bullet) if (IsDead(bullet->room)) { if (meta->i->damage_dia() > 0.01f && meta->i->damage() > 0.01f) { - Explosion(bullet); + Explosion explosion; + explosion.IndifferenceAttack( + bullet->room, + GetPos(), + meta->i->damage_dia(), + meta->i->damage(), + meta->i->explosion_effect()); } bullet->sender.Get()->DropItems(this); } @@ -658,20 +534,62 @@ void Obstacle::OnBulletHit(Bullet* bullet) } } +void Obstacle::OnExplosionHit(Explosion* e) +{ +#if 0 + if (!target->IsEntityType(Obstacle)) { + continue; + } + Obstacle* obstacle = (Obstacle*)target; + if (obstacle->IsDead(room)) { + continue; + } + if (obstacle->meta->i->explosion_hit() == kExplosionHitPass || + obstacle->meta->i->explosion_hit() == kExplosionHitEatDmg) { + continue; + } + if (obstacle->Attackable(sender.Get()) && + !obstacle->IsTerminatorAirDropBox(room)) { + float dmg = GetAtk() * (1 + sender.Get()->GetAttrRate(kHAT_Atk)) + + sender.Get()->GetAttrAbs(kHAT_Atk); + float def = 0; + float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K); + obstacle->SetHealth(room, std::max(0.0f, obstacle->GetHealth(room) - finaly_dmg)); + if (obstacle->GetHealth(room) <= 0.01f) { + obstacle->Die(room); + } + if (obstacle->IsDead(room)) { + if (obstacle->meta->i->damage_dia() > 0.01f && + obstacle->meta->i->damage() > 0.01f) { + #if 0 + obstacle->Explosion(this); + #endif + } + sender.Get()->DropItems(obstacle); + } + obstacle->BroadcastFullState(room); + } +#endif +} + bool Obstacle::CanThroughable(Creature* c) { + #if 0 if (meta->i->attack_type() == 4) { return true; } + #endif return false; } bool Obstacle::CanThroughable(Bullet* bullet) { + #if 0 if (meta->i->attack_type() == 4) { return !(meta->receive_special_damage_type != 0 && ((bullet->gun_meta->special_damage_type & meta->receive_special_damage_type) != 0)); } + #endif return false; } @@ -744,7 +662,9 @@ void Obstacle::OnCollisionTrigger(Creature* c, OptResult& opt_result) { if (c->team_id != GetTeamId(c->room)) { AddObstacleBuff(c); + #if 0 Explosion(); + #endif Die(c->room); BroadcastFullState(c->room); } @@ -858,3 +778,9 @@ bool Obstacle::CanSeeMe(Human* hum) break; } } + +bool Obstacle::IsHalfWallCollider() +{ + return meta->i->collision_hit() == kCollisionHitPass && + meta->i->bullet_hit() != kBulletHitPass; +} diff --git a/server/gameserver/obstacle.h b/server/gameserver/obstacle.h index dd43753..2f4288a 100644 --- a/server/gameserver/obstacle.h +++ b/server/gameserver/obstacle.h @@ -42,14 +42,13 @@ class Obstacle : public Entity virtual long long GetDeadFrameNo(Room* room) override; virtual void OnPreCollision(Room* room) override; virtual void OnBulletHit(Bullet* bullet) override; + virtual void OnExplosionHit(Explosion* explosion) override; virtual bool IsTerminatorAirDropBox(Room* room) { return false; } virtual bool CanThroughable(Creature* c); virtual bool CanThroughable(Bullet* bullet); virtual bool DoInteraction(Human* sender); virtual void OnCollisionTrigger(Creature* c, OptResult& opt_result); - virtual void Explosion() {}; virtual bool CanSeeMe(Human* hum); - void Explosion(Bullet* bullet); void SetDoorInfo(Building* building, int door_id_x); bool IsDoor(); DoorState_e GetDoorState(Room* room); @@ -67,7 +66,6 @@ class Obstacle : public Entity int GetMasterId(Room* room); void SetMasterId(Room* room, int master_id); bool IsPermanent(); - bool Attackable(Entity* sender); bool Throughable(); bool IsTouchInteraction(); bool IsOpenInteraction(); @@ -80,6 +78,7 @@ protected: std::tuple* GetInteractionData(Human* sender); void AddObstacleBuff(Creature* c); void ClearObstacleBuff(Creature* c); + bool IsHalfWallCollider(); protected: CircleCollider* self_collider_ = nullptr; diff --git a/server/gameserver/roomobstacle.cc b/server/gameserver/roomobstacle.cc index 0f52da7..d51530b 100644 --- a/server/gameserver/roomobstacle.cc +++ b/server/gameserver/roomobstacle.cc @@ -10,6 +10,7 @@ #include "bullet.h" #include "mapservice.h" #include "roomobstacle.h" +#include "explosion.h" RoomObstacle::RoomObstacle():Obstacle() { @@ -94,7 +95,7 @@ void RoomObstacle::RecalcSelfCollider() collider->tag = collider_tag; collider->param1 = collider_param1; collider->param2 = collider_param2; - if (meta->i->attack_type() == 3) { + if (IsHalfWallCollider()) { a8::SetBitFlag(collider->tag, kHalfWallTag); } } @@ -163,8 +164,16 @@ void RoomObstacle::UpdateTimerFunc() } } } - Explosion(); Die(room); + { + Explosion explosion; + explosion.IndifferenceAttack( + room, + GetPos(), + meta->i->damage_dia(), + meta->i->damage(), + meta->i->explosion_effect()); + } BroadcastFullState(room); if (room->xtimer.GetRunningTimer()) { room->xtimer.DeleteTimer(room->xtimer.GetRunningTimer()); @@ -175,102 +184,6 @@ void RoomObstacle::UpdateTimerFunc() } } -void RoomObstacle::Explosion() -{ - float old_rad = self_collider_->rad; - if (self_collider_) { - self_collider_->rad = meta->i->damage_dia(); - } - if (meta->i->damage_dia() > 0.01f && - meta->i->damage() > 0.01f) { - std::set objects; - room->grid_service->TraverseAllLayerHumanList - ( - room->GetRoomIdx(), - *grid_list_, - [this, &objects] (Human* hum, bool& stop) - { - if (master.Get()->team_id != hum->team_id && TestCollision(room, hum)) { - objects.insert(hum); - } - }); - room->grid_service->TraverseAllLayerEntityList - ( - room->GetRoomIdx(), - *grid_list_, - [this, &objects] (Entity* entity, bool& stop) - { - switch (entity->GetEntityType()) { - case ET_Obstacle: - case ET_Building: - { - if (entity != this && TestCollision(room, entity)) { - objects.insert(entity); - } - } - break; - default: - { - } - break; - } - }); - a8::Vec2 bomb_pos = GetPos(); - room->frame_event.AddExplosionEx(master, - meta->i->thing_id(), - bomb_pos, - meta->i->explosion_effect()); - for (auto& target : objects) { - switch (target->GetEntityType()) { - case ET_Player: - { - Human* hum = (Human*)target; - if (!hum->dead) { - float dmg = meta->i->damage(); - float def = hum->ability.def; - float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K); - if (master.Get()) { - hum->DecHP(finaly_dmg, master.Get()->GetUniId(), master.Get()->GetName(), VW_Mine); - } else { - hum->DecHP(finaly_dmg, VP_Mine, TEXT("battle_server_killer_mine", "地雷"), VW_Mine); - } - } - } - break; - case ET_Obstacle: - { - Obstacle* obstacle = (Obstacle*)target; - if (!obstacle->IsDead(room) && - obstacle->Attackable(this) && - !obstacle->IsTerminatorAirDropBox(room)) { - float dmg = meta->i->damage(); - float def = 0; - float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K); - - obstacle->SetHealth(room, - std::max(0.0f, obstacle->GetHealth(room) - finaly_dmg)); - if (obstacle->GetHealth(room) <= 0.01f) { - obstacle->Die(room); - } - if (obstacle->IsDead(room)) { - #if 0 - bullet->player->DropItems(obstacle); - #endif - } - obstacle->BroadcastFullState(room); - } - } - break; - default: - break; - } - } - } - if (self_collider_) { - self_collider_->rad = old_rad; - } -} - void RoomObstacle::SpecExplosion() { ++explosion_times_; @@ -284,58 +197,13 @@ 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; - std::set objects; - Creature* dumy_c = nullptr; - room->grid_service->TraverseAllLayerHumanList - ( - room->GetRoomIdx(), - *grid_list_, - [this, &objects, &bomb_pos, &dumy_c] (Human* hum, bool& stop) - { - if (!dumy_c) { - dumy_c = hum; - } - float distance = (hum->GetPos() - bomb_pos).Norm(); - if ((!master.Get() || master.Get()->team_id != hum->team_id) && - distance < meta->i->damage_dia()) { - dumy_c = hum; - objects.insert(hum); - } - }); - if (dumy_c) { - room->frame_event.AddExplosionEx(dumy_c->GetWeakPtrRef(), - meta->i->thing_id(), - bomb_pos, - meta->i->explosion_effect()); - } - for (auto& target : objects) { - switch (target->GetEntityType()) { - case ET_Player: - { - Human* hum = (Human*)target; - if (!hum->dead) { - float dmg = meta->i->damage(); - float def = hum->ability.def; - float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K); - hum->DecHP(finaly_dmg, VP_Mine, TEXT("battle_server_killer_mine", "地雷"), VW_Mine); - - for (int buff_id : meta->buff_list) { - MetaData::Buff* buff_meta = MetaMgr::Instance()->GetBuff(buff_id); - if (buff_meta) { - hum->AddBuff(master.Get(), - buff_meta, - 1); - } - } - } - } - break; - default: - { - } - break; - } - } + Explosion explosion; + explosion.IndifferenceAttack( + room, + bomb_pos, + meta->i->damage_dia(), + meta->i->damage(), + meta->i->explosion_effect()); } if (explosion_times_ >= meta->i->explosion_times()) { room->xtimer.DeleteTimer(room->xtimer.GetRunningTimer()); diff --git a/server/gameserver/roomobstacle.h b/server/gameserver/roomobstacle.h index 48fb3aa..44e4919 100644 --- a/server/gameserver/roomobstacle.h +++ b/server/gameserver/roomobstacle.h @@ -25,7 +25,6 @@ class RoomObstacle : public Obstacle void Active(); void DetachFromMaster(); virtual void Die(Room* room) override; - virtual void Explosion() override; Entity* GetRealObject(Room* room); private: diff --git a/server/tools/protobuild/metatable.proto b/server/tools/protobuild/metatable.proto index b4afae2..36379e0 100755 --- a/server/tools/protobuild/metatable.proto +++ b/server/tools/protobuild/metatable.proto @@ -52,7 +52,6 @@ message MapThing optional float damage = 6; //伤害 optional float damage_dia = 7; //伤害半径 optional int32 drop = 8; //掉落 - optional int32 attack_type = 9; //是否可攻击 0:不可破坏对象 1:可破坏对象 2:可穿透对象 optional int32 is_door = 10; //是否门 optional int32 is_house = 11; //是否房间 optional int32 is_tree = 12; //是否树