完成子弹hit逻辑

This commit is contained in:
aozhiwei 2021-05-14 14:50:26 +08:00
parent d9164d85dc
commit 28e4f36c4f
9 changed files with 93 additions and 86 deletions

View File

@ -51,88 +51,7 @@ void Bullet::RecalcSelfCollider()
void Bullet::OnHit(std::set<Entity*>& objects)
{
for (auto& target : objects) {
switch (target->GetEntityType()) {
case ET_Player:
{
Human* hum = (Human*)target;
if (hum->IsInvincible()) {
continue;
}
if (sender.Get()->room->GetRoomMode() == kZombieMode &&
sender.Get()->GetRace() == hum->GetRace()) {
continue;
}
if (!hum->dead && (IsBomb() || sender.Get()->team_id != hum->team_id)) {
float dmg = GetAtk() * (1 + sender.Get()->GetAttrRate(kHAT_Atk)) +
sender.Get()->GetAttrAbs(kHAT_Atk);
float def = hum->ability.def * (1 + hum->GetAttrRate(kHAT_Def)) +
hum->GetAttrAbs(kHAT_Def);
float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K);
finaly_dmg = std::max(finaly_dmg, 0.0f);
#if 0
sender->stats.damage_amount_out += finaly_dmg;
#endif
#ifdef DEBUG
if (App::Instance()->HasFlag(1) && hum->IsPlayer()) {
continue;
}
#endif
if (meta->buff_meta) {
hum->MustBeAddBuff(hum, meta->i->buffid());
}
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",
{
gun_meta->i->id(),
GetAtk()
})
);
#endif
}
}
break;
case ET_Obstacle:
{
Obstacle* obstacle = (Obstacle*)target;
if (!obstacle->IsDead(room) &&
obstacle->Attackable() &&
!obstacle->IsTerminatorAirDropBox(room)) {
float dmg = GetAtk() * (1 + sender.Get()->GetAttrRate(kHAT_Atk)) +
sender.Get()->GetAttrAbs(kHAT_Atk);
float def = 0;
float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K);
obstacle->SetHealth(room, std::max(0.0f, obstacle->GetHealth(room) - finaly_dmg));
if (obstacle->GetHealth(room) <= 0.01f) {
obstacle->Die(room);
}
if (obstacle->IsDead(room)) {
if (obstacle->meta->i->damage_dia() > 0.01f &&
obstacle->meta->i->damage() > 0.01f) {
obstacle->Explosion(this);
}
sender.Get()->DropItems(obstacle);
}
obstacle->BroadcastFullState(room);
#ifdef DEBUG
sender.Get()->SendDebugMsg(a8::Format("bullet weapon_id:%d atk:%f",
{
gun_meta->i->id(),
GetAtk()
})
);
#endif
}
}
break;
case ET_Car:
{
}
break;
default:
break;
}
target->OnBulletHit(this);
}
}

View File

@ -34,6 +34,8 @@ class Bullet : public MoveableEntity
virtual void Initialize() override;
virtual void Update(int delta_time) override;
void RecalcSelfCollider();
bool IsBomb();
float GetAtk();
protected:
Bullet();
@ -46,9 +48,7 @@ protected:
void ProcFragBomb(int delay_time);
void ProcPosionGasBomb(int delay_time);
void ProcMolotorCocktailBomb(int delay_time);
bool IsBomb();
inline void MapServiceUpdate();
float GetAtk();
void Check(float distance);
private:

View File

@ -36,6 +36,8 @@ void Car::Initialize()
SetCurrWeapon(&weapons[GUN_SLOT1]);
}
born_frameno_ = room->GetFrameNo();
ability.hp = hero_meta_->i->health();
ability.max_hp = std::max(ability.hp, ability.max_hp);
}
void Car::FillMFObjectPart(Room* room, Human* hum, cs::MFObjectPart* part_data)
@ -198,8 +200,7 @@ void Car::SyncPos()
float Car::GetRadius()
{
abort();
return 0;
return hero_meta_->i->radius();
}
float Car::GetSpeed()
@ -207,3 +208,8 @@ float Car::GetSpeed()
float speed = hero_meta_->i->move_speed();
return speed;
}
void Car::OnBulletHit(Bullet* bullet)
{
}

View File

@ -24,6 +24,7 @@ class Car : public Creature
virtual void Initialize() override;
virtual void FillMFObjectPart(Room* room, Human* hum, cs::MFObjectPart* part_data) override;
virtual void FillMFObjectFull(Room* room, Human* hum, cs::MFObjectFull* full_data) override;
virtual void OnBulletHit(Bullet* bullet) override;
bool IsDriver(Human* hum) { return driver_ == hum && driver_; }
void GetDown(Human* passenger);

