添加ai
This commit is contained in:
parent
dab78aad55
commit
e61e88653c
@ -19,13 +19,12 @@ AndroidAI::~AndroidAI()
|
|||||||
|
|
||||||
void AndroidAI::Update(int delta_time)
|
void AndroidAI::Update(int delta_time)
|
||||||
{
|
{
|
||||||
Human* hum = (Human*)owner;
|
|
||||||
state_elapsed_time_ += delta_time;
|
state_elapsed_time_ += delta_time;
|
||||||
if (hum->dead) {
|
if (HumMaster()->dead) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (hum->playing_skill) {
|
if (HumMaster()->playing_skill) {
|
||||||
hum->UpdateSkill();
|
HumMaster()->UpdateSkill();
|
||||||
}
|
}
|
||||||
switch (state_) {
|
switch (state_) {
|
||||||
case AS_thinking:
|
case AS_thinking:
|
||||||
@ -42,9 +41,22 @@ void AndroidAI::Update(int delta_time)
|
|||||||
break;
|
break;
|
||||||
case AS_moving:
|
case AS_moving:
|
||||||
{
|
{
|
||||||
|
bool need_chg = true;
|
||||||
if (state_elapsed_time_ < 1000 + rand() % 2000) {
|
if (state_elapsed_time_ < 1000 + rand() % 2000) {
|
||||||
DoMove();
|
DoMove();
|
||||||
|
need_chg = false;
|
||||||
|
} else if (locked_enemy_ && !locked_enemy_->dead &&
|
||||||
|
HumMaster()->pos.Distance(locked_enemy_->pos) < MetaMgr::Instance()->robot_pursuit_range) {
|
||||||
|
if (HumMaster()->pos.Distance(locked_enemy_->pos) < MetaMgr::Instance()->robot_attack_range) {
|
||||||
|
ChangeToState(AS_attack);
|
||||||
} else {
|
} else {
|
||||||
|
HumMaster()->move_dir = locked_enemy_->pos - HumMaster()->pos;
|
||||||
|
HumMaster()->move_dir.Normalize();
|
||||||
|
DoMove();
|
||||||
|
}
|
||||||
|
need_chg = false;
|
||||||
|
}
|
||||||
|
if (need_chg) {
|
||||||
int rnd = rand();
|
int rnd = rand();
|
||||||
if (rnd % 100 < 30) {
|
if (rnd % 100 < 30) {
|
||||||
ChangeToState(AS_thinking);
|
ChangeToState(AS_thinking);
|
||||||
@ -56,9 +68,20 @@ void AndroidAI::Update(int delta_time)
|
|||||||
break;
|
break;
|
||||||
case AS_attack:
|
case AS_attack:
|
||||||
{
|
{
|
||||||
|
bool need_chg = true;
|
||||||
if (state_elapsed_time_ < 1000) {
|
if (state_elapsed_time_ < 1000) {
|
||||||
DoAttack();
|
DoAttack();
|
||||||
|
need_chg = false;
|
||||||
|
} else if (locked_enemy_ && locked_enemy_->dead &&
|
||||||
|
HumMaster()->pos.Distance(locked_enemy_->pos) < MetaMgr::Instance()->robot_pursuit_range) {
|
||||||
|
if (HumMaster()->pos.Distance(locked_enemy_->pos) > MetaMgr::Instance()->robot_attack_range) {
|
||||||
|
ChangeToState(AS_moving);
|
||||||
} else {
|
} else {
|
||||||
|
DoAttack();
|
||||||
|
}
|
||||||
|
need_chg = false;
|
||||||
|
}
|
||||||
|
if (need_chg) {
|
||||||
int rnd = rand();
|
int rnd = rand();
|
||||||
if (rnd % 100 < 30) {
|
if (rnd % 100 < 30) {
|
||||||
ChangeToState(AS_moving);
|
ChangeToState(AS_moving);
|
||||||
@ -68,6 +91,8 @@ void AndroidAI::Update(int delta_time)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,11 +130,21 @@ void AndroidAI::ChangeToState(AndroidState_e to_state)
|
|||||||
switch (state_) {
|
switch (state_) {
|
||||||
case AS_moving:
|
case AS_moving:
|
||||||
{
|
{
|
||||||
Human* hum = (Human*)owner;
|
if (locked_enemy_) {
|
||||||
hum->move_dir = a8::Vec2(1.0f, 0);
|
a8::Vec2 move_dir = locked_enemy_->pos - HumMaster()->pos;
|
||||||
hum->move_dir.Rotate(a8::RandAngle());
|
if (std::abs(move_dir.x) > 0.00001f ||
|
||||||
hum->move_dir.Normalize();
|
std::abs(move_dir.y) > 0.00001f) {
|
||||||
hum->attack_dir = hum->move_dir;
|
HumMaster()->move_dir = move_dir;
|
||||||
|
HumMaster()->move_dir.Normalize();
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HumMaster()->move_dir = a8::Vec2(1.0f, 0);
|
||||||
|
HumMaster()->move_dir.Rotate(a8::RandAngle());
|
||||||
|
HumMaster()->move_dir.Normalize();
|
||||||
|
}
|
||||||
|
HumMaster()->attack_dir = HumMaster()->move_dir;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -119,47 +154,44 @@ void AndroidAI::ChangeToState(AndroidState_e to_state)
|
|||||||
|
|
||||||
void AndroidAI::DoMove()
|
void AndroidAI::DoMove()
|
||||||
{
|
{
|
||||||
Human* hum = (Human*)owner;
|
if (HumMaster()->HasBuffEffect(kBET_Vertigo) || HumMaster()->HasBuffEffect(kBET_Dcgr)) {
|
||||||
if (hum->HasBuffEffect(kBET_Vertigo) || hum->HasBuffEffect(kBET_Dcgr)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (owner->updated_times % 2 == 0) {
|
if (owner->updated_times % 2 == 0) {
|
||||||
Human* hum = (Human*)owner;
|
int speed = std::max(1, (int)HumMaster()->GetSpeed());
|
||||||
int speed = std::max(1, (int)hum->GetSpeed());
|
|
||||||
for (int i = 0; i < speed; ++i) {
|
for (int i = 0; i < speed; ++i) {
|
||||||
a8::Vec2 old_pos = hum->pos;
|
a8::Vec2 old_pos = HumMaster()->pos;
|
||||||
hum->pos = hum->pos + hum->move_dir;
|
HumMaster()->pos = HumMaster()->pos + HumMaster()->move_dir;
|
||||||
if (hum->IsCollisionInMapService()) {
|
if (HumMaster()->IsCollisionInMapService()) {
|
||||||
hum->pos = old_pos;
|
HumMaster()->pos = old_pos;
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
hum->FindPath();
|
HumMaster()->FindPath();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
hum->room->grid_service.MoveHuman(hum);
|
HumMaster()->room->grid_service.MoveHuman(HumMaster());
|
||||||
}
|
}
|
||||||
hum->CheckGrass();
|
HumMaster()->CheckGrass();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidAI::DoAttack()
|
void AndroidAI::DoAttack()
|
||||||
{
|
{
|
||||||
Human* hum = (Human*)owner;
|
if (HumMaster()->room->gas_data.gas_mode == kGasInactive) {
|
||||||
if (hum->room->gas_data.gas_mode == kGasInactive) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (hum->HasBuffEffect(kBET_Vertigo) || hum->HasBuffEffect(kBET_Dcgr)) {
|
if (HumMaster()->HasBuffEffect(kBET_Vertigo) || HumMaster()->HasBuffEffect(kBET_Dcgr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (owner->updated_times % 10 == 0) {
|
if (owner->updated_times % 10 == 0) {
|
||||||
Human* enemy = owner->room->FindEnemy((Human*)owner);
|
Human* enemy = locked_enemy_ ? locked_enemy_ : owner->room->FindEnemy(HumMaster());
|
||||||
if (enemy &&
|
if (enemy &&
|
||||||
!enemy->HasBuffEffect(kBET_Invincible) &&
|
!enemy->HasBuffEffect(kBET_Invincible) &&
|
||||||
!enemy->HasBuffEffect(kBET_Hide) &&
|
!enemy->HasBuffEffect(kBET_Hide) &&
|
||||||
!enemy->HasBuffEffect(kBET_InGrass)
|
!enemy->HasBuffEffect(kBET_InGrass)
|
||||||
) {
|
) {
|
||||||
Human* sender = (Human*)owner;
|
if (HumMaster()->CanUseSkill() &&
|
||||||
if (sender->CanUseSkill()) {
|
HumMaster()->pos.Distance(enemy->pos) < HumMaster()->tank_meta_->i->atk_range()) {
|
||||||
UseSkill(enemy);
|
UseSkill(enemy);
|
||||||
} else {
|
} else {
|
||||||
Shot(enemy);
|
Shot(enemy);
|
||||||
@ -170,47 +202,61 @@ void AndroidAI::DoAttack()
|
|||||||
|
|
||||||
void AndroidAI::Shot(Human* enemy)
|
void AndroidAI::Shot(Human* enemy)
|
||||||
{
|
{
|
||||||
Human* sender = (Human*)owner;
|
if (enemy->HasBuffEffect(kBET_Hide) ||
|
||||||
a8::Vec2 shot_dir = enemy->pos - sender->pos;
|
enemy->HasBuffEffect(kBET_Invincible) ||
|
||||||
|
enemy->dead
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (((HumMaster()->room->frameno - HumMaster()->last_shot_frameno_) * (1000 / kSERVER_FRAME_RATE)) >=
|
||||||
|
HumMaster()->curr_weapon->meta->i->fire_rate()
|
||||||
|
) {
|
||||||
|
a8::Vec2 shot_dir = enemy->pos - HumMaster()->pos;
|
||||||
if (std::abs(shot_dir.x) > FLT_EPSILON ||
|
if (std::abs(shot_dir.x) > FLT_EPSILON ||
|
||||||
std::abs(shot_dir.y) > FLT_EPSILON) {
|
std::abs(shot_dir.y) > FLT_EPSILON) {
|
||||||
shot_dir.Normalize();
|
shot_dir.Normalize();
|
||||||
shot_dir.Rotate((rand() % 10) / 180.0f);
|
shot_dir.Rotate((rand() % 10) / 180.0f);
|
||||||
sender->attack_dir = shot_dir;
|
HumMaster()->attack_dir = shot_dir;
|
||||||
if (sender->curr_weapon->meta->NeedTrace()) {
|
if (HumMaster()->curr_weapon->meta->NeedTrace()) {
|
||||||
sender->shot_target_id = enemy->entity_uniid;
|
HumMaster()->shot_target_id = enemy->entity_uniid;
|
||||||
} else {
|
} else {
|
||||||
sender->shot_target_id = 0;
|
HumMaster()->shot_target_id = 0;
|
||||||
|
}
|
||||||
|
HumMaster()->Shot();
|
||||||
}
|
}
|
||||||
sender->Shot();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidAI::UseSkill(Human* enemy)
|
void AndroidAI::UseSkill(Human* enemy)
|
||||||
{
|
{
|
||||||
Human* sender = (Human*)owner;
|
if (!HumMaster()->CurrentSkillMeta()) {
|
||||||
if (!sender->CurrentSkillMeta()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (sender->CurrentSkillMeta()->i->skill_target() == kST_Self) {
|
if (enemy->HasBuffEffect(kBET_Hide) ||
|
||||||
sender->curr_skill_phase = 0;
|
enemy->HasBuffEffect(kBET_Invincible) ||
|
||||||
sender->skill_target_id = sender->entity_uniid;
|
enemy->dead) {
|
||||||
sender->skill_dir = a8::Vec2();
|
return;
|
||||||
sender->skill_target_pos = sender->pos;
|
}
|
||||||
sender->skill_param1 = 0;
|
|
||||||
sender->playing_skill = false;
|
if (HumMaster()->CurrentSkillMeta()->i->skill_target() == kST_Self) {
|
||||||
sender->DoSkill();
|
HumMaster()->curr_skill_phase = 0;
|
||||||
|
HumMaster()->skill_target_id = HumMaster()->entity_uniid;
|
||||||
|
HumMaster()->skill_dir = a8::Vec2();
|
||||||
|
HumMaster()->skill_target_pos = HumMaster()->pos;
|
||||||
|
HumMaster()->skill_param1 = 0;
|
||||||
|
HumMaster()->playing_skill = false;
|
||||||
|
HumMaster()->DoSkill();
|
||||||
} else {
|
} else {
|
||||||
a8::Vec2 shot_dir = enemy->pos - sender->pos;
|
a8::Vec2 shot_dir = enemy->pos - HumMaster()->pos;
|
||||||
if (std::abs(shot_dir.x) > FLT_EPSILON ||
|
if (std::abs(shot_dir.x) > FLT_EPSILON ||
|
||||||
std::abs(shot_dir.y) > FLT_EPSILON) {
|
std::abs(shot_dir.y) > FLT_EPSILON) {
|
||||||
sender->curr_skill_phase = 0;
|
HumMaster()->curr_skill_phase = 0;
|
||||||
sender->skill_target_id = enemy->entity_uniid;
|
HumMaster()->skill_target_id = enemy->entity_uniid;
|
||||||
sender->skill_dir = shot_dir;
|
HumMaster()->skill_dir = shot_dir;
|
||||||
sender->skill_target_pos = enemy->pos;
|
HumMaster()->skill_target_pos = enemy->pos;
|
||||||
sender->skill_param1 = 0;
|
HumMaster()->skill_param1 = 0;
|
||||||
sender->playing_skill = false;
|
HumMaster()->playing_skill = false;
|
||||||
sender->DoSkill();
|
HumMaster()->DoSkill();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "roommgr.h"
|
#include "roommgr.h"
|
||||||
#include "android.h"
|
#include "android.h"
|
||||||
|
#include "android.ai.h"
|
||||||
#include "gamelog.h"
|
#include "gamelog.h"
|
||||||
#include "typeconvert.h"
|
#include "typeconvert.h"
|
||||||
#include "obstacle.h"
|
#include "obstacle.h"
|
||||||
@ -501,6 +502,12 @@ void Human::DecHP(float dec_hp, int killer_id, const std::string& killer_name, i
|
|||||||
last_attacker_name = killer_name;
|
last_attacker_name = killer_name;
|
||||||
last_attacker_weapon_id = weapon_id;
|
last_attacker_weapon_id = weapon_id;
|
||||||
last_attacked_frameno = room->frameno;
|
last_attacked_frameno = room->frameno;
|
||||||
|
if (entity_subtype == kEST_Android) {
|
||||||
|
Android* android = (Android*)this;
|
||||||
|
if (android->ai) {
|
||||||
|
android->ai->LockEnemy(last_attacker_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
SyncAroundPlayers();
|
SyncAroundPlayers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,4 +264,5 @@ private:
|
|||||||
|
|
||||||
friend class FrameMaker;
|
friend class FrameMaker;
|
||||||
friend class FrameEvent;
|
friend class FrameEvent;
|
||||||
|
friend class AndroidAI;
|
||||||
};
|
};
|
||||||
|
@ -123,6 +123,14 @@ public:
|
|||||||
MetaMgr::Instance()->grass_invisible_time = MetaMgr::Instance()->GetSysParamAsInt("grass_invisible_time", 0.5f);
|
MetaMgr::Instance()->grass_invisible_time = MetaMgr::Instance()->GetSysParamAsInt("grass_invisible_time", 0.5f);
|
||||||
MetaMgr::Instance()->grass_show_time = MetaMgr::Instance()->GetSysParamAsInt("grass_show_time", 0.5f);
|
MetaMgr::Instance()->grass_show_time = MetaMgr::Instance()->GetSysParamAsInt("grass_show_time", 0.5f);
|
||||||
MetaMgr::Instance()->grass_invisible_time2 = MetaMgr::Instance()->GetSysParamAsInt("grass_invisible_time2", 2.0f);
|
MetaMgr::Instance()->grass_invisible_time2 = MetaMgr::Instance()->GetSysParamAsInt("grass_invisible_time2", 2.0f);
|
||||||
|
MetaMgr::Instance()->robot_pursuit_range = MetaMgr::Instance()->
|
||||||
|
GetSysParamAsInt("robot_pursuit_range",
|
||||||
|
MetaMgr::Instance()->robot_pursuit_range
|
||||||
|
);
|
||||||
|
MetaMgr::Instance()->robot_attack_range = MetaMgr::Instance()->
|
||||||
|
GetSysParamAsInt("robot_attack_range",
|
||||||
|
MetaMgr::Instance()->robot_attack_range
|
||||||
|
);
|
||||||
if (MetaMgr::Instance()->K < 0.01f) {
|
if (MetaMgr::Instance()->K < 0.01f) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,8 @@ class MetaMgr : public a8::Singleton<MetaMgr>
|
|||||||
float grass_invisible_time = 0.5;
|
float grass_invisible_time = 0.5;
|
||||||
float grass_show_time = 0.5f;
|
float grass_show_time = 0.5f;
|
||||||
float grass_invisible_time2 = 2.0f;
|
float grass_invisible_time2 = 2.0f;
|
||||||
|
float robot_pursuit_range = 800.0f;
|
||||||
|
float robot_attack_range = 256.0f;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MetaDataLoader* loader_ = nullptr;
|
MetaDataLoader* loader_ = nullptr;
|
||||||
|
@ -214,7 +214,8 @@ message Tank
|
|||||||
required int32 skill_id = 4;
|
required int32 skill_id = 4;
|
||||||
required string attr_origin = 5;
|
required string attr_origin = 5;
|
||||||
required string attr_up = 6;
|
required string attr_up = 6;
|
||||||
optional int32 type = 7;
|
required int32 type = 7;
|
||||||
|
required float atk_range = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
message TankSkin
|
message TankSkin
|
||||||
|
Loading…
x
Reference in New Issue
Block a user