diff --git a/server/gameserver/android_new.ai.cc b/server/gameserver/android_new.ai.cc index 56180d7..a0cf9db 100644 --- a/server/gameserver/android_new.ai.cc +++ b/server/gameserver/android_new.ai.cc @@ -8,6 +8,8 @@ #include "metamgr.h" #include "player.h" +const int SHUA_RANGE = 580; + /* 目标:ai可切换,降级/升级(根据系统当前负载) @@ -85,6 +87,23 @@ void AndroidNewAI::Update(int delta_time) void AndroidNewAI::DefaultAi() { + Human* hum = (Human*)owner; + if (a8::HasBitFlag(hum->status, HS_NewBieGuideAndroid)) { + UpdateNewBieNpc(); + return; + } + if (a8::HasBitFlag(hum->status, HS_LastAndroid)) { + UpdateLastNpc(); + return; + } + if ((hum->room->GetRoomType() == RT_NewBrid || + hum->room->GetRoomType() == RT_MidBrid) && + hum->room->GetGasData().gas_mode != GasInactive && + hum->team_uuid.empty() + ) { + UpdateNewBieRoomLogic(); + return; + } switch (old_ai_data_.state) { case AS_thinking: { @@ -243,3 +262,197 @@ void AndroidNewAI::UpdateAiLevel8() { DefaultAi(); } + +void AndroidNewAI::UpdateNewBieNpc() +{ + Human* hum = (Human*)owner; + if (hum->room->GetFrameNo() - hum->enable_frameno < 2) { + if (hum->GetPos().ManhattanDistance(hum->room->GetFirstNewBie()->GetPos()) > 100) { + hum->move_dir = hum->room->GetFirstNewBie()->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) { + hum->SetPos(hum->GetPos() + hum->move_dir); + hum->room->grid_service->MoveHuman(hum); + } + } else if (hum->room->GetFrameNo() - hum->enable_frameno < SERVER_FRAME_RATE * 3) { + Human* enemy = hum->room->GetFirstNewBie(); + 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_NewBieGuideAndroid); + } +} + +void AndroidNewAI::UpdateLastNpc() +{ + Human* hum = (Human*)owner; + if (hum->room->GetFrameNo() - hum->enable_frameno < 2) { + if (hum->GetPos().ManhattanDistance(hum->last_human_target->GetPos()) > 100) { + 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 * 2; + } + } 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->room->OverBorder(hum->GetPos(), hum->meta->i->radius())) { + hum->room->grid_service->MoveHuman(hum); + } else { + hum->SetPos(old_pos); + break; + } + } + } 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); + } +} + +void AndroidNewAI::UpdateNewBieRoomLogic() +{ + Human* hum = (Human*)owner; + Human* old_last_target = old_ai_data_.last_target; + Human* target = old_ai_data_.last_target; + if ((old_ai_data_.last_target && old_ai_data_.last_target->real_dead) || !old_ai_data_.last_target) { + if (hum->last_human_target && !hum->last_human_target->dead) { + target = hum->last_human_target; + } else { + if (rand() % 100 < 70) { + hum->room->TouchPlayerList + ( + a8::XParams(), + [hum, &target] (Player* player, a8::XParams& param) + { + if (!player->dead && hum->team_id != player->team_id) { + if (!target) { + target = player; + } else { + if (hum->GetPos().ManhattanDistance(player->GetPos()) < + hum->GetPos().ManhattanDistance(target->GetPos())) { + target = player; + } + } + } + }); + } else { + hum->room->TouchHumanList + ( + a8::XParams(), + [hum, &target] (Human* huma, a8::XParams& param) + { + if (!huma->dead && + huma->IsAndroid() && + hum->team_id != huma->team_id && + !a8::HasBitFlag(huma->status, HS_Disable)) { + if (!target) { + target = huma; + } else { + if (hum->GetPos().ManhattanDistance(huma->GetPos()) < + hum->GetPos().ManhattanDistance(target->GetPos())) { + target = huma; + } + } + } + return true; + }); + } + } + old_ai_data_.last_target = target; + } + if (!target) { + return; + } + if (target->IsPlayer()) { + if (hum->room->AliveCount() < 15) { + if (hum->GetPos().ManhattanDistance(target->GetPos()) > 1000) { + a8::Vec2 pos = target->GetPos(); + a8::Vec2 dir = target->move_dir; + dir = a8::Vec2::UP; + if (rand() % 100 < 1) { + dir.Rotate(a8::RandAngle() / 2.0f); + } else { + dir.Rotate(a8::RandAngle()); + } + pos = pos + dir * SHUA_RANGE; + if (hum->room->OverBorder(pos, hum->GetRadius())) { + pos.x = target->GetPos().x; + if (hum->room->OverBorder(pos, hum->GetRadius())) { + pos = target->GetPos(); + } + } + hum->SetPos(pos); + hum->room->grid_service->MoveHuman(hum); + hum->FindLocation(); + hum->RefreshView(); + } + } + } + if (hum->GetPos().ManhattanDistance(target->GetPos()) > 180) { + if (hum->GetPos().ManhattanDistance(target->GetPos()) > 650 && + hum->room->GetFrameNo() - old_ai_data_.last_findenemy_frameno > SERVER_FRAME_RATE * 3) { + old_ai_data_.last_findenemy_frameno = hum->room->GetFrameNo(); + old_ai_data_.last_target = nullptr; + } else { + int speed = std::max(1, (int)hum->GetSpeed()); + hum->move_dir = target->GetPos() - hum->GetPos(); + hum->move_dir.Normalize(); + hum->attack_dir = hum->move_dir; + speed *= 0.7; + for (int i = 0; i < speed; ++i) { + hum->SetPos(hum->GetPos() + hum->move_dir); + hum->room->grid_service->MoveHuman(hum); + } + } + } else { + if (hum->room->GetFrameNo() - old_ai_data_.last_attack_frameno > SERVER_FRAME_RATE + (rand() % 15)) { + old_ai_data_.last_attack_frameno = hum->room->GetFrameNo(); + Human* sender = (Human*)owner; + a8::Vec2 shot_dir = target->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); + } + } + if (old_last_target && old_ai_data_.last_target && old_last_target == old_ai_data_.last_target) { + ++old_ai_data_.series_attack_frames; + } else { + old_ai_data_.series_attack_frames = 0; + } + if (old_ai_data_.series_attack_frames > SERVER_FRAME_RATE * 10 && + old_ai_data_.last_target && old_ai_data_.last_target->IsAndroid()) { + old_ai_data_.last_target = nullptr; + } + } +} diff --git a/server/gameserver/android_new.ai.h b/server/gameserver/android_new.ai.h index 64148fa..2f3b0cd 100644 --- a/server/gameserver/android_new.ai.h +++ b/server/gameserver/android_new.ai.h @@ -8,6 +8,9 @@ struct OldAiData AndroidState_e state = AS_thinking; int state_elapsed_time = 0; Human* last_target = nullptr; + long long last_attack_frameno = 0; + long long last_findenemy_frameno = 0; + long long series_attack_frames = 0; }; class Human; @@ -23,6 +26,9 @@ private: void ChangeToStateOldAI(AndroidState_e to_state); void DoMoveOldAI(); void DoAttackOldAI(); + void UpdateNewBieNpc(); + void UpdateLastNpc(); + void UpdateNewBieRoomLogic(); void UpdateAiLevel1(); void UpdateAiLevel2();