merge incubator

This commit is contained in:
aozhiwei 2021-04-19 14:09:23 +08:00
commit 381d4f46f1
26 changed files with 678 additions and 27 deletions

View File

@ -429,6 +429,9 @@ void AndroidNewAI::UpdateNewAI()
abort();
}
}
if (hum->playing_skill) {
hum->UpdateSkill();
}
++node_.exec_frame_num;
hum->shot_hold = false;
switch (node_.main_state) {

View File

@ -6,6 +6,7 @@
#include "room.h"
#include "collider.h"
#include "skill.h"
#include "incubator.h"
int Buff::GetLeftTime()
{
@ -145,6 +146,24 @@ void Buff::ProcSummonHero(Creature* caster)
}
}
void Buff::ProcBeRecycle(Creature* caster)
{
owner->room->xtimer.AddRepeatTimerAndAttach
(
SERVER_FRAME_RATE * 2,
a8::XParams()
.SetSender(this),
[] (const a8::XParams& param)
{
Buff* buff = (Buff*)param.sender.GetUserData();
if (buff->owner->IsHuman()) {
buff->owner->room->GetIncubator()->RecycleAndroid((Human*)buff->owner);
}
},
&xtimer_attacher.timer_list_
);
}
bool Buff::NeedSync(Human* hum)
{
return !meta->i->only_server() || !(meta->i->only_self() && owner == hum);

View File

@ -36,6 +36,7 @@ class Buff
void ProcIntervalAddBuff(Creature* caster);
void ProcBatchAddBuff(Creature* caster);
void ProcSummonHero(Creature* caster);
void ProcBeRecycle(Creature* caster);
private:
void InternalTimerAddBuff(Creature* caster);

View File

@ -75,6 +75,11 @@ void Bullet::OnHit(std::set<Entity*>& objects)
#if 0
sender->stats.damage_amount_out += finaly_dmg;
#endif
#ifdef DEBUG
if (App::Instance()->HasFlag(1) && hum->IsPlayer()) {
continue;
}
#endif
hum->DecHP(finaly_dmg, sender.Get()->GetEntityUniId(), sender.Get()->GetName(), gun_meta->i->id());
#ifdef DEBUG
sender.Get()->SendDebugMsg(a8::Format("bullet weapon_id:%d atk:%f",
@ -417,6 +422,18 @@ void Bullet::ProcPosionGasBomb(int delay_time)
void Bullet::ProcMolotorCocktailBomb(int delay_time)
{
if (sender.Get()) {
#if 1
a8::Vec2 old_buff_vec2_param1 = sender.Get()->buff_vec2_param1;
sender.Get()->buff_vec2_param1 = GetPos();
MetaData::Buff * buff_meta = MetaMgr::Instance()->GetBuff(gun_meta->i->buffid());
if (buff_meta) {
sender.Get()->AddBuff(sender.Get(),
buff_meta,
1
);
}
sender.Get()->buff_vec2_param1 = old_buff_vec2_param1;
#else
MolotorCocktailMiTask* task = new MolotorCocktailMiTask();
task->room = room;
task->sender.Attach(sender.Get());
@ -442,5 +459,6 @@ void Bullet::ProcMolotorCocktailBomb(int delay_time)
},
&room->timer_attacher.timer_list_
);
#endif
}
}

View File

@ -9,6 +9,8 @@ const int kRecoilBuffId = 7005;
const int kInGrassBuffId = 7006;
const int kInWaterBuffId = 7007;
const int kInIceBuffId = 7008;
const int kBeRecycleBuffId = 7009;
const int kTraceBuffId = 7011;
enum BuffEffectType_e
{
@ -59,6 +61,8 @@ enum BuffEffectType_e
kBET_InWater = 57, //在水里
kBET_InIce = 58, //在冰里
kBET_BatchAddBuff = 60, //批量添加buff
kBET_BeRecycle = 61, //待回收
kBET_Trace = 62, //追踪玩家
kBET_End
};

View File

@ -146,9 +146,11 @@ void Creature::AddBuff(Creature* caster,
int skill_lv,
MetaData::Skill* buff_skill_meta)
{
#if 0
if (GetBuffById(buff_meta->i->buff_id())) {
return;
}
#endif
if (IsImmuneBuffEffect(buff_meta->i->buff_effect())) {
return;
}
@ -484,6 +486,12 @@ bool Creature::CanUseSkill(int skill_id)
if (!skill) {
return false;
}
if (dead) {
return false;
}
if (playing_skill) {
return false;
}
return skill->GetCurrTimes() > 0;
}
@ -513,7 +521,10 @@ void Creature::DoSkill(int skill_id,
std::set<Creature*> target_list;
SelectSkillTargets(CurrentSkill(), GetPos(), target_list);
TriggerBuff(CurrentSkill(), target_list, kBTT_UseSkill);
UpdateSkill();
if (!CurrentSkill()->meta->phases.empty() &&
CurrentSkill()->meta->phases[0].time_offset <= 0) {
UpdateSkill();
}
} else {
Entity* entity = room->GetEntityByUniId(skill_target_id_);
if (entity && entity->IsEntityType(ET_Player)) {
@ -564,7 +575,7 @@ void Creature::ResetSkill()
void Creature::UpdateSkill()
{
if (CurrentSkill()) {
if (CurrentSkill() && !dead) {
if (curr_skill_phase < CurrentSkill()->meta->phases.size()) {
MetaData::SkillPhase* phase = &CurrentSkill()->meta->phases[curr_skill_phase];
if (phase->time_offset >= CurrentSkill()->GetPassedTime()) {
@ -574,6 +585,8 @@ void Creature::UpdateSkill()
} else {
playing_skill = false;
}
} else {
playing_skill = false;
}
}
@ -848,9 +861,11 @@ void Creature::ProcBuffEffect(Creature* caster, Buff* buff)
break;
case kBET_SummonObstacle:
{
a8::Vec2 target_pos = caster->GetPos() + caster->skill_dir_ * caster->skill_distance_;
target_pos = buff_vec2_param1;
SummonObstacle(buff->meta->param1, target_pos);
if (!dead) {
a8::Vec2 target_pos = caster->GetPos() + caster->skill_dir_ * caster->skill_distance_;
target_pos = buff_vec2_param1;
SummonObstacle(buff->meta->param1, target_pos);
}
}
break;
case kBET_Sprint:
@ -875,6 +890,11 @@ void Creature::ProcBuffEffect(Creature* caster, Buff* buff)
buff->ProcBatchAddBuff(caster);
}
break;
case kBET_BeRecycle:
{
buff->ProcBeRecycle(caster);
}
break;
default:
{
}
@ -1149,7 +1169,14 @@ void Creature::Shot(a8::Vec2& target_dir, bool& shot_ok, float fly_distance)
int weapon_idx = GetCurrWeapon()->weapon_idx;
*GetCurrWeapon() = Weapon();
GetCurrWeapon()->weapon_idx = weapon_idx;
SetCurrWeapon(ChooseNextWeapon(slot_id, SPEC1_IS_BEGIN, SPEC1_IS_END));
Weapon* next_weapon = ChooseNextWeapon(slot_id, SPEC1_IS_BEGIN, SPEC1_IS_END);
if (!next_weapon) {
next_weapon = ChooseNextWeapon(SPEC2_IS_BEGIN, SPEC2_IS_BEGIN, SPEC2_IS_END);
}
if (!next_weapon) {
next_weapon = AutoChgWeapon();
}
SetCurrWeapon(next_weapon);
AutoLoadingBullet();
}
}
@ -1170,7 +1197,14 @@ void Creature::Shot(a8::Vec2& target_dir, bool& shot_ok, float fly_distance)
int weapon_idx = GetCurrWeapon()->weapon_idx;
*GetCurrWeapon() = Weapon();
GetCurrWeapon()->weapon_idx = weapon_idx;
SetCurrWeapon(ChooseNextWeapon(slot_id, SPEC2_IS_BEGIN, SPEC2_IS_END));
Weapon* next_weapon = ChooseNextWeapon(slot_id, SPEC2_IS_BEGIN, SPEC2_IS_END);
if (!next_weapon) {
next_weapon = ChooseNextWeapon(SPEC1_IS_BEGIN, SPEC1_IS_BEGIN, SPEC1_IS_END);
}
if (!next_weapon) {
next_weapon = AutoChgWeapon();
}
SetCurrWeapon(next_weapon);
AutoLoadingBullet();
}
}
@ -1190,6 +1224,7 @@ void Creature::Shot(a8::Vec2& target_dir, bool& shot_ok, float fly_distance)
last_shot_frameno_ = room->GetFrameNo();
if (!need_sync_active_player && IsPlayer()) {
room->frame_event.AddBulletNumChg((Human*)this);
room->frame_event.AddWeaponAmmoChg((Human*)this);
}
shot_ok = true;
}
@ -1453,7 +1488,7 @@ Weapon* Creature::ChooseNextWeapon(int curr_weapon_slot_id, int begin_slot_id, i
break;
}
}
return next_weapon ? next_weapon : AutoChgWeapon();
return next_weapon;
}
void Creature::SetCurrWeapon(Weapon* weapon)

