From f6f7b78edf45399c292b4b88deb4071d3d63de88 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Wed, 17 Mar 2021 16:59:31 +0800 Subject: [PATCH] 1 --- server/gameserver/gridcell.cc | 1 + server/gameserver/hero.ai.cc | 19 +---- server/gameserver/hero.cc | 134 ++++++++++++++++++++++++++++++++++ server/gameserver/hero.h | 19 ++++- server/gameserver/human.cc | 29 ++++---- server/gameserver/human.h | 2 +- server/gameserver/room.cc | 1 + 7 files changed, 172 insertions(+), 33 deletions(-) diff --git a/server/gameserver/gridcell.cc b/server/gameserver/gridcell.cc index 160cfa1..e0b1d7a 100644 --- a/server/gameserver/gridcell.cc +++ b/server/gameserver/gridcell.cc @@ -18,6 +18,7 @@ GridCell::GridCell() entity_list_.push_back(std::set()); bullet_list_.push_back(std::set()); car_list_.push_back(std::set()); + hero_list_.push_back(std::set()); } } diff --git a/server/gameserver/hero.ai.cc b/server/gameserver/hero.ai.cc index 242927f..556c779 100644 --- a/server/gameserver/hero.ai.cc +++ b/server/gameserver/hero.ai.cc @@ -238,26 +238,14 @@ void HeroAI::DoMoveAI() Hero* hero = (Hero*)owner; if (std::abs(hero->move_dir.x) > FLT_EPSILON || std::abs(hero->move_dir.y) > FLT_EPSILON) { - #if 0 - hum->on_move_collision = + hero->on_move_collision = [this] () { ChangeToStateAI(HSE_RandomWalk); return false; }; - #endif int speed = std::max(1, (int)hero->GetSpeed()) * 1; - #if 0 - hum->_UpdateMove(speed); - hum->on_move_collision = nullptr; - if (node_.nearest_human) { - if (node_.main_state != HSE_Pursuit && - hum->GetPos().ManhattanDistance(node_.nearest_human->GetPos()) < 200) { - ChangeToStateAI(HSE_Thinking); - } else if (hum->GetPos().ManhattanDistance(node_.nearest_human->GetPos()) > 800) { - GetTarget(); - } - } - #endif + hero->UpdateMove(speed); + hero->on_move_collision = nullptr; } } @@ -450,5 +438,6 @@ int HeroAI::GetAttackTimes() return ai_meta->i->attack_times(); } #endif + return 0; } diff --git a/server/gameserver/hero.cc b/server/gameserver/hero.cc index 6d2a4e1..e48a666 100644 --- a/server/gameserver/hero.cc +++ b/server/gameserver/hero.cc @@ -7,6 +7,9 @@ #include "loot.h" #include "perfmonitor.h" #include "typeconvert.h" +#include "hero.ai.h" +#include "obstacle.h" +#include "collider.h" Hero::Hero():MoveableEntity() { @@ -21,6 +24,10 @@ Hero::~Hero() void Hero::Initialize() { MoveableEntity::Initialize(); + RecalcSelfCollider(); + ai = new HeroAI; + ai->owner = this; + ai->SetAiLevel(8); } void Hero::FillMFObjectPart(Room* room, Human* hum, cs::MFObjectPart* part_data) @@ -45,9 +52,23 @@ void Hero::FillMFObjectFull(Room* room, Human* hum, cs::MFObjectFull* full_data) void Hero::Update(int delta_time) { + ai->Update(delta_time); ++updated_times_; } +void Hero::GetAabbBox(AabbCollider& aabb_box) +{ + if (!meta) { + abort(); + } + aabb_box.active = true; + aabb_box.owner = this; + aabb_box._min.x = -meta->i->radius(); + aabb_box._min.y = -meta->i->radius(); + aabb_box._max.x = meta->i->radius(); + aabb_box._max.y = meta->i->radius(); +} + bool Hero::HasBuffEffect(int buff_effect_id) { return false; @@ -62,3 +83,116 @@ float Hero::GetSpeed() { return 3; } + +void Hero::UpdateMove(int speed) +{ + do { + int distance = std::min(5, speed); + InternalUpdateMove(distance); + speed -= distance; + } while (speed > 0); +} + +void Hero::InternalUpdateMove(float speed) +{ + a8::Vec2 old_pos = GetPos(); + a8::Vec2 new_pos = GetPos() + move_dir * speed; + + SetPos(new_pos); + if (!IsCollisionInMapService()) { + room->grid_service->MoveHero(this); + } else { + if (on_move_collision && !on_move_collision()) { + SetPos(old_pos); + } + } +} + +bool Hero::IsCollisionInMapService() +{ + if (room->OverBorder(GetPos(), meta->i->radius())){ + return true; + } + if (HasBuffEffect(kBET_ThroughWall)) { + return false; + } + + std::set colliders; + room->map_service->GetColliders(room, GetX(), GetY(), colliders); + + AabbCollider aabb_box; + GetAabbBox(aabb_box); + for (ColliderComponent* collider : colliders) { + switch (collider->owner->GetEntityType()) { + case ET_Obstacle: + { + Obstacle* obstacle = (Obstacle*)collider->owner; + if (!obstacle->IsDead(room) && + ( + (collider->type == CT_Aabb && aabb_box.Intersect((ColliderComponent*)collider)) || + (collider->type == CT_Circle && self_collider_->Intersect((ColliderComponent*)collider)) + ) + ) { + if (last_collision_door_ != collider->owner) { + if (!obstacle->IsDead(room) && + obstacle->Attackable() && + obstacle->meta->i->drop() != 0 && + room->GetGasData().gas_mode != GasInactive && + (!obstacle->IsTerminatorAirDropBox(room)) + ) { + obstacle->Die(room); + if (obstacle->IsDead(room)) { + #if 0 + DropItems(obstacle); + #endif + } + obstacle->BroadcastFullState(room); + if (obstacle->IsTerminatorAirDropBox(room) && + !HasBuffEffect(kBET_Terminator)) { + MetaData::Buff* buff_meta = MetaMgr::Instance()->GetBuff(TERMINATOR_BUFF_ID); + if (buff_meta) { + #if 0 + AddBuff(this, buff_meta, 1); + #endif + } + } + } else { + Global::last_collider = collider; + return true; + } + } + } + } + break; + case ET_Building: + { + if ( + ( + (collider->type == CT_Aabb && aabb_box.Intersect((ColliderComponent*)collider)) || + (collider->type == CT_Circle && self_collider_->Intersect((ColliderComponent*)collider)) + ) + ) { + if (last_collision_door_ != collider->owner) { + Global::last_collider = collider; + return true; + } + } + } + break; + default: + break; + } + } + return false; +} + +void Hero::RecalcSelfCollider() +{ + if (!self_collider_) { + self_collider_ = new CircleCollider(); + self_collider_->owner = this; + AddEntityCollider(self_collider_); + } + self_collider_->pos = a8::Vec2(); + self_collider_->rad = meta->i->radius(); +} diff --git a/server/gameserver/hero.h b/server/gameserver/hero.h index 962dc44..c20a322 100644 --- a/server/gameserver/hero.h +++ b/server/gameserver/hero.h @@ -12,15 +12,17 @@ namespace MetaData class Human; class Room; class Buff; +class HeroAI; class Hero : public MoveableEntity { - public: +public: Entity* master = nullptr; MetaData::Player* meta = nullptr; bool dead = false; bool shot_hold = false; int team_id = 0; a8::Vec2 attack_dir; + std::function on_move_collision; Hero(); virtual ~Hero() override; @@ -29,11 +31,22 @@ class Hero : public MoveableEntity virtual void FillMFObjectFull(Room* room, Human* hum, cs::MFObjectFull* full_data) override; virtual void Update(int delta_time) override; + virtual void GetAabbBox(AabbCollider& aabb_box) override; + bool HasBuffEffect(int buff_effect_id); Buff* GetBuffByEffectId(int effect_id); float GetSpeed(); - private: - bool later_removed_ = false; +protected: + void UpdateMove(int speed); + void InternalUpdateMove(float speed); + bool IsCollisionInMapService(); + void RecalcSelfCollider(); +private: + bool later_removed_ = false; + CircleCollider* self_collider_ = nullptr; + Entity* last_collision_door_ = nullptr; + + friend class HeroAI; }; diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index bb04f93..4f404da 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -1325,19 +1325,6 @@ void Human::DoJump() MustBeAddBuff(this, JUMP_BUFFID); jump_frameno_ = room->GetFrameNo(); SyncAroundPlayers(__FILE__, __LINE__, __func__); - MetaData::Buff* buff_meta = MetaMgr::Instance()->GetBuff(JUMP_BUFFID); - if (buff_meta) { - room->xtimer.AddDeadLineTimerAndAttach - (buff_meta->i->duration_time() * SERVER_FRAME_RATE, - a8::XParams() - .SetSender(this), - [] (const a8::XParams& param) - { - Human* hum = (Human*)param.sender.GetUserData(); - hum->OnLand(); - }, - &xtimer_attacher.timer_list_); - } } } @@ -1767,7 +1754,15 @@ void Human::FillItemList(::google::protobuf::RepeatedPtrField<::cs::MFPair>* pb_ void Human::SummonHero(int heroid) { - + MetaData::Player* hero_meta = MetaMgr::Instance()->GetPlayer(heroid); + if (hero_meta) { + Hero* hero = room->CreateHero + (this, + hero_meta, + GetPos(), + move_dir + ); + } } void Human::AddObserver(Human* observer) @@ -4343,6 +4338,12 @@ void Human::OnLand() } SetPos(old_pos); } + #ifdef DEBUG + if (IsPlayer()) { + SummonHero(6001); + a8::XPrintf("Summon Hero\n", {}); + } + #endif } void Human::NextReload(int prev_weapon_id, int prev_weapon_idx) diff --git a/server/gameserver/human.h b/server/gameserver/human.h index 2cdfcac..ad88004 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -168,7 +168,7 @@ class Human : public MoveableEntity void FillMFObjectLess(Room* room, Human* hum, cs::MFPlayerFull* full_data); virtual void FillMFObjectFull(Room* room, Human* hum, cs::MFObjectFull* full_data) override; virtual void FillMFPlayerStats(cs::MFPlayerStats* stats); - virtual void GetAabbBox(AabbCollider& aabb_box); + virtual void GetAabbBox(AabbCollider& aabb_box) override; virtual bool IsDead(Room* room) override; virtual long long GetDeadFrameNo(Room* room) override; long long GetRealDeadFrameNo(Room* room); diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index 4bb8a28..e35a734 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -583,6 +583,7 @@ Hero* Room::CreateHero(Entity* master, hero->move_dir = dir; hero->Initialize(); AddToEntityHash(hero); + AddToMoveableHash(hero); grid_service->AddHero(hero); hero->RefreshView(); return hero;