This commit is contained in:
aozhiwei 2021-03-17 16:59:31 +08:00
parent 8dd5ae9d58
commit f6f7b78edf
7 changed files with 172 additions and 33 deletions

View File

@ -18,6 +18,7 @@ GridCell::GridCell()
entity_list_.push_back(std::set<Entity*>()); entity_list_.push_back(std::set<Entity*>());
bullet_list_.push_back(std::set<Bullet*>()); bullet_list_.push_back(std::set<Bullet*>());
car_list_.push_back(std::set<Car*>()); car_list_.push_back(std::set<Car*>());
hero_list_.push_back(std::set<Hero*>());
} }
} }

View File

@ -238,26 +238,14 @@ void HeroAI::DoMoveAI()
Hero* hero = (Hero*)owner; Hero* hero = (Hero*)owner;
if (std::abs(hero->move_dir.x) > FLT_EPSILON || if (std::abs(hero->move_dir.x) > FLT_EPSILON ||
std::abs(hero->move_dir.y) > FLT_EPSILON) { std::abs(hero->move_dir.y) > FLT_EPSILON) {
#if 0 hero->on_move_collision =
hum->on_move_collision =
[this] () { [this] () {
ChangeToStateAI(HSE_RandomWalk); ChangeToStateAI(HSE_RandomWalk);
return false; return false;
}; };
#endif
int speed = std::max(1, (int)hero->GetSpeed()) * 1; int speed = std::max(1, (int)hero->GetSpeed()) * 1;
#if 0 hero->UpdateMove(speed);
hum->_UpdateMove(speed); hero->on_move_collision = nullptr;
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
} }
} }
@ -450,5 +438,6 @@ int HeroAI::GetAttackTimes()
return ai_meta->i->attack_times(); return ai_meta->i->attack_times();
} }
#endif #endif
return 0;
} }

View File

@ -7,6 +7,9 @@
#include "loot.h" #include "loot.h"
#include "perfmonitor.h" #include "perfmonitor.h"
#include "typeconvert.h" #include "typeconvert.h"
#include "hero.ai.h"
#include "obstacle.h"
#include "collider.h"
Hero::Hero():MoveableEntity() Hero::Hero():MoveableEntity()
{ {
@ -21,6 +24,10 @@ Hero::~Hero()
void Hero::Initialize() void Hero::Initialize()
{ {
MoveableEntity::Initialize(); MoveableEntity::Initialize();
RecalcSelfCollider();
ai = new HeroAI;
ai->owner = this;
ai->SetAiLevel(8);
} }
void Hero::FillMFObjectPart(Room* room, Human* hum, cs::MFObjectPart* part_data) 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) void Hero::Update(int delta_time)
{ {
ai->Update(delta_time);
++updated_times_; ++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) bool Hero::HasBuffEffect(int buff_effect_id)
{ {
return false; return false;
@ -62,3 +83,116 @@ float Hero::GetSpeed()
{ {
return 3; 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<ColliderComponent*> 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();
}

View File

@ -12,6 +12,7 @@ namespace MetaData
class Human; class Human;
class Room; class Room;
class Buff; class Buff;
class HeroAI;
class Hero : public MoveableEntity class Hero : public MoveableEntity
{ {
public: public:
@ -21,6 +22,7 @@ class Hero : public MoveableEntity
bool shot_hold = false; bool shot_hold = false;
int team_id = 0; int team_id = 0;
a8::Vec2 attack_dir; a8::Vec2 attack_dir;
std::function<bool ()> on_move_collision;
Hero(); Hero();
virtual ~Hero() override; 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 FillMFObjectFull(Room* room, Human* hum, cs::MFObjectFull* full_data) override;
virtual void Update(int delta_time) override; virtual void Update(int delta_time) override;
virtual void GetAabbBox(AabbCollider& aabb_box) override;
bool HasBuffEffect(int buff_effect_id); bool HasBuffEffect(int buff_effect_id);
Buff* GetBuffByEffectId(int effect_id); Buff* GetBuffByEffectId(int effect_id);
float GetSpeed(); float GetSpeed();
protected:
void UpdateMove(int speed);
void InternalUpdateMove(float speed);
bool IsCollisionInMapService();
void RecalcSelfCollider();
private: private:
bool later_removed_ = false; bool later_removed_ = false;
CircleCollider* self_collider_ = nullptr;
Entity* last_collision_door_ = nullptr;
friend class HeroAI;
}; };

View File

@ -1325,19 +1325,6 @@ void Human::DoJump()
MustBeAddBuff(this, JUMP_BUFFID); MustBeAddBuff(this, JUMP_BUFFID);
jump_frameno_ = room->GetFrameNo(); jump_frameno_ = room->GetFrameNo();
SyncAroundPlayers(__FILE__, __LINE__, __func__); 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) 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) void Human::AddObserver(Human* observer)
@ -4343,6 +4338,12 @@ void Human::OnLand()
} }
SetPos(old_pos); 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) void Human::NextReload(int prev_weapon_id, int prev_weapon_idx)

View File

@ -168,7 +168,7 @@ class Human : public MoveableEntity
void FillMFObjectLess(Room* room, Human* hum, cs::MFPlayerFull* full_data); void FillMFObjectLess(Room* room, Human* hum, cs::MFPlayerFull* full_data);
virtual void FillMFObjectFull(Room* room, Human* hum, cs::MFObjectFull* full_data) override; virtual void FillMFObjectFull(Room* room, Human* hum, cs::MFObjectFull* full_data) override;
virtual void FillMFPlayerStats(cs::MFPlayerStats* stats); 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 bool IsDead(Room* room) override;
virtual long long GetDeadFrameNo(Room* room) override; virtual long long GetDeadFrameNo(Room* room) override;
long long GetRealDeadFrameNo(Room* room); long long GetRealDeadFrameNo(Room* room);

View File

@ -583,6 +583,7 @@ Hero* Room::CreateHero(Entity* master,
hero->move_dir = dir; hero->move_dir = dir;
hero->Initialize(); hero->Initialize();
AddToEntityHash(hero); AddToEntityHash(hero);
AddToMoveableHash(hero);
grid_service->AddHero(hero); grid_service->AddHero(hero);
hero->RefreshView(); hero->RefreshView();
return hero; return hero;