diff --git a/server/gameserver/car.cc b/server/gameserver/car.cc index ba8b09b..ed92759 100644 --- a/server/gameserver/car.cc +++ b/server/gameserver/car.cc @@ -7,6 +7,7 @@ #include "loot.h" #include "perfmonitor.h" #include "typeconvert.h" +#include "bullet.h" Car::Car():Creature() { @@ -211,5 +212,38 @@ float Car::GetSpeed() void Car::OnBulletHit(Bullet* bullet) { - + if (!IsDead(room)) { + float dmg = bullet->GetAtk() * (1 + bullet->sender.Get()->GetAttrRate(kHAT_Atk)) + + bullet->sender.Get()->GetAttrAbs(kHAT_Atk); + float def = ability.def * (1 + GetAttrRate(kHAT_Def)) + + GetAttrAbs(kHAT_Def); + float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K); + finaly_dmg = std::max(finaly_dmg, 0.0f); + DecHP(finaly_dmg, + bullet->sender.Get()->GetEntityUniId(), + bullet->sender.Get()->GetName(), + bullet->gun_meta->i->id()); + if (bullet->meta->buff_meta) { + MustBeAddBuff(this, bullet->meta->i->buffid()); + } + } +} + +void Car::DecHP(float dec_hp, int killer_id, const std::string& killer_name, int weapon_id) +{ + float old_health = GetHP(); + float new_health = std::max(0.0f, GetHP() - dec_hp); + ability.hp = std::max(0.0f, new_health); + if (GetHP() <= 0.0001f && !IsDead(room)) { + BeKill(killer_id, killer_name, weapon_id); + } + room->frame_event.AddHpChg(GetWeakPtrRef()); +} + +void Car::BeKill(int killer_id, const std::string& killer_name, int weapon_id) +{ + dead = true; + BroadcastDeleteState(room); + RemoveFromAroundPlayers(room); + room->grid_service->RemoveCreature(this); } diff --git a/server/gameserver/car.h b/server/gameserver/car.h index 6097b44..59edb9c 100644 --- a/server/gameserver/car.h +++ b/server/gameserver/car.h @@ -32,9 +32,11 @@ class Car : public Creature void SyncPos(); virtual float GetRadius() override; virtual float GetSpeed() override; + virtual void DecHP(float dec_hp, int killer_id, const std::string& killer_name, int weapon_id) override; private: int AllocSeat(); + void BeKill(int killer_id, const std::string& killer_name, int weapon_id); private: long long born_frameno_ = 0; diff --git a/server/gameserver/frameevent.cc b/server/gameserver/frameevent.cc index 625d0e3..a0aa5de 100644 --- a/server/gameserver/frameevent.cc +++ b/server/gameserver/frameevent.cc @@ -183,11 +183,11 @@ void FrameEvent::AddPlaySkill(CreatureWeakPtr& sender, int skill_id) } } -void FrameEvent::AddHpChg(Human* sender) +void FrameEvent::AddHpChg(CreatureWeakPtr& sender) { chged_hps_.push_back(sender); int idx = chged_hps_.size() - 1; - sender->TouchAllLayerHumanList + sender.Get()->TouchAllLayerHumanList ( [idx] (Human* hum, bool& stop) { diff --git a/server/gameserver/frameevent.h b/server/gameserver/frameevent.h index a746d56..1cc3e31 100644 --- a/server/gameserver/frameevent.h +++ b/server/gameserver/frameevent.h @@ -25,7 +25,7 @@ public: void AddPlaySkill(CreatureWeakPtr& sender, int skill_id); void AddExplosionEx(CreatureWeakPtr& sender, int item_id, a8::Vec2 bomb_pos, int effect); void AddBulletNumChg(Human* hum); - void AddHpChg(Human* hum); + void AddHpChg(CreatureWeakPtr& sender); void AddWeaponAmmoChg(Human* hum); void AddBuff(CreatureWeakPtr& sender, Buff* buff); void RemoveBuff(CreatureWeakPtr& sender, int buff_id); @@ -50,7 +50,7 @@ private: std::vector> chged_items_; std::vector chged_bullet_nums_; std::vector> chged_weapon_ammo_; - std::vector chged_hps_; + std::vector chged_hps_; std::vector> chged_skillcds_; std::vector> chged_skill_curr_times_; std::vector chged_zombieids_; diff --git a/server/gameserver/framemaker.cc b/server/gameserver/framemaker.cc index 55bcb31..54425e0 100644 --- a/server/gameserver/framemaker.cc +++ b/server/gameserver/framemaker.cc @@ -222,19 +222,19 @@ cs::SMUpdate* FrameMaker::MakeUpdateMsg(Human* hum) } for (size_t idx : hum->chged_hps_) { if (idx < room->frame_event.chged_hps_.size()) { - Human* target = room->frame_event.chged_hps_[idx]; - if (hum->CanSee(target)) { + CreatureWeakPtr& target = room->frame_event.chged_hps_[idx]; + if (target.Get() && hum->CanSee(target.Get())) { { auto p = msg->add_chged_property_list(); - p->set_obj_id(target->GetEntityUniId()); + p->set_obj_id(target.Get()->GetEntityUniId()); p->set_property_type(kPropHp); - p->set_value(target->GetHP()); + p->set_value(target.Get()->GetHP()); } { auto p = msg->add_chged_property_list(); - p->set_obj_id(target->GetEntityUniId()); + p->set_obj_id(target.Get()->GetEntityUniId()); p->set_property_type(kPropMaxHp); - p->set_value(target->GetMaxHP()); + p->set_value(target.Get()->GetMaxHP()); } } } diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index e6125bd..324a517 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -952,7 +952,7 @@ void Human::DecHP(float dec_hp, int killer_id, const std::string& killer_name, i } } } - room->frame_event.AddHpChg(this); + room->frame_event.AddHpChg(GetWeakPtrRef()); } } @@ -3021,7 +3021,7 @@ void Human::OnMetaChange() ability.hp += weapon.meta ? weapon.GetAttrValue(kHAT_MaxHp) : 0; } } - room->frame_event.AddHpChg(this); + room->frame_event.AddHpChg(GetWeakPtrRef()); RecalcBaseAttr(); ClearSkill(); AddSkill(meta->i->active_skill());