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) 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();
} 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(); 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();
} 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(); 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) ||
if (std::abs(shot_dir.x) > FLT_EPSILON || enemy->dead
std::abs(shot_dir.y) > FLT_EPSILON) { ) {
shot_dir.Normalize(); return;
shot_dir.Rotate((rand() % 10) / 180.0f); }
sender->attack_dir = shot_dir; if (((HumMaster()->room->frameno - HumMaster()->last_shot_frameno_) * (1000 / kSERVER_FRAME_RATE)) >=
if (sender->curr_weapon->meta->NeedTrace()) { HumMaster()->curr_weapon->meta->i->fire_rate()
sender->shot_target_id = enemy->entity_uniid; ) {
} else { a8::Vec2 shot_dir = enemy->pos - HumMaster()->pos;
sender->shot_target_id = 0; 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) 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();
} }
} }
} }

View File

@ -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();
} }

View File

@ -264,4 +264,5 @@ private:
friend class FrameMaker; friend class FrameMaker;
friend class FrameEvent; 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_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();
} }

View File

@ -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;

View File

@ -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