添加last android逻辑

This commit is contained in:
aozhiwei 2020-06-04 14:51:25 +08:00
parent 41db14e14b
commit e0fb3a679a
5 changed files with 137 additions and 2 deletions

View File

@ -37,6 +37,10 @@ void AndroidAI::Update(int delta_time)
UpdateNewBieNpc();
return;
}
if (a8::HasBitFlag(hum->status, HS_LastAndroid)) {
UpdateLastNpc();
return;
}
switch (state) {
case AS_thinking:
{
@ -195,3 +199,43 @@ void AndroidAI::UpdateNewBieNpc()
a8::UnSetBitFlag(hum->status, HS_NewBieGuideAndroid);
}
}
void AndroidAI::UpdateLastNpc()
{
Human* hum = (Human*)owner;
if (hum->room->GetFrameNo() - hum->enable_frameno < 2) {
hum->move_dir = hum->last_human_target->GetPos() - hum->GetPos();
hum->move_dir.Normalize();
hum->attack_dir = hum->move_dir;
if (hum->curr_weapon->weapon_idx != 0) {
hum->curr_weapon->ammo = MetaMgr::Instance()->newbie_first_robot_ammo;
}
} else if (hum->room->GetFrameNo() - hum->enable_frameno < SERVER_FRAME_RATE * 1.5) {
int speed = std::max(1, (int)hum->GetSpeed());
for (int i = 0; i < speed; ++i) {
a8::Vec2 old_pos = hum->GetPos();
hum->SetPos(hum->GetPos() + hum->move_dir);
if (hum->IsCollisionInMapService()) {
hum->SetPos(old_pos);
if (i == 0) {
hum->FindPathInMapService();
}
break;
}
hum->room->grid_service->MoveHuman(hum);
}
} else if (hum->room->GetFrameNo() - hum->enable_frameno < SERVER_FRAME_RATE * 3) {
Human* enemy = hum->last_human_target;
Human* sender = hum;
a8::Vec2 shot_dir = enemy->GetPos() - sender->GetPos();
if (std::abs(shot_dir.x) > FLT_EPSILON ||
std::abs(shot_dir.y) > FLT_EPSILON) {
shot_dir.Normalize();
shot_dir.Rotate((rand() % 10) / 180.0f);
sender->attack_dir = shot_dir;
sender->Shot(shot_dir);
}
} else {
a8::UnSetBitFlag(hum->status, HS_LastAndroid);
}
}

View File

@ -22,6 +22,7 @@ class AndroidAI : public AIComponent
private:
void UpdateNewBieNpc();
void UpdateLastNpc();
void ChangeToState(AndroidState_e to_state);

View File

@ -21,6 +21,7 @@ enum HumanStatus
HS_NewBieGuideAndroid = 3,
HS_AlreadyEquip = 5,
HS_AlreadyProcNewBieLogic = 6,
HS_LastAndroid = 7,
HS_End
};
@ -138,6 +139,7 @@ class Human : public MoveableEntity
float skill_param1 = 0;
bool playing_skill = false;
xtimer_list* ad_timer_ = nullptr;
Human* last_human_target = nullptr;
std::function<void(Human*)> on_grid_chg;

View File

