This commit is contained in:
aozhiwei 2021-06-17 19:41:35 +08:00
parent e8d711dcd3
commit ec4b690440
6 changed files with 136 additions and 102 deletions

View File

@ -1,5 +1,9 @@
#include "precompile.h" #include "precompile.h"
#include <math.h>
#include <float.h>
#include "buff.h" #include "buff.h"
#include "metamgr.h" #include "metamgr.h"
#include "human.h" #include "human.h"
@ -464,3 +468,26 @@ void Buff::SetCaster(Creature* caster)
caster_.Reset(); caster_.Reset();
} }
} }
void Buff::ProcPullToWalkable()
{
if (owner->CollisonDetection()) {
return;
}
a8::Vec2 move_dir = owner->GetMoveDir();
if (std::abs(move_dir.x) > FLT_EPSILON ||
std::abs(move_dir.y) > FLT_EPSILON
) {
a8::Vec2 old_pos = owner->GetPos();
for (int i = 1; i < 2000; i += 5) {
owner->SetPos(old_pos + move_dir * i);
if (owner->CollisonDetection()) {
owner->room->grid_service->MoveCreature(owner);
return;
}
}
abort();
} else {
owner->FindLocation();
}
}

View File

@ -55,6 +55,7 @@ class Buff
void ProcSprint(Creature* caster); void ProcSprint(Creature* caster);
void ProcSeletTargetWithSelfPos(Creature* caster); void ProcSeletTargetWithSelfPos(Creature* caster);
void ProcTurnOver(Creature* caster); void ProcTurnOver(Creature* caster);
void ProcPullToWalkable();
private: private:
void InternalTimerAddBuff(Creature* caster); void InternalTimerAddBuff(Creature* caster);

View File

@ -983,6 +983,11 @@ void Creature::ProcBuffEffect(Creature* caster, Buff* buff)
buff->ProcPassenger(caster); buff->ProcPassenger(caster);
} }
break; break;
case kBET_PullToWalkable:
{
buff->ProcPullToWalkable();
}
break;
default: default:
{ {
} }
@ -1917,3 +1922,104 @@ void Creature::SetInfiniteBulletMode()
inventory_[IS_12GAUGE].num = FIGHTING_MODE_BULLET_NUM; inventory_[IS_12GAUGE].num = FIGHTING_MODE_BULLET_NUM;
inventory_[IS_RPG].num = FIGHTING_MODE_BULLET_NUM; inventory_[IS_RPG].num = FIGHTING_MODE_BULLET_NUM;
} }
void Creature::FindLocationWithTarget(Entity* target)
{
a8::Vec2 old_pos = GetPos();
a8::Vec2 new_pos = GetPos();
AabbCollider a_collider;
GetAabbBox(a_collider);
AabbCollider target_collider;
target->GetAabbBox(target_collider);
{
bool ret = a_collider.CalcSafePoint(&target_collider, new_pos);
if (!ret) {
abort();
}
}
a8::Vec2 new_pos_dir = new_pos - old_pos;
new_pos_dir.Normalize();
float distance = (new_pos - old_pos).Norm();
for (int i = distance; i < 10000000; i += 5) {
SetPos(old_pos + new_pos_dir * i);
room->grid_service->MoveCreature(this);
Entity* building = nullptr;
std::set<GridCell*> tmp_grids;
room->grid_service->GetAllCellsByXy(room, GetX(), GetY(), tmp_grids);
room->grid_service->TraverseAllLayerEntityList
(
room->GetRoomIdx(),
tmp_grids,
[this, &building] (Entity* entity, bool& stop)
{
switch (entity->GetEntityType()) {
case ET_Building:
{
if (TestCollision(room, entity)) {
building = entity;
stop = true;
}
}
break;
default:
break;
}
});
if (!building) {
bool is_collision = false;
std::set<ColliderComponent*> colliders;
room->map_service->GetColliders(room, GetX(), GetY(), colliders);
for (ColliderComponent* collider : colliders) {
if (TestCollision(room, collider)) {
is_collision = true;
break;
}
}
if (!is_collision) {
break;
}
}
}
}
void Creature::FindLocation()
{
Entity* target = nullptr;
TraverseAllLayerEntityList
(
[this, &target] (Entity* entity, bool& stop)
{
switch (entity->GetEntityType()) {
case ET_Obstacle:
{
if (!target) {
if (TestCollision(room, entity)) {
target = entity;
}
}
}
break;
case ET_Building:
{
if (!target || !target->IsEntityType(ET_Building)) {
AabbCollider aabb_box;
entity->GetAabbBox(aabb_box);
if (TestCollision(room, &aabb_box)) {
target = entity;
}
}
}
break;
default:
{
}
break;
}
});
if (target) {
FindLocationWithTarget(target);
}
}

