diff --git a/server/gameserver/constant.h b/server/gameserver/constant.h index c0fd1e3..1991e14 100755 --- a/server/gameserver/constant.h +++ b/server/gameserver/constant.h @@ -103,6 +103,7 @@ const int DEF_WEAPON_ID = 12103; const int GAS_INACTIVE_TIME = 30; const int SERVER_FRAME_RATE = 20; const int SYNC_FRAME_RATE = 10; +const float FRAME_RATE_MS = 1000.0f / SERVER_FRAME_RATE; const int MAX_INVENTORY_NUM = 17; const int MAX_WEAPON_NUM = 5; diff --git a/server/gameserver/human.h b/server/gameserver/human.h index dea7ee0..22f2d48 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -9,6 +9,12 @@ namespace MetaData struct Equip; } +enum HumanStatus +{ + HS_PainKiller = 1, +}; + +struct xtimer_list; class CircleCollider; class Obstacle; class Human : public Entity @@ -48,6 +54,7 @@ class Human : public Entity long long poisoning_time = 0; long long dead_frameno = 0; long long join_frameno = 0; + int status = 0; Weapon default_weapon; std::vector weapons; @@ -63,6 +70,9 @@ class Human : public Entity bool send_gameover = false; + int pain_killer_frameno = 0; + xtimer_list* pain_killer_timer = nullptr; + Human(); virtual ~Human() override; virtual void Initialize() override; diff --git a/server/gameserver/player.cc b/server/gameserver/player.cc index 88b4c79..d4a3dee 100644 --- a/server/gameserver/player.cc +++ b/server/gameserver/player.cc @@ -204,15 +204,33 @@ void Player::UpdateAction() case IS_PAIN_KILLER: { MetaData::Equip* item_meta = MetaMgr::Instance()->GetEquipBySlotId(action_item_id); - if (item_meta){ + if (item_meta && !pain_killer_timer){ if (inventory[item_meta->i->_inventory_slot()] > 0) { - float old_health = health; - health += item_meta->i->heal(); - health = std::min(health, GetMaxHP()); - stats.heal_amount += health - old_health; + pain_killer_frameno = room->frame_no; + pain_killer_timer = room->xtimer.AddRepeatTimerAndAttach( + SERVER_FRAME_RATE, + a8::XParams() + .SetSender(this) + .SetParam1(item_meta->i->heal()) + .SetParam2(item_meta->i->time()) + .SetParam3(0), + [] (const a8::XParams& param) + { + Human* hum = (Human*)param.sender.GetUserData(); + float old_health = hum->health; + hum->health += param.param2.GetDouble(); + hum->health = std::min(hum->health, hum->GetMaxHP()); + hum->stats.heal_amount += hum->health - old_health; + hum->SyncAroundPlayers(); + if (hum->room->frame_no - hum->pain_killer_frameno > param.param2.GetInt() * SERVER_FRAME_RATE) { + hum->room->xtimer.DeleteTimer(hum->pain_killer_timer); + hum->pain_killer_timer = nullptr; + } + }, + &xtimer_attacher.timer_list_ + ); --inventory[item_meta->i->_inventory_slot()]; need_sync_active_player = true; - SyncAroundPlayers(); } } }