View File

@ -45,6 +45,7 @@ class Creature : public MoveableEntity
std::function<bool ()> on_move_collision;
bool poisoning = false;
long long poisoning_time = 0;
bool playing_skill = false;
Weapon car_weapon;
a8::Vec2 buff_vec2_param1;
@ -140,6 +141,7 @@ class Creature : public MoveableEntity
Weapon* GetCurrWeapon() { return curr_weapon_; };
void SetCurrWeapon(Weapon* weapon);
void ResetAllSkillCd();
void UpdateSkill();
private:
@ -148,7 +150,6 @@ private:
virtual void DoSkillPreProc(int skill_id, int target_id, const a8::Vec2& target_pos);
virtual void DoSkillPostProc(bool used, int skill_id, int target_id, const a8::Vec2& target_pos);
void UpdateSkill();
void ProcSkillPhase(MetaData::SkillPhase* phase);
void ProcBuffEffect(Creature* caster, Buff* buff);
void TriggerOneObjectBuff(Skill* skill, Creature* target, BuffTriggerType_e trigger_type);
@ -177,7 +178,6 @@ private:
a8::Vec2 skill_dir_;
float skill_param1 = 0;
bool playing_skill = false;
size_t curr_skill_phase = 0;
Skill* curr_skill_ = nullptr;
int skill_target_id_ = 0;

