diff --git a/server/gameserver/android.ai.cc b/server/gameserver/android.ai.cc index 0d3b38c..048462c 100644 --- a/server/gameserver/android.ai.cc +++ b/server/gameserver/android.ai.cc @@ -8,7 +8,14 @@ void AndroidAI::Update(int delta_time) { + Human* hum = (Human*)owner; + if (hum->poisoning) { + hum->poisoning_time += delta_time; + } state_elapsed_time += delta_time; + if (hum->poisoning) { + hum->UpdatePoisoning(); + } switch (state) { case AS_thinking: { diff --git a/server/gameserver/collision.cc b/server/gameserver/collision.cc index 6b0d03b..bd71195 100644 --- a/server/gameserver/collision.cc +++ b/server/gameserver/collision.cc @@ -108,3 +108,8 @@ bool IntersectCircleCircle(Vector2D a_pos, float a_rad, Vector2D b_pos, float b_ float n = a8::LengthSqr(d); return n < t*t; } + +bool CircleContainCircle(Vector2D a_pos, float a_rad, Vector2D b_pos, float b_rad) +{ + return false; +} diff --git a/server/gameserver/collision.h b/server/gameserver/collision.h index 9833694..832106b 100644 --- a/server/gameserver/collision.h +++ b/server/gameserver/collision.h @@ -5,4 +5,5 @@ bool IntersectSegmentAabb(Vector2D p0, Vector2D p1, Vector2D _min, Vector2D _max bool IntersectAabbCircle(Vector2D a_min, Vector2D a_max, Vector2D b_pos, float b_rad); bool IntersectAabbAabb(Vector2D a_min, Vector2D a_max, Vector2D b_min, Vector2D b_max); bool IntersectCircleCircle(Vector2D a_pos, float a_rad, Vector2D b_pos, float b_rad); +bool CircleContainCircle(Vector2D a_pos, float a_rad, Vector2D b_pos, float b_rad); void TestGlm(); diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 0053c02..2c6961c 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -205,3 +205,28 @@ float Human::GetRadius() { return meta->i->radius(); } + +void Human::UpdatePoisoning() +{ + if (dead) { + return; + } + bool need_notify = poisoning_time > 1000; + while (poisoning_time > 1000) { + if (room->gas_data.is_last_gas) { + health = std::max(0.0f, health - room->gas_data.new_area_meta->i->hurt()); + } else { + health = std::max(0.0f, health - room->gas_data.old_area_meta->i->hurt()); + } + if (health <= 0.0f) { + dead = true; + downed = true; + poisoning_time = 0; + break; + } + poisoning_time -= 1000; + } + if (need_notify && entity_subtype != EST_Player) { + this->new_objects.insert(this); + } +} diff --git a/server/gameserver/human.h b/server/gameserver/human.h index 00e74e3..9b966fb 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -43,6 +43,8 @@ class Human : public Entity int energy_shield = 0; int vip = 0; int sdmg = 0; + bool poisoning = false; + long long poisoning_time = 0; HumanFrameData frame_data; @@ -63,6 +65,7 @@ class Human : public Entity ColliderComponent* GetFirstCollision(); void FindPath(); float GetRadius(); + void UpdatePoisoning(); private: CircleCollider* self_collider_ = nullptr; diff --git a/server/gameserver/player.cc b/server/gameserver/player.cc index 93b9f2b..0c1f613 100644 --- a/server/gameserver/player.cc +++ b/server/gameserver/player.cc @@ -56,6 +56,9 @@ void Player::Initialize() void Player::Update(int delta_time) { + if (poisoning) { + poisoning_time += delta_time; + } movement->Update(delta_time); if (moving) { UpdateMove(); @@ -67,6 +70,9 @@ void Player::Update(int delta_time) if (interaction_objids.size() > 0) { ProcInteraction(); } + if (poisoning) { + UpdatePoisoning(); + } MakeUpdateMsg(); SendNotifyMsg(*update_msg); { diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index 25cc1f3..00e9479 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -12,6 +12,7 @@ #include "obstacle.h" #include "building.h" #include "loot.h" +#include "collision.h" const int ROOM_MAX_PLAYER_NUM = 50; const int ANDROID_NUM = 0; @@ -509,9 +510,27 @@ void Room::UpdateGas() } break; } - if (gas_data.gas_mode == GasInactive) { + if (gas_data.gas_mode != GasInactive) { for (auto& pair : human_hash_) { - + if (pair.second->dead) { + continue; + } + if (!CircleContainCircle(gas_data.pos_old, + gas_data.rad_old, + pair.second->pos, + pair.second->GetRadius() + ) && + !CircleContainCircle(gas_data.pos_new, + gas_data.rad_new, + pair.second->pos, + pair.second->GetRadius() + ) + ) { + pair.second->poisoning = true; + } else { + pair.second->poisoning = false; + pair.second->poisoning_time = false; + } } } }