This commit is contained in:
aozhiwei 2021-06-23 03:02:08 +00:00
parent ff2d2b2e9d
commit a1dafd094f
10 changed files with 83 additions and 183 deletions

View File

@ -196,7 +196,7 @@ void AndroidAI::DoMoveOldAI()
for (int i = 0; i < speed; ++i) {
a8::Vec2 old_pos = hum->GetPos();
hum->SetPos(hum->GetPos() + hum->GetMoveDir());
if (hum->IsCollisionInMapService()) {
if (hum->CheckCollision()) {
hum->SetPos(old_pos);
if (i == 0) {
hum->FindPathInMapService();

View File

@ -340,13 +340,6 @@ enum ObstacleType_e
kObstacleOilBucket = 9,
};
enum OptResult
{
kOptPass = 0,
kOptContinue = 1,
kOptBreak = 2
};
enum BulletHit_e
{
kBulletHitPass = 1,

View File

@ -2075,3 +2075,58 @@ bool Creature::ReceiveExplosionDmg(Explosion* explosion)
{
return true;
}
bool Creature::CheckCollision()
{
Global::last_collider = nullptr;
if (room->OverBorder(GetPos(), GetRadius())){
return true;
}
if (HasBuffEffect(kBET_ThroughWall) ||
HasBuffEffect(kBET_Fly)) {
return false;
}
std::set<ColliderComponent*> colliders;
room->map_service->GetColliders(room, GetX(), GetY(), colliders);
AabbCollider aabb_box;
GetAabbBox(aabb_box);
for (ColliderComponent* collider : colliders) {
if (last_collision_door_ != collider->owner) {
switch (collider->owner->GetEntityType()) {
case ET_Obstacle:
{
Obstacle* obstacle = (Obstacle*)collider->owner;
if (!obstacle->CanThroughable(this)) {
if (
(collider->type == CT_Aabb && aabb_box.Intersect(collider)) ||
(collider->type == CT_Circle && self_collider_->Intersect(collider))
) {
if (obstacle->OnCollisionTrigger(this, collider) == 1) {
return true;
}
}
}
}
break;
case ET_Building:
{
if (
(collider->type == CT_Aabb && aabb_box.Intersect(collider)) ||
(collider->type == CT_Circle && self_collider_->Intersect(collider))
) {
Global::last_collider = collider;
return true;
}
}
break;
default:
{
}
break;
}
}
}
return false;
}

View File

@ -193,6 +193,12 @@ class Creature : public MoveableEntity
void SetInfiniteBulletMode();
void FindLocation();
void FindLocationWithTarget(Entity* target);
Entity* GetLastCollisionDoor() { return last_collision_door_; }
void SetLastCollisionDoor(Entity* door) { last_collision_door_ = door; }
bool CheckCollision();
protected:
private:
@ -220,6 +226,8 @@ protected:
int action_target_id = 0;
long long cell_flags_ = 0;
CircleCollider* self_collider_ = nullptr;
Entity* last_collision_door_ = nullptr;
private:
CreatureWeakPtr weak_ptr_;

View File

@ -122,7 +122,7 @@ void Hero::InternalUpdateMove(float speed)
a8::Vec2 new_pos = GetPos() + GetMoveDir() * speed;
SetPos(new_pos);
if (!IsCollisionInMapService()) {
if (!CheckCollision()) {
room->grid_service->MoveCreature(this);
} else {
if (on_move_collision && !on_move_collision()) {
@ -131,94 +131,6 @@ void Hero::InternalUpdateMove(float speed)
}
}
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))
) &&
!obstacle->CanThroughable(this)) {
if (last_collision_door_ != collider->owner) {
OptResult opt_result = kOptPass;
obstacle->OnCollisionTrigger(this, collider, opt_result);
if (opt_result == kOptContinue) {
continue;
} else if (opt_result == kOptBreak) {
return true;
}
if (!obstacle->IsDead(room) &&
#if 0
obstacle->Attackable(this) &&
#endif
obstacle->meta->i->drop() != 0 &&
obstacle->IsTouchInteraction() &&
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_) {

View File

@ -43,14 +43,11 @@ public:
protected:
virtual void _UpdateMove(int speed) override;
void InternalUpdateMove(float speed);
bool IsCollisionInMapService();
virtual void RecalcSelfCollider() override;
void BeKill(int killer_id, const std::string& killer_name, int weapon_id);
private:
bool later_removed_ = false;
CircleCollider* self_collider_ = nullptr;
Entity* last_collision_door_ = nullptr;
bool detached_ = false;
friend class HeroAI;

View File

@ -489,67 +489,6 @@ void Human::RecalcSelfCollider()
}
}
bool Human::IsCollisionInMapService()
{
Global::last_collider = nullptr;
if (room->OverBorder(GetPos(), meta->i->radius())){
return true;
}
if (HasBuffEffect(kBET_ThroughWall) ||
HasBuffEffect(kBET_Fly)) {
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->CanThroughable(this) &&
(
(collider->type == CT_Aabb && aabb_box.Intersect(collider)) ||
(collider->type == CT_Circle && self_collider_->Intersect(collider))
)
) {
if (last_collision_door_ != collider->owner) {
OptResult opt_result = kOptPass;
obstacle->OnCollisionTrigger(this, collider, opt_result);
if (opt_result == kOptContinue) {
continue;
} else if (opt_result == kOptBreak) {
return true;
}
}
}
}
break;
case ET_Building:
{
if (
(collider->type == CT_Aabb && aabb_box.Intersect(collider)) ||
(collider->type == CT_Circle && self_collider_->Intersect(collider))
) {
if (last_collision_door_ != collider->owner) {
Global::last_collider = collider;
return true;
}
}
}
break;
default:
{
}
break;
}
}
return false;
}
void Human::FindPathInMapService()
{
a8::Vec2 old_pos = GetPos();
@ -580,7 +519,7 @@ void Human::FindPathInMapService()
}
float distance = ((CircleCollider*)last_collider)->rad + meta->i->radius();
SetPos(last_collider->owner->GetPos() + extend_dir * (distance + 1));
if (IsCollisionInMapService()) {
if (CheckCollision()) {
SetPos(old_pos);
}
}
@ -597,34 +536,34 @@ void Human::FindPathInMapService()
if (std::abs(up_dot) <= 0.001f) { //相互垂直
//向上
SetPos(old_pos + a8::Vec2::UP);
if (!IsCollisionInMapService()) {
if (!CheckCollision()) {
return;
} else {
//向下
SetPos(old_pos + a8::Vec2::DOWN);
if (!IsCollisionInMapService()) {
if (!CheckCollision()) {
return;
}
}
} else if (up_dot > 0.001f) { //基本相同
SetPos(old_pos + (at_left_side ? a8::Vec2::LEFT : a8::Vec2::RIGHT));
if (!IsCollisionInMapService()) {
if (!CheckCollision()) {
return;
} else {
//向上
SetPos(old_pos + a8::Vec2::UP);
if (!IsCollisionInMapService()) {
if (!CheckCollision()) {
return;
}
}
} else if (up_dot < 0.001f) { //基本相反
SetPos(old_pos + (at_left_side ? a8::Vec2::LEFT : a8::Vec2::RIGHT));
if (!IsCollisionInMapService()) {
if (!CheckCollision()) {
return;
} else {
//向下
SetPos(old_pos + a8::Vec2::DOWN);
if (!IsCollisionInMapService()) {
if (!CheckCollision()) {
return;
}
}
@ -1838,7 +1777,7 @@ void Human::_InternalUpdateMove(float speed)
#if 1
SetPos(old_pos + a8::Vec2(nx, ny));
if (!IsCollisionInMapService()) {
if (!CheckCollision()) {
room->grid_service->MoveCreature(this);
return;
} else {
@ -1853,7 +1792,7 @@ void Human::_InternalUpdateMove(float speed)
a8::Vec2 new_dir = tmp_dir * rate;
SetPos(GetPos() + new_dir);
}
if (!IsCollisionInMapService()) {
if (!CheckCollision()) {
room->grid_service->MoveCreature(this);
return;
}
@ -1866,7 +1805,7 @@ void Human::_InternalUpdateMove(float speed)
}
SetPos(old_pos + a8::Vec2(nx, 0));
if (IsCollisionInMapService()) {
if (CheckCollision()) {
if (a8::HasBitFlag(status, CS_Collisioning)) {
SetPos(old_pos);
return;
@ -1879,7 +1818,7 @@ void Human::_InternalUpdateMove(float speed)
}
SetPos(old_pos + a8::Vec2(nx, ny));
if (IsCollisionInMapService()) {
if (CheckCollision()) {
if (a8::HasBitFlag(status, CS_Collisioning)) {
SetPos(old_pos);
return;
@ -3232,7 +3171,7 @@ void Human::OnLand()
hum->refresh_view_timer_ = nullptr;
});
}
if (IsCollisionInMapService()) {
if (CheckCollision()) {
a8::Vec2 old_pos = GetPos();
std::vector<a8::Vec2> dirs;
{
@ -3244,7 +3183,7 @@ void Human::OnLand()
for (int i = 0; i < 10000000; i += 10) {
for (const a8::Vec2& dir : dirs) {
SetPos(old_pos + dir * i);
if (!IsCollisionInMapService()) {
if (!CheckCollision()) {
room->grid_service->MoveCreature(this);
return;
}

View File

@ -147,7 +147,6 @@ class Human : public Creature
void FillMFTeamData(cs::MFTeamData* team_data, bool is_game_over);
void CarShot(const a8::Vec2& target_dir);
virtual void RecalcSelfCollider() override;
bool IsCollisionInMapService();
void FindPathInMapService();
void BeKill(int killer_id, const std::string& killer_name, int weapon_id);
virtual void DecHP(float dec_hp, int killer_id, const std::string& killer_name, int weapon_id) override;
@ -219,8 +218,6 @@ class Human : public Creature
virtual void DropItems(Obstacle* obstacle) override;
void OnEnable();
void OnDisable();
Entity* GetLastCollisionDoor() { return last_collision_door_; }
void SetLastCollisionDoor(Entity* door) { last_collision_door_ = door; }
ObjectSyncFlags* GetObjectSyncFlags(int obj_uniid);
bool HasSpecMove();
void _UpdateSpecMove();
@ -328,7 +325,6 @@ protected:
std::vector<Skin> skins;
private:
CircleCollider* self_collider_ = nullptr;
long long last_sync_gas_frameno = 0;
std::map<int, int> items_;
std::set<int> battling_items_;
@ -341,8 +337,6 @@ private:
bool sent_battlereport_ = false;
bool sent_game_end_ = false;
Entity* last_collision_door_ = nullptr;
long long jump_frameno_ = 0;
float old_sync_speed = 0;

View File

@ -667,8 +667,10 @@ bool Obstacle::DoInteraction(Human* sender)
return false;
}
void Obstacle::OnCollisionTrigger(Creature* c, ColliderComponent* collider, OptResult& opt_result)
int Obstacle::OnCollisionTrigger(Creature* c, ColliderComponent* collider)
{
return 0;
#if 0
opt_result = kOptPass;
switch (meta->i->thing_type()) {
case kObstacleSpring:
@ -700,6 +702,7 @@ void Obstacle::OnCollisionTrigger(Creature* c, ColliderComponent* collider, OptR
}
break;
}
#endif
#if 0
Global::last_collider = collider;
#endif

View File

@ -48,7 +48,7 @@ class Obstacle : public Entity
virtual bool CanThroughable(Creature* c);
virtual bool CanThroughable(Bullet* bullet);
virtual bool DoInteraction(Human* sender);
virtual void OnCollisionTrigger(Creature* c, ColliderComponent* collider, OptResult& opt_result);
virtual int OnCollisionTrigger(Creature* c, ColliderComponent* collider);
virtual bool CanSeeMe(Human* hum);
virtual bool ReceiveExplosionDmg(Explosion* explosion) override;
void SetDoorInfo(Building* building, int door_id_x);
@ -102,4 +102,3 @@ protected:
friend class EntityFactory;
};