View File

@ -6,6 +6,7 @@
#include "typeconvert.h"
#include "metamgr.h"
#include "car.h"
#include "app.h"
cs::SMUpdate* FrameMaker::MakeUpdateMsg(Human* hum)
{
@ -31,6 +32,16 @@ cs::SMUpdate* FrameMaker::MakeUpdateMsg(Human* hum)
if (hum->IsPlayer()) {
itr->FillMFObjectFull(room, (Human*)hum, msg->add_full_objects());
}
#ifdef DEBUG
if (App::Instance()->HasFlag(2) && itr->GetEntityType() == ET_Player) {
room->BroadcastDebugMsg(a8::Format("投放 %d pos:%d,%d 出现",
{
itr->GetEntityUniId(),
itr->GetPos().x,
itr->GetPos().y,
}));
}
#endif
}
for (auto& itr : hum->part_objects) {
Entity* entity = itr;
@ -52,9 +63,25 @@ cs::SMUpdate* FrameMaker::MakeUpdateMsg(Human* hum)
}
for (auto& itr : hum->del_objects) {
msg->add_del_objids(itr);
#ifdef DEBUG
if (App::Instance()->HasFlag(2)) {
room->BroadcastDebugMsg(a8::Format("投放 删除对象%d",
{
itr
}));
}
#endif
}
for (auto& itr : hum->out_objects) {
msg->add_out_objids(itr);
#ifdef DEBUG
if (App::Instance()->HasFlag(2)) {
room->BroadcastDebugMsg(a8::Format("投放 移除视野对象%d",
{
itr
}));
}
#endif
}
for (size_t idx : hum->shots_) {
if (idx < room->frame_event.shots_.size()) {

View File

@ -87,6 +87,7 @@ void HandlerMgr::RegisterNetMsgHandlers()
RegisterNetMsgHandler(&ggmsghandler, &RoomMgr::_CMReconnect);
RegisterNetMsgHandler(&ggmsghandler, &Player::_CMMove);
RegisterNetMsgHandler(&ggmsghandler, &Player::_CMExecCommand);
RegisterNetMsgHandler(&ggmsghandler, &Player::_CMEmote);
RegisterNetMsgHandler(&ggmsghandler, &Player::_CMVoice);
RegisterNetMsgHandler(&ggmsghandler, &Player::_CMGameOver);

View File

@ -27,6 +27,7 @@
#include "aicomponent.h"
#include "jsondatamgr.h"
#include "skill.h"
#include "incubator.h"
#include "framework/cpp/utils.h"
#include "framework/cpp/httpclientpool.h"
@ -942,6 +943,12 @@ void Human::DecHP(float dec_hp, int killer_id, const std::string& killer_name, i
&xtimer_attacher.timer_list_
);
SyncAroundPlayers(__FILE__, __LINE__, __func__);
if (GetNearbyTeammateNum(MetaMgr::Instance()->refresh_ai_downed_nearby_range) <
MetaMgr::Instance()->refresh_ai_downed_nearby_teammate_num) {
#if 0
room->GetIncubator()->AllocAndroid(this, 1 + rand() % 2);
#endif
}
} else {
BeKill(killer_id, killer_name, weapon_id);
}
@ -976,6 +983,11 @@ int Human::GetPartObjectsCount()
return part_objects.size();
}
bool Human::InNewObjects(Entity* target)
{
return new_objects.find(target) != new_objects.end();
}
bool Human::InPartObjects(Entity* target)
{
return part_objects.find(target) != part_objects.end();
@ -1047,6 +1059,21 @@ bool Human::HasNoDownedTeammate()
return false;
}
int Human::GetNearbyTeammateNum(float range)
{
int num = 0;
if (team_members) {
for (auto& hum : *team_members) {
if (hum != this && !hum->dead && !hum->downed) {
if (hum->GetPos().Distance(GetPos()) <= range) {
++num;
}
}
}
}
return num;
}
bool Human::CanUseSkill(int skill_id)
{
return !downed && Creature::CanUseSkill(skill_id);
@ -1770,12 +1797,14 @@ void Human::_UpdateSpecMove()
void Human::_UpdateMove(int speed)
{
do {
int distance = std::min(5, speed);
_InternalUpdateMove(distance);
speed -= distance;
} while (speed > 0);
CheckSpecObject();
if (!HasBuffEffect(kBET_Vertigo)) {
do {
int distance = std::min(5, speed);
_InternalUpdateMove(distance);
speed -= distance;
} while (speed > 0);
CheckSpecObject();
}
}
void Human::ChangeToRace(RaceType_e race, int level)
@ -2638,7 +2667,9 @@ Skin* Human::GetSkinByIdx(int idx)
void Human::AddBuffPostProc(Creature* caster, Buff* buff)
{
room->frame_event.AddBuff(this, buff);
if (!buff->meta->i->only_server()) {
room->frame_event.AddBuff(this, buff);
}
}
int Human::GetItemNum(int item_id)
@ -2712,6 +2743,22 @@ void Human::DropItems(Obstacle* obstacle)
} else {
++normal_drop_times_;
}
{
if (behavior.curr_start_destory_box_frameno <= 0 ||
behavior.curr_destory_box_times >= MetaMgr::Instance()->refresh_ai_destory_box_times ||
(room->GetFrameNo() - behavior.curr_start_destory_box_frameno >
MetaMgr::Instance()->refresh_ai_destory_box_time * SERVER_FRAME_RATE)){
behavior.curr_start_destory_box_frameno = room->GetFrameNo();
behavior.curr_destory_box_times = 0;
}
behavior.curr_destory_box_times++;
behavior.total_destory_box_times++;
if (behavior.curr_destory_box_times >= MetaMgr::Instance()->refresh_ai_destory_box_times) {
#if 0
room->GetIncubator()->AllocAndroid(this, 1 + rand() % 2);
#endif
}
}
#ifdef DEBUG
#if 0
a8::UdpLog::Instance()->Debug("DropItems normal:%d box:%d drop_id:%d is_treasure_box:%d",
@ -3198,7 +3245,9 @@ void Human::OnBuffRemove(const Buff& buff)
default:
break;
}
room->frame_event.RemoveBuff(this, buff.meta->i->buff_id());
if (!buff.meta->i->only_server()) {
room->frame_event.RemoveBuff(this, buff.meta->i->buff_id());
}
}
void Human::OnLand()
@ -3206,6 +3255,27 @@ void Human::OnLand()
//着陆
RemoveBuffByEffectId(kBET_Jump);
RemoveBuffByEffectId(kBET_ThroughWall);
if (IsAndroid() && team_uuid.empty()) {
MustBeAddBuff(this, kBeRecycleBuffId);
}
if (IsPlayer()) {
refresh_view_timer_ = room->xtimer.AddRepeatTimerAndAttach
(
SERVER_FRAME_RATE * MetaMgr::Instance()->refresh_view_time,
a8::XParams()
.SetSender(this),
[] (const a8::XParams& param)
{
Human* hum = (Human*)param.sender.GetUserData();
hum->UpdateViewObjects();
},
&xtimer_attacher.timer_list_,
[] (const a8::XParams& param)
{
Human* hum = (Human*)param.sender.GetUserData();
hum->refresh_view_timer_ = nullptr;
});
}
if (IsCollisionInMapService()) {
a8::Vec2 old_pos = GetPos();
std::vector<a8::Vec2> dirs;
@ -3396,3 +3466,122 @@ void Human::GetHitAabbBox(AabbCollider& aabb_box)
aabb_box._max.y = GetHitRadius();
}
}
void Human::UpdateViewObjects()
{
if (view_objects_.size() >= 2) {
std::vector<Human*> deleted_humans;
for (Human* hum : view_objects_) {
if (hum->dead ||
hum->GetPos().ManhattanDistance(GetPos()) > MetaMgr::Instance()->view_objects_out_distance) {
deleted_humans.push_back(hum);
}
}
for (Human* hum : deleted_humans) {
view_objects_.erase(hum);
}
}
if (view_objects_.size() < 2) {
TouchAllLayerHumanList
(
[this] (Human* hum, bool& stop)
{
if (hum->IsAndroid() && !hum->dead && view_objects_.find(hum) == view_objects_.end()) {
if (hum->GetPos().ManhattanDistance(GetPos()) <
MetaMgr::Instance()->view_objects_in_distance) {
view_objects_.insert(hum);
}
if (view_objects_.size() >= 2) {
stop = true;
return;
}
}
});
}
if (view_objects_.size() < 2) {
room->GetIncubator()->AllocAndroid(this, 1 + rand() % 2);
if (refresh_view_timer_) {
room->xtimer.ModifyTimer(refresh_view_timer_,
SERVER_FRAME_RATE * (MetaMgr::Instance()->refresh_view_time + (rand() % 3))
);
}
}
}
void Human::GMAddItem(int item_id, int item_num)
{
MetaData::Equip* item_meta = MetaMgr::Instance()->GetEquip(item_id);
if (!item_meta) {
return;
}
if (item_meta->i->_inventory_slot() >= 0 &&
item_meta->i->_inventory_slot() < IS_END) {
if (GetInventory(item_meta->i->_inventory_slot()) >=
GetVolume(item_meta->i->_inventory_slot())
) {
/*
cs::SMPickup notifymsg;
notifymsg.set_error_code(1);
SendNotifyMsg(notifymsg);
*/
return;
}
int add_num = GetVolume(item_meta->i->_inventory_slot()) -
GetInventory(item_meta->i->_inventory_slot());
add_num = std::min(item_num, add_num);
AddInventory(item_meta->i->_inventory_slot(), add_num);
switch (item_meta->i->_inventory_slot()) {
case IS_FRAG:
case IS_SMOKE:
{
Weapon* weapon = &weapons[SPEC1_SLOT_BEGIN +
(item_meta->i->_inventory_slot() - SPEC1_IS_BEGIN)
];
weapon->weapon_id = item_id;
weapon->weapon_lv = 1;
weapon->ammo += item_num;
weapon->meta = item_meta;
weapon->Recalc();
DecInventory(item_meta->i->_inventory_slot(), add_num);
}
break;
case IS_1XSCOPE:
case IS_2XSCOPE:
case IS_4XSCOPE:
case IS_8XSCOPE:
case IS_15XSCOPE:
{
if (item_meta->i->_inventory_slot() - IS_1XSCOPE > curr_scope_idx) {
curr_scope_idx = item_meta->i->_inventory_slot() - IS_1XSCOPE;
}
}
break;
case IS_POSION_GAS_BOMB:
case IS_MOLOTOR_COCKTAIL:
case IS_TRAP:
case IS_MINE:
{
Weapon* weapon = &weapons[SPEC2_SLOT_BEGIN +
(item_meta->i->_inventory_slot() - SPEC2_IS_BEGIN)
];
weapon->weapon_id = item_id;
weapon->weapon_lv = 1;
weapon->ammo += item_num;
weapon->meta = item_meta;
weapon->Recalc();
DecInventory(item_meta->i->_inventory_slot(), add_num);
}
break;
default:
{
#if 0
abort();
#endif
}
break;
}
}
need_sync_active_player = true;
SyncAroundPlayers(__FILE__, __LINE__, __func__);
}

