添加ai
This commit is contained in:
parent
dab78aad55
commit
e61e88653c
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -264,4 +264,5 @@ private:
|
||||
|
||||
friend class FrameMaker;
|
||||
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_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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user