View File

@ -188,6 +188,8 @@ class Creature : public MoveableEntity
void GetHitEnemys(std::set<Creature*>& enemys); void GetHitEnemys(std::set<Creature*>& enemys);
bool TryMove(const a8::Vec2& target_pos, a8::Vec2& out_pos); bool TryMove(const a8::Vec2& target_pos, a8::Vec2& out_pos);
void SetInfiniteBulletMode(); void SetInfiniteBulletMode();
void FindLocation();
void FindLocationWithTarget(Entity* target);
private: private:

View File

@ -1191,45 +1191,6 @@ void Human::DoGetOn(int obj_uniid)
} }
} }
void Human::FindLocation()
{
Entity* target = nullptr;
TraverseAllLayerEntityList
(
[this, &target] (Entity* entity, bool& stop)
{
switch (entity->GetEntityType()) {
case ET_Obstacle:
{
if (!target) {
if (TestCollision(room, entity)) {
target = entity;
}
}
}
break;
case ET_Building:
{
if (!target || !target->IsEntityType(ET_Building)) {
AabbCollider aabb_box;
entity->GetAabbBox(aabb_box);
if (TestCollision(room, &aabb_box)) {
target = entity;
}
}
}
break;
default:
{
}
break;
}
});
if (target) {
FindLocationWithTarget(target);
}
}
void Human::RefreshView() void Human::RefreshView()
{ {
#if 1 #if 1
@ -2521,67 +2482,6 @@ void Human::ProcSpoils(Loot* entity, MetaData::Equip* item_meta)
} }
} }
void Human::FindLocationWithTarget(Entity* target)
{
a8::Vec2 old_pos = GetPos();
a8::Vec2 new_pos = GetPos();
AabbCollider a_collider;
GetAabbBox(a_collider);
AabbCollider target_collider;
target->GetAabbBox(target_collider);
{
bool ret = a_collider.CalcSafePoint(&target_collider, new_pos);
if (!ret) {
abort();
}
}
a8::Vec2 new_pos_dir = new_pos - old_pos;
new_pos_dir.Normalize();
float distance = (new_pos - old_pos).Norm();
for (int i = distance; i < 10000000; i += 5) {
SetPos(old_pos + new_pos_dir * i);
room->grid_service->MoveCreature(this);
Entity* building = nullptr;
std::set<GridCell*> tmp_grids;
room->grid_service->GetAllCellsByXy(room, GetX(), GetY(), tmp_grids);
room->grid_service->TraverseAllLayerEntityList
(
room->GetRoomIdx(),
tmp_grids,
[this, &building] (Entity* entity, bool& stop)
{
switch (entity->GetEntityType()) {
case ET_Building:
{
if (TestCollision(room, entity)) {
building = entity;
stop = true;
}
}
break;
default:
break;
}
});
if (!building) {
bool is_collision = false;
std::set<ColliderComponent*> colliders;
room->map_service->GetColliders(room, GetX(), GetY(), colliders);
for (ColliderComponent* collider : colliders) {
if (TestCollision(room, collider)) {
is_collision = true;
break;
}
}
if (!is_collision) {
break;
}
}
}
}
void Human::OnDie() void Human::OnDie()
{ {
real_dead_frameno = room->GetFrameNo(); real_dead_frameno = room->GetFrameNo();

View File

@ -167,7 +167,6 @@ class Human : public Creature
virtual Skill* SelectSkill(); virtual Skill* SelectSkill();
void DoGetOn(int obj_uniid); void DoGetOn(int obj_uniid);
void DoGetDown(); void DoGetDown();
void FindLocation();
virtual void RefreshView() override; virtual void RefreshView() override;
virtual void OnGridListChange(std::set<GridCell*>& old_grids, virtual void OnGridListChange(std::set<GridCell*>& old_grids,
std::set<GridCell*>& inc_grids, std::set<GridCell*>& inc_grids,
@ -252,7 +251,6 @@ private:
void GenZbModeBattleReportData(a8::MutableXObject* params); void GenZbModeBattleReportData(a8::MutableXObject* params);
void FillSMGameOver(cs::SMGameOver& msg); void FillSMGameOver(cs::SMGameOver& msg);
void SendBattleReport(); void SendBattleReport();
void FindLocationWithTarget(Entity* target);
void Revive(); void Revive();
void ClearLordMode(); void ClearLordMode();
void AdjustDecHp(float old_health, float& new_health); void AdjustDecHp(float old_health, float& new_health);