View File

@ -52,6 +52,7 @@ class Human : public Creature
int today_enter_times = 0;
int account_registertime = 0;
int channel = 0;
HumanBehavior behavior;
MetaData::Player* meta = nullptr;
MetaData::Equip* helmet_meta = nullptr;
MetaData::Equip* chest_meta = nullptr;
@ -163,6 +164,7 @@ class Human : public Creature
void AddToNewObjects(Entity* entity);
void AddToPartObjects(Entity* entity);
void RemovePartObjects(Entity* entity);
bool InNewObjects(Entity* target);
bool InPartObjects(Entity* target);
int GetPartObjectsCount();
void RemoveObjects(Entity* entity);
@ -170,6 +172,7 @@ class Human : public Creature
void RemoveOutObjects(Entity* entity);
bool HasLiveTeammate();
bool HasNoDownedTeammate();
int GetNearbyTeammateNum(float range);
void DoJump();
virtual bool CanUseSkill(int skill_id) override;
virtual Skill* SelectSkill();
@ -241,6 +244,8 @@ class Human : public Creature
void SetSeat(int seat) { seat_ = seat; }
void DeadDrop();
virtual std::string GetName() override { return name;};
void UpdateViewObjects();
void GMAddItem(int item_id, int item_num);
protected:
void _InternalUpdateMove(float speed);
@ -328,6 +333,8 @@ protected:
bool follow_synced_active_player = false;
Car* car_ = nullptr;
int seat_ = 0;
std::set<Human*> view_objects_;
xtimer_list* refresh_view_timer_ = nullptr;
private:
CircleCollider* self_collider_ = nullptr;

