diff --git a/server/gameserver/creature.cc b/server/gameserver/creature.cc index f9d1512e..ae047595 100644 --- a/server/gameserver/creature.cc +++ b/server/gameserver/creature.cc @@ -3789,71 +3789,3 @@ void Creature::CheckShotHold() } } } - -void Creature::Throw(int slot, const glm::vec3& bomb_pos, const glm::vec3& bomb_dir, - float fly_distance, int estimated_time) -{ - if (slot < 0 || slot >= weapons.size()) { - return; - } - - Weapon& weapon = weapons.at(slot); - if (weapon.weapon_idx != 0 && - weapon.meta && - weapon.ammo > 0) { - if (HasBuffEffect(kBET_Hide)) { - RemoveHideEffect(kShotReason); - } - if (!nature_recover_hp_idle_timer.expired()) { - room->xtimer.FireEvent - ( - nature_recover_hp_idle_timer, - kRemoveNatureRecoverTimerEvent, - nullptr); - } - --weapon.ammo; - room->frame_event.AddPropChgEx - ( - GetWeakPtrRef(), - kPropWeaponAmmo, - weapon.weapon_idx, - weapon.ammo, - weapon.GetClipVolume(this), - 0, - true - ); - DecInventory(weapon.meta->_inventory_slot(), 1); - if (IsHuman()) { - AsHuman()->SyncVolume(weapon.meta->_inventory_slot()); - } - SetAttackDir(bomb_dir); - int throw_uniid = room->AllocUniid(); - room->frame_event.AddBullet - ( - throw_uniid, - GetWeakPtrRef(), - weapon.meta, - 1, - bomb_pos, - bomb_dir, - fly_distance, - 0, - 1, - nullptr); - if (IsPlayer()) { - AsPlayer()->pending_throw_bomb[throw_uniid] = AsPlayer()->throw_bomb; - } - room->xtimer.SetTimeoutEx - ( - SERVER_FRAME_RATE * 15, - [this, throw_uniid] (int event, const a8::Args* args) - { - if (a8::TIMER_DELETE_EVENT == event) { - if (IsPlayer()) { - AsPlayer()->ProcThrowDmg(throw_uniid); - } - } - }, - &room->xtimer_attacher_); - } -} diff --git a/server/gameserver/creature.h b/server/gameserver/creature.h index 3215e508..c57f1646 100644 --- a/server/gameserver/creature.h +++ b/server/gameserver/creature.h @@ -395,8 +395,8 @@ class Creature : public MoveableEntity float GetSkillLocalVar(int skill_id, int idx); void SetSkillLocalVar(int skill_id, int idx, float val); void CheckShotHold(); - void Throw(int slot, const glm::vec3& pos, const glm::vec3& dir, - float fly_distance, int estimated_time); + int Throw(int slot, const glm::vec3& bomb_pos, const glm::vec3& bomb_dir, + float fly_distance, int estimated_time); protected: virtual void OnBuffRemove(Buff& buff); diff --git a/server/gameserver/pbutils.cc b/server/gameserver/pbutils.cc index 8a33c154..54c0b533 100644 --- a/server/gameserver/pbutils.cc +++ b/server/gameserver/pbutils.cc @@ -2222,3 +2222,89 @@ void SyncObject::FillSMSyncPosition(cs::SMSyncPosition& sync_msg) last_sync_frameno = c.Get()->room->GetFrameNo(); } } + +int Creature::Throw(int slot, const glm::vec3& bomb_pos, const glm::vec3& bomb_dir, + float fly_distance, int estimated_time) +{ + if (!IsHuman()) { + return 0; + } + if (slot < 0 || slot >= weapons.size()) { + return 0; + } + + Weapon& weapon = weapons.at(slot); + if (weapon.weapon_idx != 0 && + weapon.meta && + weapon.ammo > 0) { + if (HasBuffEffect(kBET_Hide)) { + RemoveHideEffect(kShotReason); + } + if (!nature_recover_hp_idle_timer.expired()) { + room->xtimer.FireEvent + ( + nature_recover_hp_idle_timer, + kRemoveNatureRecoverTimerEvent, + nullptr); + } + --weapon.ammo; + room->frame_event.AddPropChgEx + ( + GetWeakPtrRef(), + kPropWeaponAmmo, + weapon.weapon_idx, + weapon.ammo, + weapon.GetClipVolume(this), + 0, + true + ); + DecInventory(weapon.meta->_inventory_slot(), 1); + AsHuman()->SyncVolume(weapon.meta->_inventory_slot()); + SetAttackDir(bomb_dir); + int throw_uniid = room->AllocUniid(); + room->frame_event.AddBullet + ( + throw_uniid, + GetWeakPtrRef(), + weapon.meta, + 1, + bomb_pos, + bomb_dir, + fly_distance, + 0, + 1, + nullptr); + if (IsAndroid()) { + AsHuman()->throw_bomb = std::make_shared(); + } + AsHuman()->pending_throw_bomb[throw_uniid] = AsPlayer()->throw_bomb; + if (IsAndroid()) { + room->xtimer.SetTimeoutEx + ( + SERVER_FRAME_RATE * 1, + [this, throw_uniid] (int event, const a8::Args* args) + { + if (a8::TIMER_EXEC_EVENT == event) { + if (IsHuman()) { + AsHuman()->ProcThrowDmg(throw_uniid); + } + } + }, + &room->xtimer_attacher_); + } else { + room->xtimer.SetTimeoutEx + ( + SERVER_FRAME_RATE * 15, + [this, throw_uniid] (int event, const a8::Args* args) + { + if (a8::TIMER_DELETE_EVENT == event) { + if (IsPlayer()) { + AsPlayer()->ProcThrowDmg(throw_uniid); + } + } + }, + &room->xtimer_attacher_); + } + } + return 0; +}