1
This commit is contained in:
parent
8dd5ae9d58
commit
f6f7b78edf
@ -18,6 +18,7 @@ GridCell::GridCell()
|
||||
entity_list_.push_back(std::set<Entity*>());
|
||||
bullet_list_.push_back(std::set<Bullet*>());
|
||||
car_list_.push_back(std::set<Car*>());
|
||||
hero_list_.push_back(std::set<Hero*>());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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<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();
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ namespace MetaData
|
||||
class Human;
|
||||
class Room;
|
||||
class Buff;
|
||||
class HeroAI;
|
||||
class Hero : public MoveableEntity
|
||||
{
|
||||
public:
|
||||
@ -21,6 +22,7 @@ class Hero : public MoveableEntity
|
||||
bool shot_hold = false;
|
||||
int team_id = 0;
|
||||
a8::Vec2 attack_dir;
|
||||
std::function<bool ()> 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();
|
||||
|
||||
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;
|
||||
};
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user