View File

@ -0,0 +1,186 @@
#include "precompile.h"
#include "incubator.h"
#include "room.h"
#include "human.h"
#include "metamgr.h"
void Incubator::Init()
{
xtimer_attacher_.xtimer = &room->xtimer;
room->xtimer.AddRepeatTimerAndAttach
(
SERVER_FRAME_RATE * (2 + rand() % 3),
a8::XParams()
.SetSender(this),
[] (const a8::XParams& param)
{
Incubator* incubator = (Incubator*)param.sender.GetUserData();
incubator->AutoAllocAndroid();
},
&xtimer_attacher_.timer_list_);
}
void Incubator::UnInit()
{
}
void Incubator::AllocAndroid(Human* target, int num)
{
if (room->xtimer.GetRunningTimer() == nullptr) {
abort();
}
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() % MetaMgr::Instance()->incubator_rand_length;
Human* hum = hold_humans_[0];
a8::Vec2 old_pos = hum->GetPos();
hum->SetPos(target->GetPos() + dir * (MetaMgr::Instance()->incubator_base_length + rand_len));
if (hum->CollisonDetection() || !CanSet(hum, target)) {
hum->SetPos(old_pos);
} else {
room->EnableHuman(hum);
#ifdef DEBUG
if (!target->InNewObjects(hum)) {
abort();
}
if (hum->dead) {
abort();
}
#endif
hum->MustBeAddBuff(hum, kTraceBuffId);
hold_humans_.erase(hold_humans_.begin());
--num;
#ifdef DEBUG
room->BroadcastDebugMsg(a8::Format("投放机器人 %d:%s pos:%d,%d pos1:%d,%d %d num:%d",
{hum->GetEntityUniId(),
hum->name,
hum->GetPos().x,
hum->GetPos().y,
target->GetPos().x,
target->GetPos().y,
hum->GetPos().Distance(target->GetPos()),
hold_humans_.size()}));
#endif
}
++try_count;
}
#ifdef DEBUG
if (num > 0) {
room->BroadcastDebugMsg(a8::Format("投放机器人 分配失败 %d", {hold_humans_.size()}));
}
#endif
}
void Incubator::RecycleAndroid(Human* hum)
{
Human* nearest_hum = nullptr;
Human* target = hum;
float distance = 10000000;
room->TouchAlivePlayers
(
a8::XParams(),
[&nearest_hum, target, &distance] (Human* hum, a8::XParams& param) -> bool
{
float tmp_distance = hum->GetPos().ManhattanDistance(target->GetPos());
if (tmp_distance < distance) {
nearest_hum = hum;
distance = tmp_distance;
}
return true;
});
if (hum->dead) {
#ifdef DEBUG
room->BroadcastDebugMsg(a8::Format("回收机器人 %d:%s 角色已死亡",
{hum->GetEntityUniId(),
hum->name}));
#endif
hum->RemoveBuffByEffectId(kBET_BeRecycle);
return;
}
if (distance < MetaMgr::Instance()->incubator_canset_distance) {
#ifdef DEBUG
room->BroadcastDebugMsg(a8::Format("回收机器人 %d:%s 距离太近",
{hum->GetEntityUniId(),
hum->name}));
#endif
hum->RemoveBuffByEffectId(kBET_BeRecycle);
return;
}
if (distance > MetaMgr::Instance()->incubator_canset_distance + 100) {
hum->RemoveBuffByEffectId(kBET_BeRecycle);
hold_humans_.push_back(hum);
room->DisableHuman(hum);
#ifdef DEBUG
room->BroadcastDebugMsg(a8::Format("回收机器人 %d:%s:%d 添加到回收列表",
{hum->GetEntityUniId(),
hum->name,
hold_humans_.size()
}));
#endif
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()) <
MetaMgr::Instance()->incubator_canset_distance) {
can_set = false;
return false;
}
}
return true;
});
return can_set;
}
void Incubator::AutoAllocAndroid()
{
switch (room->GetGasData().gas_mode) {
case GasWaiting:
case GasMoving:
{
if (!hold_humans_.empty()){
Human* hum = hold_humans_[0];
if (room->GetGasData().gas_mode == GasWaiting &&
hold_humans_.size() > 1 &&
((rand() % 100) > 40)) {
Human* killer = nullptr;
if (hold_humans_.size() == 2) {
killer = hold_humans_[1];
} else {
killer = hold_humans_[1 + (rand() % (hold_humans_.size() - 1))];
}
hum->BeKill(killer->GetEntityUniId(),
killer->name,
killer->GetCurrWeapon()->weapon_id);
} else if (room->GetGasData().gas_count > 1) {
hum->BeKill(VP_SafeArea,
TEXT("battle_server_killer_gas", "毒圈"),
VW_SafeArea);
} else {
return;
}
hold_humans_.erase(hold_humans_.begin());
room->xtimer.ModifyTimer(room->xtimer.GetRunningTimer(), SERVER_FRAME_RATE * (3 + rand() % 5));
}
}
break;
default:
{
}
break;
}
}

