diff --git a/server/gameserver/constant.h b/server/gameserver/constant.h index 14d622d..aa9ddba 100755 --- a/server/gameserver/constant.h +++ b/server/gameserver/constant.h @@ -170,6 +170,7 @@ enum BuffEffectType_e kBET_InIce = 58, //在冰里 kBET_BatchAddBuff = 60, //批量添加buff kBET_BeRecycle = 61, //待回收 + kBET_Trace = 62, //追踪玩家 kBET_End }; @@ -470,4 +471,5 @@ const int kInGrassBuffId = 7006; const int kInWaterBuffId = 7007; const int kInIceBuffId = 7008; const int kBeRecycleBuffId = 7009; +const int kTraceBuffId = 7011; const float DEFAULT_FLY_DISTANCE = 5.0f; diff --git a/server/gameserver/incubator.cc b/server/gameserver/incubator.cc index 1b1db5f..d98fdfd 100644 --- a/server/gameserver/incubator.cc +++ b/server/gameserver/incubator.cc @@ -4,6 +4,9 @@ #include "room.h" #include "human.h" +const int ALLOC_BASE_LENGTH = 500; +const int ALLOC_RAND_LENGTH = 100; + void Incubator::Init() { @@ -16,8 +19,23 @@ void Incubator::UnInit() void Incubator::AllocAndroid(Human* target, int num) { - if (num > 0) { - + int try_count = 0; + a8::Vec2 dir = a8::Vec2::UP; + while (num > 0 && try_count < 20 && !hold_humans_.empty()) { + dir.Rotate(a8::RandAngle()); + int rand_len = rand() % ALLOC_RAND_LENGTH; + Human* hum = hold_humans_[0]; + a8::Vec2 old_pos = hum->GetPos(); + hum->SetPos(target->GetPos() + dir + ALLOC_BASE_LENGTH + rand_len); + if (!hum->CollisonDetection() && CanSet(hum, target)) { + hum->SetPos(old_pos); + } else { + room->EnableHuman(hum); + hum->MustBeAddBuff(hum, kTraceBuffId); + hold_humans_.erase(hold_humans_.begin()); + --num; + } + ++try_count; } } @@ -48,7 +66,27 @@ void Incubator::RecycleAndroid(Human* hum) } if (distance > 1450) { hum->RemoveBuffByEffectId(kBET_BeRecycle); - hold_humans_.insert(hum); + hold_humans_.push_back(hum); return; } } + +bool Incubator::CanSet(Human* hum, Human* exclude_hum) +{ + Human* target = hum; + bool can_set = true; + room->TouchAlivePlayers + ( + a8::XParams(), + [target, exclude_hum, &can_set] (Human* hum, a8::XParams& param) -> bool + { + if (hum != exclude_hum) { + if (target->GetPos().ManhattanDistance(hum->GetPos()) < 100) { + can_set = false; + return false; + } + } + return true; + }); + return can_set; +} diff --git a/server/gameserver/incubator.h b/server/gameserver/incubator.h index ee8c875..165cf58 100644 --- a/server/gameserver/incubator.h +++ b/server/gameserver/incubator.h @@ -13,7 +13,8 @@ class Incubator void RecycleAndroid(Human* hum); private: + bool CanSet(Human* hum, Human* exclude_hum); private: - std::set hold_humans_; + std::vector hold_humans_; };