This commit is contained in:
aozhiwei 2019-04-17 11:40:26 +08:00
parent 90b64a8e97
commit 5a281bf4f1
4 changed files with 100 additions and 2 deletions

View File

@ -492,12 +492,52 @@ void Human::BeKill(int killer_id, const std::string& killer_name)
void Human::DecHP(float dec_hp, int killer_id, const std::string& killer_name)
{
auto downed_func = [] (const a8::XParams& param)
{
Human* hum = (Human*)param.sender.GetUserData();
if (!hum->downed) {
hum->room->xtimer.DeleteTimer(hum->downed_timer);
return;
}
if (hum->dead) {
return;
}
if (!hum->HasLiveTeammate()) {
hum->BeKill(param.param1, param.param2);
return;
}
int dec_hp = MetaMgr::Instance()->GetSysParamAsInt("downed_dec_hp");
hum->DecHP(dec_hp, param.param1, param.param2);
};
if (energy_shield > 0.001f) {
energy_shield = std::max(0.0f, energy_shield - dec_hp);
} else {
health = std::max(0.0f, health - dec_hp);
if (health <= 0.0001f) {
BeKill(killer_id, killer_name);
if (health <= 0.0001f && !dead) {
if (downed) {
if (downed_timer) {
room->xtimer.DeleteTimer(downed_timer);
}
downed = false;
downed_timer = nullptr;
BeKill(killer_id, killer_name);
} else {
if (HasLiveTeammate()) {
health = MetaMgr::Instance()->GetSysParamAsInt("downed_recover_hp");
downed = true;
downed_timer = room->xtimer.AddRepeatTimerAndAttach(
SERVER_FRAME_RATE,
a8::XParams()
.SetSender(this)
.SetParam1(killer_id)
.SetParam2(killer_name),
downed_func,
&xtimer_attacher.timer_list_
);
} else {
BeKill(killer_id, killer_name);
}
}
}
}
SyncAroundPlayers();
@ -522,3 +562,15 @@ void Human::RemovePartObjects(Entity* entity)
{
part_objects.erase(entity);
}
bool Human::HasLiveTeammate()
{
if (team_members) {
for (auto& hum : *team_members) {
if (!hum->dead) {
return true;
}
}
}
return false;
}

View File

@ -76,6 +76,8 @@ class Human : public Entity
int pain_killer_lastingtime = 0;
xtimer_list* pain_killer_timer = nullptr;
xtimer_list* downed_timer = nullptr;
std::set<Human*>* team_members = nullptr;
Human();
@ -109,6 +111,7 @@ class Human : public Entity
void AddToPartObjects(Entity* entity);
void RemoveNewObjects(Entity* entity);
void RemovePartObjects(Entity* entity);
bool HasLiveTeammate();
protected:
long long last_shot_frameno_ = 0;

View File

@ -82,6 +82,9 @@ void Player::Update(int delta_time)
void Player::UpdateMove()
{
if (action_type == AT_Relive) {
CancelAction();
}
++moved_frames;
if (moved_frames > 4) {
moving = false;
@ -243,6 +246,24 @@ void Player::UpdateAction()
}
}
break;
case AT_Relive:
{
Entity* entity = room->GetEntityByUniId(action_target_id);
if (entity->entity_type != ET_Player) {
return;
}
Human* hum = (Human*)entity;
if (!hum->dead && hum->downed) {
hum->health = MetaMgr::Instance()->GetSysParamAsInt("downed_relive_recover_hp");
hum->downed = false;
if (hum->downed_timer) {
room->xtimer.DeleteTimer(hum->downed_timer);
hum->downed_timer = nullptr;
}
SyncAroundPlayers();
}
}
break;
default:
{
}
@ -472,6 +493,11 @@ void Player::ProcInteraction()
LootInteraction((Loot*)entity);
}
break;
case ET_Player:
{
HumanInteraction((Human*)entity);
}
break;
default:
break;
}
@ -651,6 +677,22 @@ void Player::LootInteraction(Loot* entity)
room->AddDeletedObject(entity->entity_uniid, false);
}
void Player::HumanInteraction(Human* hum)
{
if (hum == this) {
return;
}
if (!hum->downed) {
return;
}
StartAction(
AT_Relive,
MetaMgr::Instance()->GetSysParamAsInt("downed_relive_time") * 1000,
room->frame_no,
hum->entity_uniid
);
}
void Player::SendUpdateMsg()
{
MakeUpdateMsg();

View File

@ -86,6 +86,7 @@ class Player : public Human
void ProcInteraction();
void ObstacleInteraction(Obstacle* entity);
void LootInteraction(Loot* entity);
void HumanInteraction(Human* hum);
void SendUpdateMsg();
void _CMMove(f8::MsgHdr& hdr, const cs::CMMove& msg);