View File

@ -0,0 +1,24 @@
#pragma once
#include <a8/xtimer.h>
class Human;
class Room;
class Incubator
{
public:
Room* room = nullptr;
void Init();
void UnInit();
void AllocAndroid(Human* target, int num);
void RecycleAndroid(Human* hum);
private:
bool CanSet(Human* hum, Human* exclude_hum);
void AutoAllocAndroid();
private:
std::vector<Human*> hold_humans_;
a8::XTimerAttacher xtimer_attacher_;
};

View File

@ -237,6 +237,19 @@ public:
METAMGR_READ(teammate_bekill_color, 0x00FF00);
METAMGR_READ(self_kill_color, 0xFFFF00);
METAMGR_READ(self_bekill_color, 0x00FF00);
METAMGR_READ(refresh_ai_destory_box_time, 30);
METAMGR_READ(refresh_ai_destory_box_times, 5);
METAMGR_READ(refresh_ai_downed_nearby_teammate_num, 1);
METAMGR_READ(refresh_ai_downed_nearby_range, 580);
METAMGR_READ(view_objects_out_distance, 530);
METAMGR_READ(view_objects_in_distance, 530);
METAMGR_READ(incubator_base_length, 501);
METAMGR_READ(incubator_rand_length, 10);
METAMGR_READ(incubator_canset_distance, 520);
METAMGR_READ(refresh_view_time, 4);
{
METAMGR_READ_STR(level0room_spec_things, "");
std::vector<std::string> tmpstrings;

View File

@ -139,6 +139,20 @@ class MetaMgr : public a8::Singleton<MetaMgr>
float ice_show_time = 0.5f;
float ice_invisible_time2 = 2.0f;
int refresh_ai_destory_box_time = 30;
int refresh_ai_destory_box_times = 5;
int refresh_ai_downed_nearby_teammate_num = 1;
int refresh_ai_downed_nearby_range = 580;
int view_objects_out_distance = 580;
int view_objects_in_distance = 580;
int incubator_base_length = 580;
int incubator_rand_length = 100;
int incubator_canset_distance = 100;
int refresh_view_time = 8;
#if 0
int refresh_robot_min_num = 0;
int refresh_robot_max_num = 0;

View File

@ -64,14 +64,14 @@ void MolotorCocktailMiTask::Check()
}
}
);
a8::Vec2 old_buff_vec2_param1 = sender.Get()->buff_vec2_param1;
sender.Get()->buff_vec2_param1 = sender.Get()->GetPos();
for (Creature* target : objects) {
if (!target->GetBuffById(meta->i->buffid())) {
a8::Vec2 old_buff_vec2_param1 = target->buff_vec2_param1;
target->buff_vec2_param1 = target->GetPos();
target->MustBeAddBuff(sender.Get(), meta->i->buffid());
target->buff_vec2_param1 = old_buff_vec2_param1;
}
}
sender.Get()->buff_vec2_param1 = old_buff_vec2_param1;
}
}