@ -508,6 +508,7 @@ void Room::OnHumanDie(Human* hum)
--PerfMonitor::Instance()->alive_count;
RemoveFromAliveHumanHash(hum);
NotifyUiUpdate();
CheckShowHand();
}
bool Room::OverBorder(const a8::Vec2 pos, float radius)
@ -1892,7 +1893,7 @@ void Room::ProcDieAndroid(int die_time, int die_num)
#endif
std::vector<Human*> alive_humans;
alive_humans.reserve(human_hash_.size());
GetAliveHumans(alive_humans, 16, nullptr);
GetAliveHumansExcludeLastHuman(alive_humans, 16);
{
Human* first_alive_player = nullptr;
for (auto& pair : accountid_hash_) {
@ -2058,6 +2059,7 @@ void Room::ShuaGridRound(Human* target)
Human* hum = pair.second;
if (hum->IsAndroid() &&
a8::HasBitFlag(hum->status, HS_Disable) &&
!a8::HasBitFlag(hum->status, HS_LastAndroid) &&
!hum->real_dead &&
hum->team_uuid.empty() &&
grid_service->InView(target->GetGridId(), hum->GetPos().x, hum->GetPos().y)
@ -2164,6 +2166,34 @@ void Room::GetAliveHumans(std::vector<Human*>& alive_humans, size_t num, Human*
}
}
void Room::GetAliveHumansExcludeLastHuman(std::vector<Human*>& alive_humans, size_t num)
{
alive_humans.reserve(num);
{
if (GetFrameNo() % 8 < 5) {
for (auto itr = human_hash_.begin(); itr != human_hash_.end(); ++itr) {
if (a8::HasBitFlag(itr->second->status, HS_LastAndroid)) {
continue;
}
CheckAliveHuman(itr->second, alive_humans);
if (alive_humans.size() > num) {
break;
}
}
} else {
for (auto itr = human_hash_.rbegin(); itr != human_hash_.rend(); ++itr) {
if (a8::HasBitFlag(itr->second->status, HS_LastAndroid)) {
continue;
}
CheckAliveHuman(itr->second, alive_humans);
if (alive_humans.size() > num) {
break;
}
}
}
}
}
void Room::CheckAliveHuman(Human* hum, std::vector<Human*>& alive_humans)
{
if (hum->IsAndroid() &&
@ -2419,6 +2449,18 @@ void Room::NewBieRoomStart()
},
&xtimer_attacher_.timer_list_);
}
std::vector<Human*> tmp_humans;
tmp_humans.reserve(ROOM_MAX_PLAYER_NUM);
for (auto& pair : human_hash_) {
if (pair.second->IsAndroid()) {
tmp_humans.push_back(pair.second);
}
}
std::random_shuffle(tmp_humans.begin(), tmp_humans.end());
for (size_t i = 0; i < accountid_hash_.size(); ++i) {
last_human_hash_[tmp_humans[i]->GetEntityUniId()] = tmp_humans[i];
a8::SetBitFlag(tmp_humans[i]->status, HS_LastAndroid);
}
}
Human* Room::GetOneCanEnableAndroid()
@ -2433,7 +2475,8 @@ void Room::GetCanEnableAndroids(std::vector<Human*>& humans, size_t num)
for (auto& pair : human_hash_) {
if (pair.second->IsAndroid() &&
!pair.second->real_dead &&
a8::HasBitFlag(pair.second->status, HS_Disable)
a8::HasBitFlag(pair.second->status, HS_Disable) &&
!a8::HasBitFlag(pair.second->status, HS_LastAndroid)
) {
if (humans.size() >= num) {
break;
@ -2550,3 +2593,45 @@ void Room::SyncFrameData()
}
frame_event.Clear();
}
void Room::CheckShowHand()
{
if (room_type_ == RT_NewBrid || room_type_ == RT_MidBrid) {
if (alive_count_ <= (int)(accountid_hash_.size() + last_human_hash_.size())) {
std::vector<Player*> players;
std::vector<Human*> androids;
for (auto& pair : accountid_hash_) {
players.push_back(pair.second);
}
for (auto& pair : last_human_hash_) {
androids.push_back(pair.second);
}
for (size_t i = 0; i < players.size(); ++i) {
if (i >= androids.size()) {
break;
}
Player* target = players[i];
Human* hum = androids[i];
{
a8::Vec2 pos = target->GetPos();
a8::Vec2 dir = target->move_dir;
if (rand() % 100 < 80) {
dir.Rotate(a8::RandAngle() / 2.0f);
} else {
dir.Rotate(a8::RandAngle());
}
pos = pos + dir * SHUA_RANGE;
if (OverBorder(pos, hum->GetRadius())) {
pos.x = target->GetPos().x;
if (OverBorder(pos, hum->GetRadius())) {
pos = target->GetPos(); //!!!
}
}
hum->last_human_target = target;
hum->SetPos(pos);
EnableHuman(hum);
}
}
}
}
}

View File

@ -168,6 +168,7 @@ private:
void ShuaGridRound(Human* target);
void GetAliveHumans(std::vector<Human*>& alive_humans, size_t num, Human* exclude_hum);
void CheckAliveHuman(Human* hum, std::vector<Human*>& alive_humans);
void GetAliveHumansExcludeLastHuman(std::vector<Human*>& alive_humans, size_t num);
a8::Vec2 GetDefaultBornPoint();
void AddToEntityHash(Entity* entity);
@ -190,6 +191,7 @@ private:
void CreateLevel0RoomSpecThings();
bool CanAddToScene(Human* hum);
void SyncFrameData();
void CheckShowHand();
#ifdef DEBUG
void InitDebugInfo();
@ -233,6 +235,7 @@ private:
std::map<int, RoomEntity*> later_add_hash_;
std::map<int, Human*> human_hash_;
std::map<int, Human*> alive_human_hash_;
std::map<int, Human*> last_human_hash_;
std::map<int, BornPoint> born_point_hash_;
std::map<int, CarObject> car_hash_;