diff --git a/server/gameserver/bullet.cc b/server/gameserver/bullet.cc index b275c55..c2084f7 100644 --- a/server/gameserver/bullet.cc +++ b/server/gameserver/bullet.cc @@ -33,6 +33,7 @@ void Bullet::Initialize() RecalcSelfCollider(); ability_ = sender.Get()->GetAbility(); is_curr_weapon = sender.Get()->GetCurrWeapon()->meta == gun_meta; + create_frameno_ = room->GetFrameNo(); } void Bullet::Update(int delta_time) @@ -588,3 +589,8 @@ void Bullet::AddGunBuff() sender.Get()->context_ability = old_context_ability; } } + +bool Bullet::IsPreBattleBullet() +{ + return create_frameno_ <= room->GetBattleStartFrameNo(); +} diff --git a/server/gameserver/bullet.h b/server/gameserver/bullet.h index dd4f2bd..f4a4fc5 100644 --- a/server/gameserver/bullet.h +++ b/server/gameserver/bullet.h @@ -41,6 +41,7 @@ class Bullet : public MoveableEntity float GetAtk(); float GetExplosionRange(); bool IsCurrWeapon(); + bool IsPreBattleBullet(); protected: Bullet(); @@ -67,6 +68,7 @@ private: std::shared_ptr ability_; bool is_curr_weapon = false; std::set hit_objects_; + long long create_frameno_ = 0; friend class EntityFactory; }; diff --git a/server/gameserver/car.cc b/server/gameserver/car.cc index b127dec..773d071 100644 --- a/server/gameserver/car.cc +++ b/server/gameserver/car.cc @@ -291,10 +291,12 @@ void Car::OnBulletHit(Bullet* bullet) if (bullet->meta->buff_meta) { MustBeAddBuff(bullet->sender.Get(), bullet->meta->i->buffid()); } - DecHP(finaly_dmg, - bullet->sender.Get()->GetUniId(), - bullet->sender.Get()->GetName(), - bullet->gun_meta->i->id()); + if (!bullet->IsPreBattleBullet()) { + DecHP(finaly_dmg, + bullet->sender.Get()->GetUniId(), + bullet->sender.Get()->GetName(), + bullet->gun_meta->i->id()); + } if (bullet->meta->buff_meta) { MustBeAddBuff(this, bullet->meta->i->buffid()); } diff --git a/server/gameserver/creature.cc b/server/gameserver/creature.cc index 89bd1b7..a1e780a 100644 --- a/server/gameserver/creature.cc +++ b/server/gameserver/creature.cc @@ -42,9 +42,8 @@ static void InternalCreateBullet(BulletInfo& bullet_info) } if (bullet_info.delay_time <= 0) { int bullet_uniid = 0; - if (c->room->BattleStarted() || - (c->room->GetGasData().gas_mode == GasJump && - !c->HasBuffEffect(kBET_Jump))) { + if (MetaMgr::Instance()->prebattle_can_use_skill || + !(c->HasBuffEffect(kBET_Jump) || c->HasBuffEffect(kBET_Fly))) { bullet_uniid = c->room->CreateBullet (c, c->shot_passenger, @@ -56,9 +55,7 @@ static void InternalCreateBullet(BulletInfo& bullet_info) bullet_info.fly_distance, bullet_info.is_tank_skin); } - if (bullet_uniid == 0) { - bullet_uniid = c->room->AllocUniid(); - } + bullet_uniid = bullet_uniid ? bullet_uniid : c->room->AllocUniid(); c->room->frame_event.AddBullet (bullet_uniid, c->GetWeakPtrRef(), @@ -70,7 +67,7 @@ static void InternalCreateBullet(BulletInfo& bullet_info) } else { BulletInfo* info_copy = new BulletInfo(); *info_copy = bullet_info; - bullet_info.c.Get()->room->xtimer.AddDeadLineTimerAndAttach + xtimer_list* timer = bullet_info.c.Get()->room->xtimer.AddDeadLineTimerAndAttach ( bullet_info.delay_time / FRAME_RATE_MS, a8::XParams() @@ -88,6 +85,9 @@ static void InternalCreateBullet(BulletInfo& bullet_info) delete info_copy; } ); + if (!c->room->BattleStarted()) { + c->room->AddToPostBattleAutoFreeList(timer); + } } } diff --git a/server/gameserver/hero.cc b/server/gameserver/hero.cc index 5627097..9632348 100644 --- a/server/gameserver/hero.cc +++ b/server/gameserver/hero.cc @@ -131,10 +131,12 @@ void Hero::OnBulletHit(Bullet* bullet) if (bullet->meta->buff_meta) { MustBeAddBuff(bullet->sender.Get(), bullet->meta->i->buffid()); } - DecHP(finaly_dmg, - bullet->sender.Get()->GetUniId(), - bullet->sender.Get()->GetName(), - bullet->gun_meta->i->id()); + if (!bullet->IsPreBattleBullet()) { + DecHP(finaly_dmg, + bullet->sender.Get()->GetUniId(), + bullet->sender.Get()->GetName(), + bullet->gun_meta->i->id()); + } } } diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index d1a11ed..f9842f4 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -3618,15 +3618,19 @@ void Human::OnBulletHit(Bullet* bullet) MustBeAddBuff(bullet->sender.Get(), bullet->meta->i->buffid()); } if (bullet->sender.Get() && bullet->sender.Get()->IsCar() && bullet->passenger.Get()) { - DecHP(finaly_dmg, - bullet->passenger.Get()->GetUniId(), - bullet->passenger.Get()->GetName(), - bullet->gun_meta->i->id()); + if (!bullet->IsPreBattleBullet()) { + DecHP(finaly_dmg, + bullet->passenger.Get()->GetUniId(), + bullet->passenger.Get()->GetName(), + bullet->gun_meta->i->id()); + } } else { - DecHP(finaly_dmg, - bullet->sender.Get()->GetUniId(), - bullet->sender.Get()->GetName(), - bullet->gun_meta->i->id()); + if (!bullet->IsPreBattleBullet()) { + DecHP(finaly_dmg, + bullet->sender.Get()->GetUniId(), + bullet->sender.Get()->GetName(), + bullet->gun_meta->i->id()); + } } #ifdef DEBUG bullet->sender.Get()->SendDebugMsg diff --git a/server/gameserver/obstacle.cc b/server/gameserver/obstacle.cc index b27e8af..99a8655 100644 --- a/server/gameserver/obstacle.cc +++ b/server/gameserver/obstacle.cc @@ -472,6 +472,9 @@ void Obstacle::OnBulletHit(Bullet* bullet) if (meta->i->bullet_hit() == kBulletHitEatDmg) { return; } + if (bullet->IsPreBattleBullet()) { + return; + } if (!IsDead(bullet->room) && !IsTerminatorAirDropBox(bullet->room)) { if (meta->receive_special_damage_type != 0 && diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index aeff713..4a1015d 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -1399,6 +1399,7 @@ void Room::UpdateGasJump() InitAirDrop(); InitAirRaid(); } + ClearPostBattleAutoFreeList(); } } @@ -4000,3 +4001,33 @@ void Room::AirRaid(int airraid_id) raid_cb, &xtimer_attacher_.timer_list_); } + +void Room::AddToPostBattleAutoFreeList(xtimer_list* timer) +{ + if (BattleStarted()) { + abort(); + } + if (!timer) { + abort(); + } + if (post_battle_auto_free_list_.find(timer) != post_battle_auto_free_list_.end()) { + abort(); + } + auto cb = + [this] (xtimer_list* timer) + { + post_battle_auto_free_list_.erase(timer); + }; + xtimer.AddTimerDestoryHandle(timer, cb); + post_battle_auto_free_list_.insert(timer); +} + +void Room::ClearPostBattleAutoFreeList() +{ + while (!post_battle_auto_free_list_.empty()) { + for (xtimer_list* timer : post_battle_auto_free_list_) { + xtimer.DeleteTimer(timer); + break; + } + } +} diff --git a/server/gameserver/room.h b/server/gameserver/room.h index 2b2cf0c..307acd3 100644 --- a/server/gameserver/room.h +++ b/server/gameserver/room.h @@ -188,6 +188,7 @@ public: void GetPartObjectWatchList(Entity* entity, std::vector& watch_list); void SetInfiniteBulletMode(); bool IsInfiniteBulletMode() { return infinite_bullet_mode_; }; + void AddToPostBattleAutoFreeList(xtimer_list* timer); private: void ShuaAndroid(); @@ -269,6 +270,7 @@ private: void InitAndroidAI(); void ForwardGasRing(int n); void InternalRemoveObjectLater(Entity* entity, a8::XTimerAttacher& entity_xtimer_attacher); + void ClearPostBattleAutoFreeList(); #ifdef DEBUG void InitDebugInfo(); @@ -340,6 +342,8 @@ private: std::vector obstacle_datas_; + std::set post_battle_auto_free_list_; + xtimer_list* auto_jump_timer_ = nullptr; Incubator* incubator_ = nullptr; diff --git a/third_party/a8engine b/third_party/a8engine index 8932713..5e0a939 160000 --- a/third_party/a8engine +++ b/third_party/a8engine @@ -1 +1 @@ -Subproject commit 8932713766a5c0289966f08a5a0153a1ae493a9d +Subproject commit 5e0a939a89ba97edd371695432ef029eae2c55d5