View File

@ -129,7 +129,10 @@ void Player::InternalUpdate(int delta_time)
if (has_use_item_id) {
UpdateUseItemId();
}
}
if (playing_skill) {
UpdateSkill();
}
}
}
void Player::UpdateMove()
@ -624,7 +627,7 @@ void Player::LootInteraction(Loot* entity)
case IS_15XSCOPE:
{
if (item_meta->i->_inventory_slot() - IS_1XSCOPE > curr_scope_idx) {
curr_scope_idx = item_meta->i->_inventory_slot() - IS_1XSCOPE;
curr_scope_idx = item_meta->i->_inventory_slot() - IS_1XSCOPE;
}
}
break;
@ -1089,6 +1092,23 @@ void Player::_CMMove(f8::MsgHdr& hdr, const cs::CMMove& msg)
last_cmmove_frameno = room->GetFrameNo();
}
void Player::_CMExecCommand(f8::MsgHdr& hdr, const cs::CMExecCommand& msg)
{
std::vector<std::string> cmds;
a8::Split(msg.cmd().c_str(), cmds, ' ');
if (cmds.empty()) {
return;
}
std::string cmd = cmds[0];
if (cmd == "gps") {
SendDebugMsg(a8::Format("%d %d", {GetPos().x, GetPos().y}));
}else if (cmd == "additem" && cmds.size() >= 2) {
int item_id = a8::XValue(cmds[1]);
int item_num = a8::XValue(cmds[2]);
GMAddItem(item_id, item_num);
}
}
void Player::UpdateDropWeapon()
{
if (drop_weapon_idx >= 0 &&

View File

@ -102,6 +102,7 @@ class Player : public Human
void _CMReconnect(f8::MsgHdr& hdr, const cs::CMReconnect& msg);
void _CMMove(f8::MsgHdr& hdr, const cs::CMMove& msg);
void _CMExecCommand(f8::MsgHdr& hdr, const cs::CMExecCommand& msg);
void _CMEmote(f8::MsgHdr& hdr, const cs::CMEmote& msg);
void _CMVoice(f8::MsgHdr& hdr, const cs::CMVoice& msg);
void _CMGameOver(f8::MsgHdr& hdr, const cs::CMGameOver& msg);

View File

@ -64,14 +64,14 @@ void PosionGasMiTask::Check()
}
}
);
a8::Vec2 old_buff_vec2_param1 = sender.Get()->buff_vec2_param1;
sender.Get()->buff_vec2_param1 = sender.Get()->GetPos();
for (Creature* target : objects) {
if (!target->GetBuffById(meta->i->buffid())) {
a8::Vec2 old_buff_vec2_param1 = target->buff_vec2_param1;
target->buff_vec2_param1 = target->GetPos();
target->MustBeAddBuff(sender.Get(), meta->i->buffid());
target->buff_vec2_param1 = old_buff_vec2_param1;
}
}
sender.Get()->buff_vec2_param1 = old_buff_vec2_param1;
}
}

View File