View File

@ -11,6 +11,7 @@ class ColliderComponent;
class AabbCollider;
class CircleCollider;
class Human;
class Bullet;
class Entity
{
public:
@ -30,6 +31,7 @@ class Entity
virtual long long GetDeadFrameNo(Room* room) { return 0;};
virtual void OnPreCollision(Room* room) {};
virtual void RecalcSelfCollider() {};
virtual void OnBulletHit(Bullet* bullet) {};
int GetEntityUniId() const { return entity_uniid_; }
EntityType_e GetEntityType() const { return entity_type_; }
EntitySubType_e GetEntitySubType() const { return entity_subtype_; }

View File

@ -3644,3 +3644,46 @@ void Human::AddHp(float hp)
stats.heal_amount += GetHP() - old_health;
SyncAroundPlayers(__FILE__, __LINE__, __func__);
}
void Human::OnBulletHit(Bullet* bullet)
{
if (IsInvincible()) {
return;
}
if (bullet->sender.Get()->room->GetRoomMode() == kZombieMode &&
bullet->sender.Get()->GetRace() == GetRace()) {
return;
}
if (!dead && (bullet->IsBomb() || bullet->sender.Get()->team_id != team_id)) {
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);
#if 0
sender->stats.damage_amount_out += finaly_dmg;
#endif
#ifdef DEBUG
if (App::Instance()->HasFlag(1) && IsPlayer()) {
return;
}
#endif
if (bullet->meta->buff_meta) {
MustBeAddBuff(this, bullet->meta->i->buffid());
}
DecHP(finaly_dmg,
bullet->sender.Get()->GetEntityUniId(),
bullet->sender.Get()->GetName(),
bullet->gun_meta->i->id());
#ifdef DEBUG
bullet->sender.Get()->SendDebugMsg
(a8::Format("bullet weapon_id:%d atk:%f",
{
bullet->gun_meta->i->id(),
bullet->GetAtk()
})
);
#endif
}
}

View File

@ -151,6 +151,7 @@ class Human : public Creature
virtual void GetHitAabbBox(AabbCollider& aabb_box) override;
virtual bool IsDead(Room* room) override;
virtual long long GetDeadFrameNo(Room* room) override;
virtual void OnBulletHit(Bullet* bullet) override;
void FillItemList(::google::protobuf::RepeatedPtrField<::cs::MFPair>* pb_item_list);
long long GetRealDeadFrameNo(Room* room);
void FillMFTeamData(cs::MFTeamData* team_data, bool is_game_over);

View File

@ -516,3 +516,37 @@ void Obstacle::SetMasterId(Room* room, int master_id)
master_id_ = master_id;
}
}
void Obstacle::OnBulletHit(Bullet* bullet)
{
if (!IsDead(bullet->room) &&
Attackable() &&
!IsTerminatorAirDropBox(bullet->room)) {
float dmg = bullet->GetAtk() * (1 + bullet->sender.Get()->GetAttrRate(kHAT_Atk)) +
bullet->sender.Get()->GetAttrAbs(kHAT_Atk);
float def = 0;
float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K);
SetHealth(bullet->room, std::max(0.0f, GetHealth(bullet->room) - finaly_dmg));
if (GetHealth(bullet->room) <= 0.01f) {
Die(bullet->room);
}
if (IsDead(bullet->room)) {
if (meta->i->damage_dia() > 0.01f &&
meta->i->damage() > 0.01f) {
Explosion(bullet);
}
bullet->sender.Get()->DropItems(this);
}
BroadcastFullState(bullet->room);
#ifdef DEBUG
bullet->sender.Get()->SendDebugMsg
(
a8::Format("bullet weapon_id:%d atk:%f",
{
bullet->gun_meta->i->id(),
bullet->GetAtk()
})
);
#endif
}
}

View File

@ -39,6 +39,7 @@ class Obstacle : public Entity
virtual bool IsDead(Room* room) override;
virtual long long GetDeadFrameNo(Room* room) override;
virtual void OnPreCollision(Room* room) override;
virtual void OnBulletHit(Bullet* bullet) override;
virtual bool IsTerminatorAirDropBox(Room* room) { return false; }
virtual bool CanThroughable(Human* num) { return false; }
void Explosion(Bullet* bullet);