246 lines
5.4 KiB
C++
246 lines
5.4 KiB
C++
#include "precompile.h"
|
||
|
||
#include <float.h>
|
||
|
||
#include "android_new.ai.h"
|
||
#include "android.h"
|
||
#include "room.h"
|
||
#include "metamgr.h"
|
||
#include "player.h"
|
||
|
||
/*
|
||
目标:ai可切换,降级/升级(根据系统当前负载)
|
||
|
||
ai级别
|
||
1: 木桩
|
||
2: 站桩间隔开枪
|
||
3: 站桩描边射击
|
||
4: 站桩扫射
|
||
5: 跑动间隔开枪
|
||
6: 跑动描边射击
|
||
7: 跑动扫射
|
||
8: 跑动射击
|
||
*/
|
||
|
||
AndroidNewAI::~AndroidNewAI()
|
||
{
|
||
}
|
||
|
||
void AndroidNewAI::Update(int delta_time)
|
||
{
|
||
old_ai_data_.state_elapsed_time += delta_time;
|
||
Human* hum = (Human*)owner;
|
||
if (hum->poisoning) {
|
||
hum->poisoning_time += delta_time;
|
||
}
|
||
if (hum->poisoning) {
|
||
hum->UpdatePoisoning();
|
||
}
|
||
if (hum->dead) {
|
||
return;
|
||
}
|
||
switch (GetAiLevel()) {
|
||
case 1:
|
||
{
|
||
UpdateAiLevel1();
|
||
}
|
||
break;
|
||
case 2:
|
||
{
|
||
UpdateAiLevel2();
|
||
}
|
||
break;
|
||
case 3:
|
||
{
|
||
UpdateAiLevel3();
|
||
}
|
||
break;
|
||
case 4:
|
||
{
|
||
UpdateAiLevel4();
|
||
}
|
||
break;
|
||
case 5:
|
||
{
|
||
UpdateAiLevel5();
|
||
}
|
||
break;
|
||
case 6:
|
||
{
|
||
UpdateAiLevel6();
|
||
}
|
||
break;
|
||
case 7:
|
||
{
|
||
UpdateAiLevel7();
|
||
}
|
||
break;
|
||
default:
|
||
{
|
||
DefaultAi();
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
void AndroidNewAI::DefaultAi()
|
||
{
|
||
switch (old_ai_data_.state) {
|
||
case AS_thinking:
|
||
{
|
||
if (old_ai_data_.state_elapsed_time > 1500 + rand() % 3000) {
|
||
int rnd = rand();
|
||
if (rnd % 100 < 30) {
|
||
ChangeToStateOldAI(AS_moving);
|
||
} else if (rnd % 100 < 50) {
|
||
ChangeToStateOldAI(AS_attack);
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case AS_moving:
|
||
{
|
||
if (old_ai_data_.state_elapsed_time < 1000 + rand() % 2000) {
|
||
DoMoveOldAI();
|
||
} else {
|
||
int rnd = rand();
|
||
if (rnd % 100 < 30) {
|
||
ChangeToStateOldAI(AS_thinking);
|
||
} else if (rnd % 100 < 50) {
|
||
ChangeToStateOldAI(AS_attack);
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case AS_attack:
|
||
{
|
||
if ((old_ai_data_.state_elapsed_time < 3000 && old_ai_data_.last_target) ||
|
||
(old_ai_data_.state_elapsed_time < 1100)) {
|
||
DoAttackOldAI();
|
||
} else {
|
||
int rnd = rand();
|
||
if (rnd % 100 < 30) {
|
||
ChangeToStateOldAI(AS_moving);
|
||
} else if (rnd % 100 < 50) {
|
||
ChangeToStateOldAI(AS_thinking);
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
void AndroidNewAI::ChangeToStateOldAI(AndroidState_e to_state)
|
||
{
|
||
old_ai_data_.state = to_state;
|
||
old_ai_data_.state_elapsed_time = 0;
|
||
switch (old_ai_data_.state) {
|
||
case AS_moving:
|
||
{
|
||
Human* hum = (Human*)owner;
|
||
hum->move_dir = a8::Vec2(1.0f, 0);
|
||
hum->move_dir.Rotate(a8::RandAngle());
|
||
hum->move_dir.Normalize();
|
||
hum->attack_dir = hum->move_dir;
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
void AndroidNewAI::DoMoveOldAI()
|
||
{
|
||
Human* hum = (Human*)owner;
|
||
if (hum->room->IsWaitingStart()) {
|
||
return;
|
||
}
|
||
if (owner->UpdatedTimes() % 2 == 0) {
|
||
Human* hum = (Human*)owner;
|
||
int speed = std::max(1, (int)hum->GetSpeed());
|
||
if (a8::HasBitFlag(hum->status, HS_NewBieGuideAndroid) &&
|
||
hum->room->GetFrameNo() - hum->enable_frameno < SERVER_FRAME_RATE * 8) {
|
||
hum->move_dir = hum->room->GetFirstNewBie()->GetPos() - hum->GetPos();
|
||
hum->move_dir.Normalize();
|
||
}
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
|
||
void AndroidNewAI::DoAttackOldAI()
|
||
{
|
||
Human* hum = (Human*)owner;
|
||
if (hum->room->IsWaitingStart()) {
|
||
return;
|
||
}
|
||
if (hum->room->GetGasData().gas_mode == GasInactive) {
|
||
return;
|
||
}
|
||
if (owner->UpdatedTimes() % 10 == 0) {
|
||
Human* enemy = owner->room->FindEnemy((Human*)owner);
|
||
if (enemy) {
|
||
Human* sender = (Human*)owner;
|
||
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);
|
||
}
|
||
}
|
||
old_ai_data_.last_target = enemy;
|
||
}
|
||
}
|
||
|
||
void AndroidNewAI::UpdateAiLevel1()
|
||
{
|
||
DefaultAi();
|
||
}
|
||
|
||
void AndroidNewAI::UpdateAiLevel2()
|
||
{
|
||
DefaultAi();
|
||
}
|
||
|
||
void AndroidNewAI::UpdateAiLevel3()
|
||
{
|
||
DefaultAi();
|
||
}
|
||
|
||
void AndroidNewAI::UpdateAiLevel4()
|
||
{
|
||
DefaultAi();
|
||
}
|
||
|
||
void AndroidNewAI::UpdateAiLevel5()
|
||
{
|
||
DefaultAi();
|
||
}
|
||
|
||
void AndroidNewAI::UpdateAiLevel6()
|
||
{
|
||
DefaultAi();
|
||
}
|
||
|
||
void AndroidNewAI::UpdateAiLevel7()
|
||
{
|
||
DefaultAi();
|
||
}
|
||
|
||
void AndroidNewAI::UpdateAiLevel8()
|
||
{
|
||
DefaultAi();
|
||
}
|