game2004/server/gameserver/android.ai.cc
2020-05-29 13:59:24 +08:00

196 lines
5.5 KiB
C++

#include "precompile.h"
#include <float.h>
#include "android.ai.h"
#include "android.h"
#include "room.h"
#include "metamgr.h"
/*
追击
攻击
巡逻
1、当可以攻击的时候攻击
2、当可追击时追击
3、其他巡逻
*/
AndroidAI::~AndroidAI()
{
}
void AndroidAI::Update(int delta_time)
{
Human* hum = (Human*)owner;
if (hum->poisoning) {
hum->poisoning_time += delta_time;
}
state_elapsed_time += delta_time;
if (hum->poisoning) {
hum->UpdatePoisoning();
}
if (hum->dead) {
return;
}
if (a8::HasBitFlag(hum->status, HS_NewBieNpc)) {
UpdateNewBieNpc();
return;
}
switch (state) {
case AS_thinking:
{
if (state_elapsed_time > 1500 + rand() % 3000) {
int rnd = rand();
if (rnd % 100 < 30) {
ChangeToState(AS_moving);
} else if (rnd % 100 < 50) {
ChangeToState(AS_attack);
}
}
}
break;
case AS_moving:
{
if (state_elapsed_time < 1000 + rand() % 2000) {
DoMove();
} else {
int rnd = rand();
if (rnd % 100 < 30) {
ChangeToState(AS_thinking);
} else if (rnd % 100 < 50) {
ChangeToState(AS_attack);
}
}
}
break;
case AS_attack:
{
if (state_elapsed_time < 1000) {
DoAttack();
} else {
int rnd = rand();
if (rnd % 100 < 30) {
ChangeToState(AS_moving);
} else if (rnd % 100 < 50) {
ChangeToState(AS_thinking);
}
}
}
break;
}
}
void AndroidAI::ChangeToState(AndroidState_e to_state)
{
state = to_state;
state_elapsed_time = 0;
switch (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 AndroidAI::DoMove()
{
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_NewBieNpc) &&
hum->room->GetFrameNo() - hum->enable_frameno < SERVER_FRAME_RATE * 8) {
hum->move_dir = hum->room->first_newbie->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 AndroidAI::DoAttack()
{
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);
}
}
}
}
void AndroidAI::UpdateNewBieNpc()
{
Human* hum = (Human*)owner;
if (hum->room->GetFrameNo() - hum->enable_frameno < 2) {
hum->move_dir = hum->room->first_newbie->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->room->first_newbie;
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_NewBieNpc);
}
}