ai重构ok
This commit is contained in:
parent
1036102409
commit
ee0005663c
@ -1,5 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
namespace MetaData
|
||||||
|
{
|
||||||
|
class AI;
|
||||||
|
}
|
||||||
|
|
||||||
class MoveableEntity;
|
class MoveableEntity;
|
||||||
class AIComponent
|
class AIComponent
|
||||||
{
|
{
|
||||||
|
@ -18,6 +18,52 @@ enum ShotType_e
|
|||||||
kShotHold = 2,
|
kShotHold = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum AndroidState_e : int
|
||||||
|
{
|
||||||
|
AS_thinking,
|
||||||
|
AS_moving,
|
||||||
|
AS_attack
|
||||||
|
};
|
||||||
|
|
||||||
|
enum AndroidStateEx_e : int
|
||||||
|
{
|
||||||
|
ASE_Idle = 0,
|
||||||
|
ASE_Thinking = 1,
|
||||||
|
ASE_Attack = 2,
|
||||||
|
ASE_RandomWalk = 3,
|
||||||
|
ASE_Pursuit = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
class Human;
|
||||||
|
class AINode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AndroidStateEx_e main_state = ASE_Idle;
|
||||||
|
long long frameno = 0;
|
||||||
|
long long exec_frame_num = 0;
|
||||||
|
long long start_shot_frameno = 0;
|
||||||
|
long long next_random_move_frameno = 0;
|
||||||
|
int shot_times = 0;
|
||||||
|
int total_shot_times = 0;
|
||||||
|
int next_total_shot_times = 0;
|
||||||
|
|
||||||
|
long long param1 = 0;
|
||||||
|
CreatureWeakPtr target;
|
||||||
|
CreatureWeakPtr nearest_human;
|
||||||
|
long long last_check_nearest_human_frameno = 0;
|
||||||
|
a8::Vec2 shot_dir;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OldAiData
|
||||||
|
{
|
||||||
|
AndroidState_e state = AS_thinking;
|
||||||
|
int state_elapsed_time = 0;
|
||||||
|
CreatureWeakPtr last_target;
|
||||||
|
long long last_attack_frameno = 0;
|
||||||
|
long long last_findenemy_frameno = 0;
|
||||||
|
long long series_attack_frames = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
nn目标:ai可切换,降级/升级(根据系统当前负载)
|
nn目标:ai可切换,降级/升级(根据系统当前负载)
|
||||||
|
|
||||||
@ -32,13 +78,21 @@ ai级别
|
|||||||
8: 跑动射击
|
8: 跑动射击
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
AndroidNewAI::AndroidNewAI()
|
||||||
|
{
|
||||||
|
old_ai_data_ = new OldAiData();
|
||||||
|
node_ = new AINode();
|
||||||
|
}
|
||||||
|
|
||||||
AndroidNewAI::~AndroidNewAI()
|
AndroidNewAI::~AndroidNewAI()
|
||||||
{
|
{
|
||||||
|
A8_SAFE_DELETE(old_ai_data_);
|
||||||
|
A8_SAFE_DELETE(node_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidNewAI::Update(int delta_time)
|
void AndroidNewAI::Update(int delta_time)
|
||||||
{
|
{
|
||||||
old_ai_data_.state_elapsed_time += delta_time;
|
old_ai_data_->state_elapsed_time += delta_time;
|
||||||
Human* hum = (Human*)owner;
|
Human* hum = (Human*)owner;
|
||||||
if (hum->poisoning) {
|
if (hum->poisoning) {
|
||||||
hum->poisoning_time += delta_time;
|
hum->poisoning_time += delta_time;
|
||||||
@ -67,10 +121,10 @@ float AndroidNewAI::GetAttackRate()
|
|||||||
|
|
||||||
void AndroidNewAI::DefaultAi()
|
void AndroidNewAI::DefaultAi()
|
||||||
{
|
{
|
||||||
switch (old_ai_data_.state) {
|
switch (old_ai_data_->state) {
|
||||||
case AS_thinking:
|
case AS_thinking:
|
||||||
{
|
{
|
||||||
if (old_ai_data_.state_elapsed_time > 1500 + rand() % 3000) {
|
if (old_ai_data_->state_elapsed_time > 1500 + rand() % 3000) {
|
||||||
int rnd = rand();
|
int rnd = rand();
|
||||||
if (rnd % 100 < 30) {
|
if (rnd % 100 < 30) {
|
||||||
ChangeToStateOldAI(AS_moving);
|
ChangeToStateOldAI(AS_moving);
|
||||||
@ -82,7 +136,7 @@ void AndroidNewAI::DefaultAi()
|
|||||||
break;
|
break;
|
||||||
case AS_moving:
|
case AS_moving:
|
||||||
{
|
{
|
||||||
if (old_ai_data_.state_elapsed_time < 1000 + rand() % 2000) {
|
if (old_ai_data_->state_elapsed_time < 1000 + rand() % 2000) {
|
||||||
DoMoveOldAI();
|
DoMoveOldAI();
|
||||||
} else {
|
} else {
|
||||||
int rnd = rand();
|
int rnd = rand();
|
||||||
@ -96,8 +150,8 @@ void AndroidNewAI::DefaultAi()
|
|||||||
break;
|
break;
|
||||||
case AS_attack:
|
case AS_attack:
|
||||||
{
|
{
|
||||||
if ((old_ai_data_.state_elapsed_time < 3000 && old_ai_data_.last_target.Get()) ||
|
if ((old_ai_data_->state_elapsed_time < 3000 && old_ai_data_->last_target.Get()) ||
|
||||||
(old_ai_data_.state_elapsed_time < 1100)) {
|
(old_ai_data_->state_elapsed_time < 1100)) {
|
||||||
DoAttackOldAI();
|
DoAttackOldAI();
|
||||||
} else {
|
} else {
|
||||||
int rnd = rand();
|
int rnd = rand();
|
||||||
@ -114,9 +168,9 @@ void AndroidNewAI::DefaultAi()
|
|||||||
|
|
||||||
void AndroidNewAI::ChangeToStateOldAI(AndroidState_e to_state)
|
void AndroidNewAI::ChangeToStateOldAI(AndroidState_e to_state)
|
||||||
{
|
{
|
||||||
old_ai_data_.state = to_state;
|
old_ai_data_->state = to_state;
|
||||||
old_ai_data_.state_elapsed_time = 0;
|
old_ai_data_->state_elapsed_time = 0;
|
||||||
switch (old_ai_data_.state) {
|
switch (old_ai_data_->state) {
|
||||||
case AS_moving:
|
case AS_moving:
|
||||||
{
|
{
|
||||||
Human* hum = (Human*)owner;
|
Human* hum = (Human*)owner;
|
||||||
@ -186,7 +240,7 @@ void AndroidNewAI::DoAttackOldAI()
|
|||||||
bool shot_ok = false;
|
bool shot_ok = false;
|
||||||
sender->Shot(shot_dir, shot_ok, DEFAULT_FLY_DISTANCE);
|
sender->Shot(shot_dir, shot_ok, DEFAULT_FLY_DISTANCE);
|
||||||
}
|
}
|
||||||
old_ai_data_.last_target.Attach(enemy);
|
old_ai_data_->last_target.Attach(enemy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -206,9 +260,9 @@ void AndroidNewAI::UpdateNewAI()
|
|||||||
if (hum->playing_skill) {
|
if (hum->playing_skill) {
|
||||||
hum->UpdateSkill();
|
hum->UpdateSkill();
|
||||||
}
|
}
|
||||||
++node_.exec_frame_num;
|
++node_->exec_frame_num;
|
||||||
hum->shot_hold = false;
|
hum->shot_hold = false;
|
||||||
switch (node_.main_state) {
|
switch (node_->main_state) {
|
||||||
case ASE_Idle:
|
case ASE_Idle:
|
||||||
{
|
{
|
||||||
UpdateIdle();
|
UpdateIdle();
|
||||||
@ -248,7 +302,7 @@ void AndroidNewAI::UpdateNewAI()
|
|||||||
void AndroidNewAI::UpdateIdle()
|
void AndroidNewAI::UpdateIdle()
|
||||||
{
|
{
|
||||||
Human* hum = (Human*)owner;
|
Human* hum = (Human*)owner;
|
||||||
if (hum->room->GetFrameNo() > node_.frameno + node_.param1) {
|
if (hum->room->GetFrameNo() > node_->frameno + node_->param1) {
|
||||||
ChangeToStateNewAI(ASE_Thinking);
|
ChangeToStateNewAI(ASE_Thinking);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -268,10 +322,10 @@ void AndroidNewAI::UpdateThinking()
|
|||||||
} else {
|
} else {
|
||||||
Creature* target = GetTarget();
|
Creature* target = GetTarget();
|
||||||
if (target) {
|
if (target) {
|
||||||
node_.target.Attach(target);
|
node_->target.Attach(target);
|
||||||
ChangeToStateNewAI(ASE_Attack);
|
ChangeToStateNewAI(ASE_Attack);
|
||||||
} else {
|
} else {
|
||||||
if (hum->room->GetFrameNo() >= node_.next_random_move_frameno) {
|
if (hum->room->GetFrameNo() >= node_->next_random_move_frameno) {
|
||||||
if ((rand() % 7) < 4) {
|
if ((rand() % 7) < 4) {
|
||||||
ChangeToStateNewAI(ASE_Idle);
|
ChangeToStateNewAI(ASE_Idle);
|
||||||
} else {
|
} else {
|
||||||
@ -279,7 +333,7 @@ void AndroidNewAI::UpdateThinking()
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ChangeToStateNewAI(ASE_Idle);
|
ChangeToStateNewAI(ASE_Idle);
|
||||||
node_.param1 = node_.next_random_move_frameno - hum->room->GetFrameNo();
|
node_->param1 = node_->next_random_move_frameno - hum->room->GetFrameNo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -288,11 +342,11 @@ void AndroidNewAI::UpdateThinking()
|
|||||||
void AndroidNewAI::UpdateAttack()
|
void AndroidNewAI::UpdateAttack()
|
||||||
{
|
{
|
||||||
Human* myself = (Human*)owner;
|
Human* myself = (Human*)owner;
|
||||||
if (!node_.target.Get() || node_.target.Get()->dead) {
|
if (!node_->target.Get() || node_->target.Get()->dead) {
|
||||||
ChangeToStateNewAI(ASE_Thinking);
|
ChangeToStateNewAI(ASE_Thinking);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (node_.exec_frame_num > SERVER_FRAME_RATE * 8) {
|
if (node_->exec_frame_num > SERVER_FRAME_RATE * 8) {
|
||||||
ChangeToStateNewAI(ASE_Thinking);
|
ChangeToStateNewAI(ASE_Thinking);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -305,7 +359,7 @@ void AndroidNewAI::UpdateAttack()
|
|||||||
if (myself->HasBuffEffect(kBET_Vertigo)) {
|
if (myself->HasBuffEffect(kBET_Vertigo)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float distance = myself->GetPos().Distance(node_.target.Get()->GetPos());
|
float distance = myself->GetPos().Distance(node_->target.Get()->GetPos());
|
||||||
if (distance > GetAttackRange()) {
|
if (distance > GetAttackRange()) {
|
||||||
if (ai_meta->i->pursuit_radius() <= 0) {
|
if (ai_meta->i->pursuit_radius() <= 0) {
|
||||||
//站桩
|
//站桩
|
||||||
@ -325,12 +379,12 @@ void AndroidNewAI::UpdateAttack()
|
|||||||
case kShotClick:
|
case kShotClick:
|
||||||
{
|
{
|
||||||
if (ai_meta->i->attack_interval() > 0) {
|
if (ai_meta->i->attack_interval() > 0) {
|
||||||
if (node_.shot_times < GetAttackTimes()) {
|
if (node_->shot_times < GetAttackTimes()) {
|
||||||
DoShotNewAI();
|
DoShotNewAI();
|
||||||
} else {
|
} else {
|
||||||
ChangeToStateNewAI(ASE_Idle);
|
ChangeToStateNewAI(ASE_Idle);
|
||||||
node_.next_total_shot_times = node_.total_shot_times;
|
node_->next_total_shot_times = node_->total_shot_times;
|
||||||
node_.param1 = ai_meta->i->attack_interval() / 1000 * SERVER_FRAME_RATE;
|
node_->param1 = ai_meta->i->attack_interval() / 1000 * SERVER_FRAME_RATE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
myself->shot_hold = true;
|
myself->shot_hold = true;
|
||||||
@ -355,7 +409,7 @@ void AndroidNewAI::UpdateAttack()
|
|||||||
void AndroidNewAI::UpdateRandomWalk()
|
void AndroidNewAI::UpdateRandomWalk()
|
||||||
{
|
{
|
||||||
Human* hum = (Human*)owner;
|
Human* hum = (Human*)owner;
|
||||||
if (hum->room->GetFrameNo() > node_.frameno + node_.param1) {
|
if (hum->room->GetFrameNo() > node_->frameno + node_->param1) {
|
||||||
ChangeToStateNewAI(ASE_Thinking);
|
ChangeToStateNewAI(ASE_Thinking);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -363,19 +417,19 @@ void AndroidNewAI::UpdateRandomWalk()
|
|||||||
void AndroidNewAI::UpdatePursuit()
|
void AndroidNewAI::UpdatePursuit()
|
||||||
{
|
{
|
||||||
Human* myself = (Human*)owner;
|
Human* myself = (Human*)owner;
|
||||||
if (node_.target.Get()) {
|
if (node_->target.Get()) {
|
||||||
float distance = myself->GetPos().Distance(node_.target.Get()->GetPos());
|
float distance = myself->GetPos().Distance(node_->target.Get()->GetPos());
|
||||||
if (!myself->HasBuffEffect(kBET_Jump) &&
|
if (!myself->HasBuffEffect(kBET_Jump) &&
|
||||||
!a8::HasBitFlag(myself->status, HS_DisableAttack) &&
|
!a8::HasBitFlag(myself->status, HS_DisableAttack) &&
|
||||||
distance < GetAttackRange()) {
|
distance < GetAttackRange()) {
|
||||||
ChangeToStateNewAI(ASE_Attack);
|
ChangeToStateNewAI(ASE_Attack);
|
||||||
} else {
|
} else {
|
||||||
if (node_.exec_frame_num > 100 * 2) {
|
if (node_->exec_frame_num > 100 * 2) {
|
||||||
ChangeToStateNewAI(ASE_RandomWalk);
|
ChangeToStateNewAI(ASE_RandomWalk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (node_.exec_frame_num > 100 * 2) {
|
if (node_->exec_frame_num > 100 * 2) {
|
||||||
ChangeToStateNewAI(ASE_RandomWalk);
|
ChangeToStateNewAI(ASE_RandomWalk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -397,11 +451,11 @@ void AndroidNewAI::DoMoveNewAI()
|
|||||||
int speed = std::max(1, (int)hum->GetSpeed()) * 1;
|
int speed = std::max(1, (int)hum->GetSpeed()) * 1;
|
||||||
hum->_UpdateMove(speed);
|
hum->_UpdateMove(speed);
|
||||||
hum->on_move_collision = nullptr;
|
hum->on_move_collision = nullptr;
|
||||||
if (node_.nearest_human.Get()) {
|
if (node_->nearest_human.Get()) {
|
||||||
if (node_.main_state != ASE_Pursuit &&
|
if (node_->main_state != ASE_Pursuit &&
|
||||||
hum->GetPos().ManhattanDistance(node_.nearest_human.Get()->GetPos()) < 200) {
|
hum->GetPos().ManhattanDistance(node_->nearest_human.Get()->GetPos()) < 200) {
|
||||||
ChangeToStateNewAI(ASE_Thinking);
|
ChangeToStateNewAI(ASE_Thinking);
|
||||||
} else if (hum->GetPos().ManhattanDistance(node_.nearest_human.Get()->GetPos()) > 800) {
|
} else if (hum->GetPos().ManhattanDistance(node_->nearest_human.Get()->GetPos()) > 800) {
|
||||||
GetTarget();
|
GetTarget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -414,57 +468,57 @@ void AndroidNewAI::ChangeToStateNewAI(AndroidStateEx_e to_state)
|
|||||||
switch (to_state) {
|
switch (to_state) {
|
||||||
case ASE_Idle:
|
case ASE_Idle:
|
||||||
{
|
{
|
||||||
node_.target.Reset();
|
node_->target.Reset();
|
||||||
node_.param1 = 0;
|
node_->param1 = 0;
|
||||||
node_.start_shot_frameno = 0;
|
node_->start_shot_frameno = 0;
|
||||||
node_.shot_times = 0;
|
node_->shot_times = 0;
|
||||||
moving_ = false;
|
moving_ = false;
|
||||||
if (hum->room->GetGasData().gas_mode == GasInactive ||
|
if (hum->room->GetGasData().gas_mode == GasInactive ||
|
||||||
hum->room->IsWaitingStart() ||
|
hum->room->IsWaitingStart() ||
|
||||||
hum->HasBuffEffect(kBET_Jump)) {
|
hum->HasBuffEffect(kBET_Jump)) {
|
||||||
node_.param1 = rand() % (3 * SERVER_FRAME_RATE);
|
node_->param1 = rand() % (3 * SERVER_FRAME_RATE);
|
||||||
} else {
|
} else {
|
||||||
node_.param1 = rand() % (2 * SERVER_FRAME_RATE);
|
node_->param1 = rand() % (2 * SERVER_FRAME_RATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ASE_Thinking:
|
case ASE_Thinking:
|
||||||
{
|
{
|
||||||
node_.target.Reset();
|
node_->target.Reset();
|
||||||
node_.param1 = 0;
|
node_->param1 = 0;
|
||||||
node_.start_shot_frameno = 0;
|
node_->start_shot_frameno = 0;
|
||||||
node_.shot_times = 0;
|
node_->shot_times = 0;
|
||||||
moving_ = false;
|
moving_ = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ASE_Attack:
|
case ASE_Attack:
|
||||||
{
|
{
|
||||||
node_.param1 = 0;
|
node_->param1 = 0;
|
||||||
node_.start_shot_frameno = 0;
|
node_->start_shot_frameno = 0;
|
||||||
node_.shot_times = 0;
|
node_->shot_times = 0;
|
||||||
moving_ = false;
|
moving_ = false;
|
||||||
node_.shot_times = 0;
|
node_->shot_times = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ASE_RandomWalk:
|
case ASE_RandomWalk:
|
||||||
{
|
{
|
||||||
moving_ = true;
|
moving_ = true;
|
||||||
node_.target.Reset();
|
node_->target.Reset();
|
||||||
#if 1
|
#if 1
|
||||||
node_.param1 = SERVER_FRAME_RATE * ai_meta->GetMoveTime();
|
node_->param1 = SERVER_FRAME_RATE * ai_meta->GetMoveTime();
|
||||||
#else
|
#else
|
||||||
node_.param1 = SERVER_FRAME_RATE * 5 + rand() % (SERVER_FRAME_RATE * 3);
|
node_->param1 = SERVER_FRAME_RATE * 5 + rand() % (SERVER_FRAME_RATE * 3);
|
||||||
#endif
|
#endif
|
||||||
node_.start_shot_frameno = 0;
|
node_->start_shot_frameno = 0;
|
||||||
node_.shot_times = 0;
|
node_->shot_times = 0;
|
||||||
node_.next_random_move_frameno = hum->room->GetFrameNo() +
|
node_->next_random_move_frameno = hum->room->GetFrameNo() +
|
||||||
SERVER_FRAME_RATE * ai_meta->GetMoveIdleTime();
|
SERVER_FRAME_RATE * ai_meta->GetMoveIdleTime();
|
||||||
a8::Vec2 move_dir = a8::Vec2(1.0f, 0);
|
a8::Vec2 move_dir = a8::Vec2(1.0f, 0);
|
||||||
move_dir.Rotate(a8::RandAngle());
|
move_dir.Rotate(a8::RandAngle());
|
||||||
move_dir.Normalize();
|
move_dir.Normalize();
|
||||||
hum->SetMoveDir(move_dir);
|
hum->SetMoveDir(move_dir);
|
||||||
hum->SetAttackDir(hum->GetMoveDir());
|
hum->SetAttackDir(hum->GetMoveDir());
|
||||||
if (node_.param1 <= 1) {
|
if (node_->param1 <= 1) {
|
||||||
moving_ = false;
|
moving_ = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -472,8 +526,8 @@ void AndroidNewAI::ChangeToStateNewAI(AndroidStateEx_e to_state)
|
|||||||
case ASE_Pursuit:
|
case ASE_Pursuit:
|
||||||
{
|
{
|
||||||
moving_ = true;
|
moving_ = true;
|
||||||
if (node_.target.Get()) {
|
if (node_->target.Get()) {
|
||||||
a8::Vec2 move_dir = node_.target.Get()->GetPos() - hum->GetPos();
|
a8::Vec2 move_dir = node_->target.Get()->GetPos() - hum->GetPos();
|
||||||
move_dir.Normalize();
|
move_dir.Normalize();
|
||||||
hum->SetMoveDir(move_dir);
|
hum->SetMoveDir(move_dir);
|
||||||
hum->SetAttackDir(hum->GetMoveDir());
|
hum->SetAttackDir(hum->GetMoveDir());
|
||||||
@ -481,9 +535,9 @@ void AndroidNewAI::ChangeToStateNewAI(AndroidStateEx_e to_state)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
node_.main_state = to_state;
|
node_->main_state = to_state;
|
||||||
node_.frameno = hum->room->GetFrameNo();
|
node_->frameno = hum->room->GetFrameNo();
|
||||||
node_.exec_frame_num = 0;
|
node_->exec_frame_num = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Creature* AndroidNewAI::GetTarget()
|
Creature* AndroidNewAI::GetTarget()
|
||||||
@ -511,8 +565,8 @@ Creature* AndroidNewAI::GetTarget()
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (target) {
|
if (target) {
|
||||||
node_.nearest_human.Attach(target);
|
node_->nearest_human.Attach(target);
|
||||||
node_.last_check_nearest_human_frameno = myself->room->GetFrameNo();
|
node_->last_check_nearest_human_frameno = myself->room->GetFrameNo();
|
||||||
float distance = myself->GetPos().Distance(target->GetPos());
|
float distance = myself->GetPos().Distance(target->GetPos());
|
||||||
if (distance > GetAttackRange()) {
|
if (distance > GetAttackRange()) {
|
||||||
target = nullptr;
|
target = nullptr;
|
||||||
@ -535,15 +589,15 @@ float AndroidNewAI::GetAttackRange()
|
|||||||
void AndroidNewAI::DoShotNewAI()
|
void AndroidNewAI::DoShotNewAI()
|
||||||
{
|
{
|
||||||
Human* myself = (Human*)owner;
|
Human* myself = (Human*)owner;
|
||||||
if (!node_.target.Get()) {
|
if (!node_->target.Get()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shot_ok = false;
|
bool shot_ok = false;
|
||||||
a8::Vec2 shot_dir = myself->GetAttackDir();
|
a8::Vec2 shot_dir = myself->GetAttackDir();
|
||||||
if (node_.total_shot_times >= node_.next_total_shot_times) {
|
if (node_->total_shot_times >= node_->next_total_shot_times) {
|
||||||
shot_dir = node_.target.Get()->GetPos() - myself->GetPos();
|
shot_dir = node_->target.Get()->GetPos() - myself->GetPos();
|
||||||
node_.next_total_shot_times += 7 + (rand() % 6);
|
node_->next_total_shot_times += 7 + (rand() % 6);
|
||||||
myself->SetAttackDir(shot_dir);
|
myself->SetAttackDir(shot_dir);
|
||||||
}
|
}
|
||||||
if (std::abs(shot_dir.x) > FLT_EPSILON ||
|
if (std::abs(shot_dir.x) > FLT_EPSILON ||
|
||||||
@ -563,11 +617,11 @@ void AndroidNewAI::DoShotNewAI()
|
|||||||
myself->Shot(shot_dir, shot_ok, DEFAULT_FLY_DISTANCE);
|
myself->Shot(shot_dir, shot_ok, DEFAULT_FLY_DISTANCE);
|
||||||
myself->SetAttackDir(old_attack_dir);
|
myself->SetAttackDir(old_attack_dir);
|
||||||
if (shot_ok) {
|
if (shot_ok) {
|
||||||
if (node_.shot_times <= 0) {
|
if (node_->shot_times <= 0) {
|
||||||
node_.start_shot_frameno = myself->room->GetFrameNo();
|
node_->start_shot_frameno = myself->room->GetFrameNo();
|
||||||
}
|
}
|
||||||
++node_.shot_times;
|
++node_->shot_times;
|
||||||
++node_.total_shot_times;
|
++node_->total_shot_times;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -581,4 +635,3 @@ int AndroidNewAI::GetAttackTimes()
|
|||||||
return ai_meta->i->attack_times();
|
return ai_meta->i->attack_times();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,62 +3,16 @@
|
|||||||
#include "aicomponent.h"
|
#include "aicomponent.h"
|
||||||
#include "weakptr.h"
|
#include "weakptr.h"
|
||||||
|
|
||||||
enum AndroidState_e
|
enum AndroidStateEx_e : int;
|
||||||
{
|
enum AndroidState_e : int;
|
||||||
AS_thinking,
|
struct OldAiData;
|
||||||
AS_moving,
|
struct AINode;
|
||||||
AS_attack
|
|
||||||
};
|
|
||||||
|
|
||||||
enum AndroidStateEx_e
|
|
||||||
{
|
|
||||||
ASE_Idle = 0,
|
|
||||||
ASE_Thinking = 1,
|
|
||||||
ASE_Attack = 2,
|
|
||||||
ASE_RandomWalk = 3,
|
|
||||||
ASE_Pursuit = 4
|
|
||||||
};
|
|
||||||
|
|
||||||
class Human;
|
|
||||||
class AINode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AndroidStateEx_e main_state = ASE_Idle;
|
|
||||||
long long frameno = 0;
|
|
||||||
long long exec_frame_num = 0;
|
|
||||||
long long start_shot_frameno = 0;
|
|
||||||
long long next_random_move_frameno = 0;
|
|
||||||
int shot_times = 0;
|
|
||||||
int total_shot_times = 0;
|
|
||||||
int next_total_shot_times = 0;
|
|
||||||
|
|
||||||
long long param1 = 0;
|
|
||||||
CreatureWeakPtr target;
|
|
||||||
CreatureWeakPtr nearest_human;
|
|
||||||
long long last_check_nearest_human_frameno = 0;
|
|
||||||
a8::Vec2 shot_dir;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct OldAiData
|
|
||||||
{
|
|
||||||
AndroidState_e state = AS_thinking;
|
|
||||||
int state_elapsed_time = 0;
|
|
||||||
CreatureWeakPtr last_target;
|
|
||||||
long long last_attack_frameno = 0;
|
|
||||||
long long last_findenemy_frameno = 0;
|
|
||||||
long long series_attack_frames = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace MetaData
|
|
||||||
{
|
|
||||||
class AI;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Human;
|
class Human;
|
||||||
class AndroidNewAI : public AIComponent
|
class AndroidNewAI : public AIComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
AndroidNewAI();
|
||||||
virtual ~AndroidNewAI() override;
|
virtual ~AndroidNewAI() override;
|
||||||
virtual void Update(int delta_time) override;
|
virtual void Update(int delta_time) override;
|
||||||
float GetAttackRate();
|
float GetAttackRate();
|
||||||
@ -84,9 +38,9 @@ private:
|
|||||||
int GetAttackTimes();
|
int GetAttackTimes();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OldAiData old_ai_data_;
|
OldAiData* old_ai_data_ = nullptr;
|
||||||
|
|
||||||
MetaData::AI* ai_meta = nullptr;
|
MetaData::AI* ai_meta = nullptr;
|
||||||
AINode node_;
|
AINode* node_ = nullptr;
|
||||||
bool moving_ = false;
|
bool moving_ = false;
|
||||||
};
|
};
|
||||||
|
@ -15,8 +15,44 @@ enum ShotType_e
|
|||||||
kShotHold = 2,
|
kShotHold = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum HeroState_e : int
|
||||||
|
{
|
||||||
|
HSE_Idle = 0,
|
||||||
|
HSE_Thinking = 1,
|
||||||
|
HSE_Attack = 2,
|
||||||
|
HSE_RandomWalk = 3,
|
||||||
|
HSE_Pursuit = 4,
|
||||||
|
HSE_FollowMaster = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
class HeroAINode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HeroState_e main_state = HSE_Idle;
|
||||||
|
long long frameno = 0;
|
||||||
|
long long exec_frame_num = 0;
|
||||||
|
long long start_shot_frameno = 0;
|
||||||
|
long long next_random_move_frameno = 0;
|
||||||
|
int shot_times = 0;
|
||||||
|
int total_shot_times = 0;
|
||||||
|
int next_total_shot_times = 0;
|
||||||
|
|
||||||
|
long long param1 = 0;
|
||||||
|
CreatureWeakPtr target;
|
||||||
|
CreatureWeakPtr nearest_human;
|
||||||
|
long long last_check_nearest_human_frameno = 0;
|
||||||
|
a8::Vec2 shot_dir;
|
||||||
|
a8::Vec2 target_pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
HeroAI::HeroAI()
|
||||||
|
{
|
||||||
|
node_ = new HeroAINode();
|
||||||
|
}
|
||||||
|
|
||||||
HeroAI::~HeroAI()
|
HeroAI::~HeroAI()
|
||||||
{
|
{
|
||||||
|
A8_SAFE_DELETE(node_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HeroAI::Update(int delta_time)
|
void HeroAI::Update(int delta_time)
|
||||||
@ -52,9 +88,9 @@ void HeroAI::UpdateAI()
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++node_.exec_frame_num;
|
++node_->exec_frame_num;
|
||||||
hero->shot_hold = false;
|
hero->shot_hold = false;
|
||||||
switch (node_.main_state) {
|
switch (node_->main_state) {
|
||||||
case HSE_Idle:
|
case HSE_Idle:
|
||||||
{
|
{
|
||||||
UpdateIdle();
|
UpdateIdle();
|
||||||
@ -99,7 +135,7 @@ void HeroAI::UpdateAI()
|
|||||||
void HeroAI::UpdateIdle()
|
void HeroAI::UpdateIdle()
|
||||||
{
|
{
|
||||||
Hero* hero = (Hero*)owner;
|
Hero* hero = (Hero*)owner;
|
||||||
if (hero->room->GetFrameNo() > node_.frameno + node_.param1) {
|
if (hero->room->GetFrameNo() > node_->frameno + node_->param1) {
|
||||||
ChangeToStateAI(HSE_Thinking);
|
ChangeToStateAI(HSE_Thinking);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,10 +161,10 @@ void HeroAI::UpdateThinking()
|
|||||||
}
|
}
|
||||||
Creature* target = GetTarget();
|
Creature* target = GetTarget();
|
||||||
if (target) {
|
if (target) {
|
||||||
node_.target.Attach(target);
|
node_->target.Attach(target);
|
||||||
ChangeToStateAI(HSE_Attack);
|
ChangeToStateAI(HSE_Attack);
|
||||||
} else {
|
} else {
|
||||||
if (hero->room->GetFrameNo() >= node_.next_random_move_frameno) {
|
if (hero->room->GetFrameNo() >= node_->next_random_move_frameno) {
|
||||||
if ((rand() % 7) < 4) {
|
if ((rand() % 7) < 4) {
|
||||||
ChangeToStateAI(HSE_Idle);
|
ChangeToStateAI(HSE_Idle);
|
||||||
} else {
|
} else {
|
||||||
@ -136,7 +172,7 @@ void HeroAI::UpdateThinking()
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ChangeToStateAI(HSE_Idle);
|
ChangeToStateAI(HSE_Idle);
|
||||||
node_.param1 = node_.next_random_move_frameno - hero->room->GetFrameNo();
|
node_->param1 = node_->next_random_move_frameno - hero->room->GetFrameNo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,18 +181,18 @@ void HeroAI::UpdateThinking()
|
|||||||
void HeroAI::UpdateAttack()
|
void HeroAI::UpdateAttack()
|
||||||
{
|
{
|
||||||
Hero* myself = (Hero*)owner;
|
Hero* myself = (Hero*)owner;
|
||||||
if (!node_.target.Get() || node_.target.Get()->dead) {
|
if (!node_->target.Get() || node_->target.Get()->dead) {
|
||||||
ChangeToStateAI(HSE_Thinking);
|
ChangeToStateAI(HSE_Thinking);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (node_.exec_frame_num > SERVER_FRAME_RATE * 8) {
|
if (node_->exec_frame_num > SERVER_FRAME_RATE * 8) {
|
||||||
ChangeToStateAI(HSE_Thinking);
|
ChangeToStateAI(HSE_Thinking);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (myself->HasBuffEffect(kBET_Vertigo)) {
|
if (myself->HasBuffEffect(kBET_Vertigo)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float distance = myself->GetPos().Distance(node_.target.Get()->GetPos());
|
float distance = myself->GetPos().Distance(node_->target.Get()->GetPos());
|
||||||
if (distance > GetAttackRange()) {
|
if (distance > GetAttackRange()) {
|
||||||
if (ai_meta->i->pursuit_radius() <= 0) {
|
if (ai_meta->i->pursuit_radius() <= 0) {
|
||||||
//站桩
|
//站桩
|
||||||
@ -176,12 +212,12 @@ void HeroAI::UpdateAttack()
|
|||||||
case kShotClick:
|
case kShotClick:
|
||||||
{
|
{
|
||||||
if (ai_meta->i->attack_interval() > 0) {
|
if (ai_meta->i->attack_interval() > 0) {
|
||||||
if (node_.shot_times < GetAttackTimes()) {
|
if (node_->shot_times < GetAttackTimes()) {
|
||||||
DoShotAI();
|
DoShotAI();
|
||||||
} else {
|
} else {
|
||||||
ChangeToStateAI(HSE_Idle);
|
ChangeToStateAI(HSE_Idle);
|
||||||
node_.next_total_shot_times = node_.total_shot_times;
|
node_->next_total_shot_times = node_->total_shot_times;
|
||||||
node_.param1 = ai_meta->i->attack_interval() / 1000 * SERVER_FRAME_RATE;
|
node_->param1 = ai_meta->i->attack_interval() / 1000 * SERVER_FRAME_RATE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
myself->shot_hold = true;
|
myself->shot_hold = true;
|
||||||
@ -206,7 +242,7 @@ void HeroAI::UpdateAttack()
|
|||||||
void HeroAI::UpdateRandomWalk()
|
void HeroAI::UpdateRandomWalk()
|
||||||
{
|
{
|
||||||
Hero* hero = (Hero*)owner;
|
Hero* hero = (Hero*)owner;
|
||||||
if (hero->room->GetFrameNo() > node_.frameno + node_.param1) {
|
if (hero->room->GetFrameNo() > node_->frameno + node_->param1) {
|
||||||
ChangeToStateAI(HSE_Thinking);
|
ChangeToStateAI(HSE_Thinking);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -214,12 +250,12 @@ void HeroAI::UpdateRandomWalk()
|
|||||||
void HeroAI::UpdatePursuit()
|
void HeroAI::UpdatePursuit()
|
||||||
{
|
{
|
||||||
Hero* myself = (Hero*)owner;
|
Hero* myself = (Hero*)owner;
|
||||||
float distance = myself->GetPos().Distance(node_.target.Get()->GetPos());
|
float distance = myself->GetPos().Distance(node_->target.Get()->GetPos());
|
||||||
if (!myself->HasBuffEffect(kBET_Jump) &&
|
if (!myself->HasBuffEffect(kBET_Jump) &&
|
||||||
distance < GetAttackRange()) {
|
distance < GetAttackRange()) {
|
||||||
ChangeToStateAI(HSE_Attack);
|
ChangeToStateAI(HSE_Attack);
|
||||||
} else {
|
} else {
|
||||||
if (node_.exec_frame_num > 100 * 2) {
|
if (node_->exec_frame_num > 100 * 2) {
|
||||||
ChangeToStateAI(HSE_RandomWalk);
|
ChangeToStateAI(HSE_RandomWalk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -229,7 +265,7 @@ void HeroAI::UpdateFollowMaster()
|
|||||||
{
|
{
|
||||||
Hero* myself = (Hero*)owner;
|
Hero* myself = (Hero*)owner;
|
||||||
if (myself->master.Get()) {
|
if (myself->master.Get()) {
|
||||||
float mdistance = myself->GetPos().ManhattanDistance(node_.target_pos);
|
float mdistance = myself->GetPos().ManhattanDistance(node_->target_pos);
|
||||||
if (mdistance < 10) {
|
if (mdistance < 10) {
|
||||||
ChangeToStateAI(HSE_Thinking);
|
ChangeToStateAI(HSE_Thinking);
|
||||||
}
|
}
|
||||||
@ -247,7 +283,7 @@ void HeroAI::DoMoveAI()
|
|||||||
auto old_on_move_collision_func = hero->on_move_collision;
|
auto old_on_move_collision_func = hero->on_move_collision;
|
||||||
hero->on_move_collision =
|
hero->on_move_collision =
|
||||||
[this] () {
|
[this] () {
|
||||||
if (node_.main_state == HSE_FollowMaster) {
|
if (node_->main_state == HSE_FollowMaster) {
|
||||||
ChangeToStateAI(HSE_FollowMaster);
|
ChangeToStateAI(HSE_FollowMaster);
|
||||||
} else {
|
} else {
|
||||||
ChangeToStateAI(HSE_RandomWalk);
|
ChangeToStateAI(HSE_RandomWalk);
|
||||||
@ -266,57 +302,57 @@ void HeroAI::ChangeToStateAI(HeroState_e to_state)
|
|||||||
switch (to_state) {
|
switch (to_state) {
|
||||||
case HSE_Idle:
|
case HSE_Idle:
|
||||||
{
|
{
|
||||||
node_.target.Reset();
|
node_->target.Reset();
|
||||||
node_.param1 = 0;
|
node_->param1 = 0;
|
||||||
node_.start_shot_frameno = 0;
|
node_->start_shot_frameno = 0;
|
||||||
node_.shot_times = 0;
|
node_->shot_times = 0;
|
||||||
moving_ = false;
|
moving_ = false;
|
||||||
if (hero->room->GetGasData().gas_mode == GasInactive ||
|
if (hero->room->GetGasData().gas_mode == GasInactive ||
|
||||||
hero->room->IsWaitingStart() ||
|
hero->room->IsWaitingStart() ||
|
||||||
hero->HasBuffEffect(kBET_Jump)) {
|
hero->HasBuffEffect(kBET_Jump)) {
|
||||||
node_.param1 = rand() % (3 * SERVER_FRAME_RATE);
|
node_->param1 = rand() % (3 * SERVER_FRAME_RATE);
|
||||||
} else {
|
} else {
|
||||||
node_.param1 = rand() % (2 * SERVER_FRAME_RATE);
|
node_->param1 = rand() % (2 * SERVER_FRAME_RATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HSE_Thinking:
|
case HSE_Thinking:
|
||||||
{
|
{
|
||||||
node_.target.Reset();
|
node_->target.Reset();
|
||||||
node_.param1 = 0;
|
node_->param1 = 0;
|
||||||
node_.start_shot_frameno = 0;
|
node_->start_shot_frameno = 0;
|
||||||
node_.shot_times = 0;
|
node_->shot_times = 0;
|
||||||
moving_ = false;
|
moving_ = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HSE_Attack:
|
case HSE_Attack:
|
||||||
{
|
{
|
||||||
node_.param1 = 0;
|
node_->param1 = 0;
|
||||||
node_.start_shot_frameno = 0;
|
node_->start_shot_frameno = 0;
|
||||||
node_.shot_times = 0;
|
node_->shot_times = 0;
|
||||||
moving_ = false;
|
moving_ = false;
|
||||||
node_.shot_times = 0;
|
node_->shot_times = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HSE_RandomWalk:
|
case HSE_RandomWalk:
|
||||||
{
|
{
|
||||||
moving_ = true;
|
moving_ = true;
|
||||||
node_.target.Reset();
|
node_->target.Reset();
|
||||||
#if 1
|
#if 1
|
||||||
node_.param1 = SERVER_FRAME_RATE * ai_meta->GetMoveTime();
|
node_->param1 = SERVER_FRAME_RATE * ai_meta->GetMoveTime();
|
||||||
#else
|
#else
|
||||||
node_.param1 = SERVER_FRAME_RATE * 5 + rand() % (SERVER_FRAME_RATE * 3);
|
node_->param1 = SERVER_FRAME_RATE * 5 + rand() % (SERVER_FRAME_RATE * 3);
|
||||||
#endif
|
#endif
|
||||||
node_.start_shot_frameno = 0;
|
node_->start_shot_frameno = 0;
|
||||||
node_.shot_times = 0;
|
node_->shot_times = 0;
|
||||||
node_.next_random_move_frameno = hero->room->GetFrameNo() +
|
node_->next_random_move_frameno = hero->room->GetFrameNo() +
|
||||||
SERVER_FRAME_RATE * ai_meta->GetMoveIdleTime();
|
SERVER_FRAME_RATE * ai_meta->GetMoveIdleTime();
|
||||||
a8::Vec2 move_dir = a8::Vec2(1.0f, 0);
|
a8::Vec2 move_dir = a8::Vec2(1.0f, 0);
|
||||||
move_dir.Rotate(a8::RandAngle());
|
move_dir.Rotate(a8::RandAngle());
|
||||||
move_dir.Normalize();
|
move_dir.Normalize();
|
||||||
hero->SetMoveDir(move_dir);
|
hero->SetMoveDir(move_dir);
|
||||||
hero->SetAttackDir(hero->GetMoveDir());
|
hero->SetAttackDir(hero->GetMoveDir());
|
||||||
if (node_.param1 <= 1) {
|
if (node_->param1 <= 1) {
|
||||||
moving_ = false;
|
moving_ = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -324,8 +360,8 @@ void HeroAI::ChangeToStateAI(HeroState_e to_state)
|
|||||||
case HSE_Pursuit:
|
case HSE_Pursuit:
|
||||||
{
|
{
|
||||||
moving_ = true;
|
moving_ = true;
|
||||||
if (node_.target.Get()) {
|
if (node_->target.Get()) {
|
||||||
a8::Vec2 move_dir = node_.target.Get()->GetPos() - hero->GetPos();
|
a8::Vec2 move_dir = node_->target.Get()->GetPos() - hero->GetPos();
|
||||||
move_dir.Normalize();
|
move_dir.Normalize();
|
||||||
hero->SetMoveDir(move_dir);
|
hero->SetMoveDir(move_dir);
|
||||||
hero->SetAttackDir(hero->GetMoveDir());
|
hero->SetAttackDir(hero->GetMoveDir());
|
||||||
@ -344,14 +380,14 @@ void HeroAI::ChangeToStateAI(HeroState_e to_state)
|
|||||||
move_dir.Normalize();
|
move_dir.Normalize();
|
||||||
hero->SetMoveDir(move_dir);
|
hero->SetMoveDir(move_dir);
|
||||||
hero->SetAttackDir(hero->GetMoveDir());
|
hero->SetAttackDir(hero->GetMoveDir());
|
||||||
node_.target_pos = target_pos;
|
node_->target_pos = target_pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
node_.main_state = to_state;
|
node_->main_state = to_state;
|
||||||
node_.frameno = hero->room->GetFrameNo();
|
node_->frameno = hero->room->GetFrameNo();
|
||||||
node_.exec_frame_num = 0;
|
node_->exec_frame_num = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Creature* HeroAI::GetTarget()
|
Creature* HeroAI::GetTarget()
|
||||||
@ -379,8 +415,8 @@ Creature* HeroAI::GetTarget()
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (target) {
|
if (target) {
|
||||||
node_.nearest_human.Attach(target);
|
node_->nearest_human.Attach(target);
|
||||||
node_.last_check_nearest_human_frameno = myself->room->GetFrameNo();
|
node_->last_check_nearest_human_frameno = myself->room->GetFrameNo();
|
||||||
float distance = myself->GetPos().Distance(target->GetPos());
|
float distance = myself->GetPos().Distance(target->GetPos());
|
||||||
if (distance > GetAttackRange()) {
|
if (distance > GetAttackRange()) {
|
||||||
target = nullptr;
|
target = nullptr;
|
||||||
@ -403,15 +439,15 @@ float HeroAI::GetAttackRange()
|
|||||||
void HeroAI::DoShotAI()
|
void HeroAI::DoShotAI()
|
||||||
{
|
{
|
||||||
Hero* myself = (Hero*)owner;
|
Hero* myself = (Hero*)owner;
|
||||||
if (!node_.target.Get()) {
|
if (!node_->target.Get()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shot_ok = false;
|
bool shot_ok = false;
|
||||||
a8::Vec2 shot_dir = myself->GetAttackDir();
|
a8::Vec2 shot_dir = myself->GetAttackDir();
|
||||||
if (node_.total_shot_times >= node_.next_total_shot_times) {
|
if (node_->total_shot_times >= node_->next_total_shot_times) {
|
||||||
shot_dir = node_.target.Get()->GetPos() - myself->GetPos();
|
shot_dir = node_->target.Get()->GetPos() - myself->GetPos();
|
||||||
node_.next_total_shot_times += 7 + (rand() % 6);
|
node_->next_total_shot_times += 7 + (rand() % 6);
|
||||||
myself->SetAttackDir(shot_dir);
|
myself->SetAttackDir(shot_dir);
|
||||||
}
|
}
|
||||||
if (std::abs(shot_dir.x) > FLT_EPSILON ||
|
if (std::abs(shot_dir.x) > FLT_EPSILON ||
|
||||||
@ -431,11 +467,11 @@ void HeroAI::DoShotAI()
|
|||||||
myself->Shot(shot_dir, shot_ok, DEFAULT_FLY_DISTANCE);
|
myself->Shot(shot_dir, shot_ok, DEFAULT_FLY_DISTANCE);
|
||||||
myself->SetAttackDir(old_attack_dir);
|
myself->SetAttackDir(old_attack_dir);
|
||||||
if (shot_ok) {
|
if (shot_ok) {
|
||||||
if (node_.shot_times <= 0) {
|
if (node_->shot_times <= 0) {
|
||||||
node_.start_shot_frameno = myself->room->GetFrameNo();
|
node_->start_shot_frameno = myself->room->GetFrameNo();
|
||||||
}
|
}
|
||||||
++node_.shot_times;
|
++node_->shot_times;
|
||||||
++node_.total_shot_times;
|
++node_->total_shot_times;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,46 +3,13 @@
|
|||||||
#include "aicomponent.h"
|
#include "aicomponent.h"
|
||||||
#include "weakptr.h"
|
#include "weakptr.h"
|
||||||
|
|
||||||
namespace MetaData
|
enum HeroState_e : int;
|
||||||
{
|
class HeroAINode;
|
||||||
class AI;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum HeroState_e
|
|
||||||
{
|
|
||||||
HSE_Idle = 0,
|
|
||||||
HSE_Thinking = 1,
|
|
||||||
HSE_Attack = 2,
|
|
||||||
HSE_RandomWalk = 3,
|
|
||||||
HSE_Pursuit = 4,
|
|
||||||
HSE_FollowMaster = 5
|
|
||||||
};
|
|
||||||
|
|
||||||
class Human;
|
|
||||||
class HeroAINode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
HeroState_e main_state = HSE_Idle;
|
|
||||||
long long frameno = 0;
|
|
||||||
long long exec_frame_num = 0;
|
|
||||||
long long start_shot_frameno = 0;
|
|
||||||
long long next_random_move_frameno = 0;
|
|
||||||
int shot_times = 0;
|
|
||||||
int total_shot_times = 0;
|
|
||||||
int next_total_shot_times = 0;
|
|
||||||
|
|
||||||
long long param1 = 0;
|
|
||||||
CreatureWeakPtr target;
|
|
||||||
CreatureWeakPtr nearest_human;
|
|
||||||
long long last_check_nearest_human_frameno = 0;
|
|
||||||
a8::Vec2 shot_dir;
|
|
||||||
a8::Vec2 target_pos;
|
|
||||||
};
|
|
||||||
|
|
||||||
class HeroAI : public AIComponent
|
class HeroAI : public AIComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
HeroAI();
|
||||||
virtual ~HeroAI() override;
|
virtual ~HeroAI() override;
|
||||||
virtual void Update(int delta_time) override;
|
virtual void Update(int delta_time) override;
|
||||||
float GetAttackRate();
|
float GetAttackRate();
|
||||||
@ -65,6 +32,6 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
MetaData::AI* ai_meta = nullptr;
|
MetaData::AI* ai_meta = nullptr;
|
||||||
HeroAINode node_;
|
HeroAINode* node_ = nullptr;
|
||||||
bool moving_ = false;
|
bool moving_ = false;
|
||||||
};
|
};
|
||||||
|
@ -19,6 +19,15 @@ enum ShotType_e
|
|||||||
kShotHold = 2,
|
kShotHold = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ZombieState_e : int
|
||||||
|
{
|
||||||
|
ZSE_Idle = 0,
|
||||||
|
ZSE_Thinking = 1,
|
||||||
|
ZSE_Attack = 2,
|
||||||
|
ZSE_RandomWalk = 3,
|
||||||
|
ZSE_Pursuit = 4
|
||||||
|
};
|
||||||
|
|
||||||
class ZombieAINode
|
class ZombieAINode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -2,16 +2,7 @@
|
|||||||
|
|
||||||
#include "aicomponent.h"
|
#include "aicomponent.h"
|
||||||
|
|
||||||
enum ZombieState_e
|
enum ZombieState_e : int;
|
||||||
{
|
|
||||||
ZSE_Idle = 0,
|
|
||||||
ZSE_Thinking = 1,
|
|
||||||
ZSE_Attack = 2,
|
|
||||||
ZSE_RandomWalk = 3,
|
|
||||||
ZSE_Pursuit = 4
|
|
||||||
};
|
|
||||||
|
|
||||||
class Human;
|
|
||||||
class Creature;
|
class Creature;
|
||||||
class ZombieAINode;
|
class ZombieAINode;
|
||||||
class ZombieModeAI : public AIComponent
|
class ZombieModeAI : public AIComponent
|
||||||
|
Loading…
x
Reference in New Issue
Block a user