This commit is contained in:
aozhiwei 2019-07-22 15:28:41 +08:00
parent dab78aad55
commit e61e88653c
6 changed files with 124 additions and 59 deletions

View File

@ -19,13 +19,12 @@ AndroidAI::~AndroidAI()
void AndroidAI::Update(int delta_time)
{
Human* hum = (Human*)owner;
state_elapsed_time_ += delta_time;
if (hum->dead) {
if (HumMaster()->dead) {
return;
}
if (hum->playing_skill) {
hum->UpdateSkill();
if (HumMaster()->playing_skill) {
HumMaster()->UpdateSkill();
}
switch (state_) {
case AS_thinking:
@ -42,9 +41,22 @@ void AndroidAI::Update(int delta_time)
break;
case AS_moving:
{
bool need_chg = true;
if (state_elapsed_time_ < 1000 + rand() % 2000) {
DoMove();
} else {
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 {
HumMaster()->move_dir = locked_enemy_->pos - HumMaster()->pos;
HumMaster()->move_dir.Normalize();
DoMove();
}
need_chg = false;
}
if (need_chg) {
int rnd = rand();
if (rnd % 100 < 30) {
ChangeToState(AS_thinking);
@ -56,9 +68,20 @@ void AndroidAI::Update(int delta_time)
break;
case AS_attack:
{
bool need_chg = true;
if (state_elapsed_time_ < 1000) {
DoAttack();
} else {
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 {
DoAttack();
}
need_chg = false;
}
if (need_chg) {
int rnd = rand();
if (rnd % 100 < 30) {
ChangeToState(AS_moving);
@ -68,6 +91,8 @@ void AndroidAI::Update(int delta_time)
}
}
break;
default:
break;
}
}
@ -105,11 +130,21 @@ void AndroidAI::ChangeToState(AndroidState_e to_state)
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;
if (locked_enemy_) {
a8::Vec2 move_dir = locked_enemy_->pos - HumMaster()->pos;
if (std::abs(move_dir.x) > 0.00001f ||
std::abs(move_dir.y) > 0.00001f) {
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;
default:
@ -119,47 +154,44 @@ void AndroidAI::ChangeToState(AndroidState_e to_state)
void AndroidAI::DoMove()
{
Human* hum = (Human*)owner;
if (hum->HasBuffEffect(kBET_Vertigo) || hum->HasBuffEffect(kBET_Dcgr)) {
if (HumMaster()->HasBuffEffect(kBET_Vertigo) || HumMaster()->HasBuffEffect(kBET_Dcgr)) {
return;
}
if (owner->updated_times % 2 == 0) {
Human* hum = (Human*)owner;
int speed = std::max(1, (int)hum->GetSpeed());
int speed = std::max(1, (int)HumMaster()->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;
a8::Vec2 old_pos = HumMaster()->pos;
HumMaster()->pos = HumMaster()->pos + HumMaster()->move_dir;
if (HumMaster()->IsCollisionInMapService()) {
HumMaster()->pos = old_pos;
if (i == 0) {
hum->FindPath();
HumMaster()->FindPath();
}
break;
}
hum->room->grid_service.MoveHuman(hum);
HumMaster()->room->grid_service.MoveHuman(HumMaster());
}
hum->CheckGrass();
HumMaster()->CheckGrass();
}
}
void AndroidAI::DoAttack()
{
Human* hum = (Human*)owner;
if (hum->room->gas_data.gas_mode == kGasInactive) {
if (HumMaster()->room->gas_data.gas_mode == kGasInactive) {
return;
}
if (hum->HasBuffEffect(kBET_Vertigo) || hum->HasBuffEffect(kBET_Dcgr)) {
if (HumMaster()->HasBuffEffect(kBET_Vertigo) || HumMaster()->HasBuffEffect(kBET_Dcgr)) {
return;
}
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 &&
!enemy->HasBuffEffect(kBET_Invincible) &&
!enemy->HasBuffEffect(kBET_Hide) &&
!enemy->HasBuffEffect(kBET_InGrass)
) {
Human* sender = (Human*)owner;
if (sender->CanUseSkill()) {
if (HumMaster()->CanUseSkill() &&
HumMaster()->pos.Distance(enemy->pos) < HumMaster()->tank_meta_->i->atk_range()) {
UseSkill(enemy);
} else {
Shot(enemy);
@ -170,47 +202,61 @@ void AndroidAI::DoAttack()
void AndroidAI::Shot(Human* 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;
if (sender->curr_weapon->meta->NeedTrace()) {
sender->shot_target_id = enemy->entity_uniid;
} else {
sender->shot_target_id = 0;
if (enemy->HasBuffEffect(kBET_Hide) ||
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 ||
std::abs(shot_dir.y) > FLT_EPSILON) {
shot_dir.Normalize();
shot_dir.Rotate((rand() % 10) / 180.0f);
HumMaster()->attack_dir = shot_dir;
if (HumMaster()->curr_weapon->meta->NeedTrace()) {
HumMaster()->shot_target_id = enemy->entity_uniid;
} else {
HumMaster()->shot_target_id = 0;
}
HumMaster()->Shot();
}
sender->Shot();
}
}
void AndroidAI::UseSkill(Human* enemy)
{
Human* sender = (Human*)owner;
if (!sender->CurrentSkillMeta()) {
if (!HumMaster()->CurrentSkillMeta()) {
return;
}
if (sender->CurrentSkillMeta()->i->skill_target() == kST_Self) {
sender->curr_skill_phase = 0;
sender->skill_target_id = sender->entity_uniid;
sender->skill_dir = a8::Vec2();
sender->skill_target_pos = sender->pos;
sender->skill_param1 = 0;
sender->playing_skill = false;
sender->DoSkill();
if (enemy->HasBuffEffect(kBET_Hide) ||
enemy->HasBuffEffect(kBET_Invincible) ||
enemy->dead) {
return;
}
if (HumMaster()->CurrentSkillMeta()->i->skill_target() == kST_Self) {
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 {
a8::Vec2 shot_dir = enemy->pos - sender->pos;
a8::Vec2 shot_dir = enemy->pos - HumMaster()->pos;
if (std::abs(shot_dir.x) > FLT_EPSILON ||
std::abs(shot_dir.y) > FLT_EPSILON) {
sender->curr_skill_phase = 0;
sender->skill_target_id = enemy->entity_uniid;
sender->skill_dir = shot_dir;
sender->skill_target_pos = enemy->pos;
sender->skill_param1 = 0;
sender->playing_skill = false;
sender->DoSkill();
HumMaster()->curr_skill_phase = 0;
HumMaster()->skill_target_id = enemy->entity_uniid;
HumMaster()->skill_dir = shot_dir;
HumMaster()->skill_target_pos = enemy->pos;
HumMaster()->skill_param1 = 0;
HumMaster()->playing_skill = false;
HumMaster()->DoSkill();
}
}
}

View File

@ -17,6 +17,7 @@
#include "app.h"
#include "roommgr.h"
#include "android.h"
#include "android.ai.h"
#include "gamelog.h"
#include "typeconvert.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_weapon_id = weapon_id;
last_attacked_frameno = room->frameno;
if (entity_subtype == kEST_Android) {
Android* android = (Android*)this;
if (android->ai) {
android->ai->LockEnemy(last_attacker_id);
}
}
SyncAroundPlayers();
}

View File

@ -264,4 +264,5 @@ private:
friend class FrameMaker;
friend class FrameEvent;
friend class AndroidAI;
};

View File

@ -123,6 +123,14 @@ public:
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_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) {
abort();
}

View File

@ -54,6 +54,8 @@ class MetaMgr : public a8::Singleton<MetaMgr>
float grass_invisible_time = 0.5;
float grass_show_time = 0.5f;
float grass_invisible_time2 = 2.0f;
float robot_pursuit_range = 800.0f;
float robot_attack_range = 256.0f;
private:
MetaDataLoader* loader_ = nullptr;

View File

@ -214,7 +214,8 @@ message Tank
required int32 skill_id = 4;
required string attr_origin = 5;
required string attr_up = 6;
optional int32 type = 7;
required int32 type = 7;
required float atk_range = 8;
}
message TankSkin