@ -29,6 +29,7 @@
#include "perfmonitor.h"
#include "mapinstance.h"
#include "mapmgr.h"
#include "incubator.h"
#include "framework/cpp/utils.h"
@ -85,6 +86,9 @@ void Room::Init()
CreateDropObjs();
InitObstacleDatas();
ShuaAndroid();
incubator_ = new Incubator();
incubator_->room = this;
incubator_->Init();
if (room_type_ == RT_NewBrid && creator_game_times_ <= 0) {
CreateLevel0RoomSpecThings();
}
@ -95,9 +99,12 @@ void Room::Init()
void Room::UnInit()
{
incubator_->UnInit();
#ifdef DEBUG
UnInitDebugInfo();
#endif
incubator_->UnInit();
A8_SAFE_DELETE(incubator_);
timer_attacher.ClearTimerList();
xtimer_attacher_.ClearTimerList();
for (auto& pair : accountid_hash_) {
@ -1077,6 +1084,31 @@ void Room::TouchEntityList(a8::XParams param,
}
}
void Room::TouchAlivePlayers(a8::XParams param,
std::function<bool (Human*, a8::XParams&)> func)
{
for (auto& pair : alive_player_hash_) {
if (!func(pair.second, param)) {
break;
}
}
}
void Room::BroadcastDebugMsg(const std::string& debug_msg)
{
#ifdef DEBUG
TouchHumanList
(
a8::XParams()
.SetParam1(debug_msg),
[] (Human* hum, a8::XParams& param) -> bool
{
hum->SendDebugMsg(param.param1);
return true;
});
#endif
}
void Room::UpdateGas()
{
switch (gas_data_.gas_mode) {
@ -2279,13 +2311,23 @@ void Room::EnableHuman(Human* target)
target->GetEntityUniId()
});
#endif
#if 0
target->OnEnable();
AddToMoveableHash(target);
if (!target->real_dead) {
AddToAliveHumanHash(target);
}
#else
if (a8::HasBitFlag(target->status, HS_Disable)) {
target->OnEnable();
AddToMoveableHash(target);
if (!target->real_dead) {
AddToAliveHumanHash(target);
}
} else {
abort();
}
#endif
#ifdef DEBUG
CheckPartObjects();
#endif
@ -2293,9 +2335,11 @@ void Room::EnableHuman(Human* target)
void Room::DisableHuman(Human* target)
{
#if 0
if (!RuningInTimer()) {
abort();
}
#endif
#ifdef DEBUG
CheckPartObjects();
a8::UdpLog::Instance()->Debug("disablehuman %d %d",
@ -2658,6 +2702,15 @@ bool Room::HasPlayerInRound(const a8::Vec2& pos, float rad)
void Room::ProcDisableHuman()
{
#if 1
for (auto& pair : human_hash_) {
if (pair.second->IsAndroid() &&
pair.second->team_uuid.empty() &&
!a8::HasBitFlag(pair.second->status, HS_Disable)) {
DisableHuman(pair.second);
}
}
#else
if (room_type_ == RT_NewBrid || room_type_ == RT_MidBrid) {
for (auto& pair : human_hash_) {
if (pair.second->IsAndroid() &&
@ -2667,6 +2720,7 @@ void Room::ProcDisableHuman()
}
}
}
#endif
}
void Room::OnHumanGridChg(Human* target)
@ -2968,6 +3022,9 @@ void Room::AddToHumanHash(Human* hum)
void Room::AddToAliveHumanHash(Human* hum)
{
alive_human_hash_[hum->GetEntityUniId()] = hum;
if (hum->IsPlayer()) {
alive_player_hash_[hum->GetEntityUniId()] = hum;
}
}
void Room::AddToMoveableHash(MoveableEntity* entity)
@ -3008,6 +3065,9 @@ void Room::RemoveFromHuamnHash(Human* hum)
void Room::RemoveFromAliveHumanHash(Human* hum)
{
alive_human_hash_.erase(hum->GetEntityUniId());
if (hum->IsPlayer()) {
alive_player_hash_.erase(hum->GetEntityUniId());
}
}
void Room::RemoveFromLaterAddHash(RoomEntity* entity)
@ -3662,6 +3722,7 @@ void Room::ForwardGasRing(int n)
}
gas_data_.rad_old = gas_data_.old_area_meta->i->rad();
gas_data_.rad_new = gas_data_.new_area_meta->i->rad();
gas_data_.gas_count++;
--n;
}
}

View File

@ -36,6 +36,7 @@ class AabbCollider;
class Android;
class Car;
class Hero;
class Incubator;
class Room
{
public:
@ -98,6 +99,9 @@ public:
std::function<bool (Human*, a8::XParams&)> func);
void TouchEntityList(a8::XParams param,
std::function<bool (Entity*, a8::XParams&)> func);
void TouchAlivePlayers(a8::XParams param,
std::function<bool (Human*, a8::XParams&)> func);
void BroadcastDebugMsg(const std::string& debug_msg);
void ScatterDrop(a8::Vec2 center, int drop_id);
void DropItem(a8::Vec2 pos, int item_id, int item_count, int item_lv);
@ -170,6 +174,7 @@ public:
int GetOnlinePlayerNum();
RoomObstacle* CreateObstacle(int id, float x, float y);
int AllocUniid();
Incubator* GetIncubator() { return incubator_;};
private:
void ShuaAndroid();
@ -311,6 +316,7 @@ private:
std::map<int, RoomEntity*> later_add_hash_;
std::map<int, Human*> human_hash_;
std::map<int, Human*> alive_human_hash_;
std::map<int, Human*> alive_player_hash_;
std::map<int, Human*> last_human_hash_;
std::map<int, BornPoint> born_point_hash_;
@ -320,4 +326,8 @@ private:
std::vector<ObstacleData> obstacle_datas_;
xtimer_list* auto_jump_timer_ = nullptr;
Incubator* incubator_ = nullptr;
friend class Incubator;
};

View File

@ -29,6 +29,7 @@ struct GasData
MetaData::SafeArea* old_area_meta = nullptr;
MetaData::SafeArea* new_area_meta = nullptr;
bool is_last_gas = false;
int gas_count = 0;
};
struct Weapon
@ -131,6 +132,13 @@ struct HumanAbility
float fire_rate = 0.0f;
};
struct HumanBehavior
{
long long curr_start_destory_box_frameno = 0;
int curr_destory_box_times = 0;
int total_destory_box_times = 0;
};
struct ObstacleData
{
int flags = 0;

View File

@ -93,6 +93,9 @@ void ZombieModeAI::UpdateAI()
abort();
}
}
if (hum->playing_skill) {
hum->UpdateSkill();
}
++node_->exec_frame_num;
hum->shot_hold = false;
switch (node_->main_state) {

View File

@ -20,6 +20,7 @@ enum CMMessageId_e
_CMAdEnd = 214;
_CMGetBoxInfo = 215;
_CMOpenBox = 216;
_CMExecCommand = 217;
}
enum SMMessageId_e

View File

@ -899,6 +899,12 @@ message CMMove
optional int32 get_on = 36;
}
//GM指令
message CMExecCommand
{
optional string cmd = 1; //
}
//
message CMDropItem
{

@ -1 +1 @@
Subproject commit 2b5f0d3b41e764d61181089b95c4fa568b1e1942
Subproject commit 8b6410826da2c0c667abdacadae6d7c00f70300d