139 lines
3.5 KiB
C++
139 lines
3.5 KiB
C++
#include "precompile.h"
|
|
|
|
#include <float.h>
|
|
|
|
#include "android.ai.h"
|
|
#include "android.h"
|
|
#include "room.h"
|
|
#include "metamgr.h"
|
|
|
|
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;
|
|
}
|
|
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 (a8::HasBitFlag(hum->status, HS_Fly)) {
|
|
return;
|
|
}
|
|
if (owner->updated_times % 2 == 0) {
|
|
Human* hum = (Human*)owner;
|
|
int speed = std::max(1, (int)hum->GetSpeed());
|
|
for (int i = 0; i < speed; ++i) {
|
|
a8::Vec2 old_pos = hum->pos;
|
|
hum->pos = hum->pos + hum->move_dir;
|
|
if (hum->IsCollisionInMapService()) {
|
|
hum->pos = old_pos;
|
|
if (i == 0) {
|
|
hum->FindPathInMapService();
|
|
}
|
|
break;
|
|
}
|
|
hum->room->grid_service.MoveHuman(hum);
|
|
}
|
|
}
|
|
}
|
|
|
|
void AndroidAI::DoAttack()
|
|
{
|
|
Human* hum = (Human*)owner;
|
|
if (a8::HasBitFlag(hum->status, HS_Fly) ||
|
|
a8::HasBitFlag(hum->status, HS_Jump)) {
|
|
return;
|
|
}
|
|
if (hum->room->gas_data.gas_mode == GasInactive) {
|
|
return;
|
|
}
|
|
if (owner->updated_times % 10 == 0) {
|
|
Human* enemy = owner->room->FindEnemy((Human*)owner);
|
|
if (enemy) {
|
|
Human* sender = (Human*)owner;
|
|
a8::Vec2 shot_dir = enemy->pos - sender->pos;
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|