Skip to content

Commit

Permalink
[Feature/Enhancement] - No disconnect on death (#147)
Browse files Browse the repository at this point in the history
no more disconnection when player dies
  • Loading branch information
omeranha authored Mar 21, 2022
1 parent b79a612 commit 4f8667a
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 32 deletions.
8 changes: 1 addition & 7 deletions data/scripts/creaturescripts/player_death.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ local deathListEnabled = true
local maxDeathRecords = 5

function playerDeath.onDeath(player, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified)
local playerId = player:getId()
if nextUseStaminaTime[playerId] then
nextUseStaminaTime[playerId] = nil
end

player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are dead.")
if not deathListEnabled then
return
end
Expand Down Expand Up @@ -74,7 +68,7 @@ function playerDeath.onDeath(player, corpse, killer, mostDamageKiller, unjustifi
if targetGuild ~= 0 then
local killerGuild = killer:getGuild()
killerGuild = killerGuild and killerGuild:getId() or 0
if killerGuild ~= 0 and targetGuild ~= killerGuild and isInWar(playerId, killer:getId()) then
if killerGuild ~= 0 and targetGuild ~= killerGuild and isInWar(player:getId(), killer:getId()) then
local warId = false
resultId = db.storeQuery("SELECT `id` FROM `guild_wars` WHERE `status` = 1 AND ((`guild1` = " .. killerGuild .. " AND `guild2` = " .. targetGuild .. ") OR (`guild1` = " .. targetGuild .. " AND `guild2` = " .. killerGuild .. "))")
if resultId ~= false then
Expand Down
8 changes: 4 additions & 4 deletions src/creatures/creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -679,12 +679,12 @@ void Creature::onDeath()
bool droppedCorpse = dropCorpse(lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified);
death(lastHitCreature);

if (master) {
setMaster(nullptr);
if (droppedCorpse && !getPlayer()) {
g_game.removeCreature(this, false);
}

if (droppedCorpse) {
g_game.removeCreature(this, false);
if (master) {
removeMaster();
}
}

Expand Down
175 changes: 162 additions & 13 deletions src/creatures/players/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1494,7 +1494,9 @@ void Player::onCreatureAppear(Creature* creature, bool isLogin)
bed->wakeUp(this);
}

SPDLOG_INFO("{} has logged in", name);
if (isLogin) {
SPDLOG_INFO("{} has logged in", name);
}

if (guild) {
guild->addMember(this);
Expand Down Expand Up @@ -1598,6 +1600,9 @@ void Player::onRemoveCreature(Creature* creature, bool isLogout)
if (creature == this) {
if (isLogout) {
loginPosition = getPosition();
SPDLOG_INFO("{} has logged out", getName());
g_chat->removeUserFromAllChannels(*this);
clearPartyInvitations();
}

lastLogout = time(nullptr);
Expand All @@ -1612,17 +1617,11 @@ void Player::onRemoveCreature(Creature* creature, bool isLogout)

closeShopWindow();

clearPartyInvitations();

if (party) {
if (party && isLogout) {
party->leaveParty(this);
}

g_chat->removeUserFromAllChannels(*this);

SPDLOG_INFO("{} has logged out", getName());

if (guild) {
if (guild && isLogout) {
guild->removeMember(this);
}

Expand Down Expand Up @@ -2492,7 +2491,7 @@ void Player::death(Creature* lastHitCreature)
if (charmRuneBless != 0) {
MonsterType* mType = g_monsters.getMonsterType(lastHitCreature->getName());
if (mType && mType->info.raceid == charmRuneBless) {
deathLossPercent = (deathLossPercent * 90) / 100;
deathLossPercent = (deathLossPercent * 90) / 100;
}
}
}
Expand All @@ -2514,6 +2513,14 @@ void Player::death(Creature* lastHitCreature)
magLevelPercent = 0;
}

//Level loss
uint64_t expLoss = static_cast<uint64_t>(experience * deathLossPercent);
g_events->eventPlayerOnLoseExperience(this, expLoss);

sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are dead.");
std::ostringstream lostExp;
lostExp << "You lost " << expLoss << " experience.";

//Skill loss
for (uint8_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) { //for each skill
uint64_t sumSkillTries = 0;
Expand Down Expand Up @@ -2542,9 +2549,7 @@ void Player::death(Creature* lastHitCreature)
skills[i].percent = Player::getPercentLevel(skills[i].tries, vocation->getReqSkillTries(i, skills[i].level));
}

//Level loss
uint64_t expLoss = static_cast<uint64_t>(experience * deathLossPercent);
g_events->eventPlayerOnLoseExperience(this, expLoss);
sendTextMessage(MESSAGE_EVENT_ADVANCE, lostExp.str());

if (expLoss != 0) {
uint32_t oldLevel = level;
Expand Down Expand Up @@ -2575,6 +2580,24 @@ void Player::death(Creature* lastHitCreature)
}
}

std::ostringstream deathType;
deathType << "You died during ";
if (pvpDeath) {
deathType << "PvP.";
} else {
deathType << "PvE.";
}
sendTextMessage(MESSAGE_EVENT_ADVANCE, deathType.str());

std::string bless = getBlessingsName();
std::ostringstream blesses;
if (bless.length() == 0) {
blesses << "You weren't protected with any blessings.";
} else {
blesses << "You were blessed with " << bless;
}
sendTextMessage(MESSAGE_EVENT_ADVANCE, blesses.str());

//Make player lose bless
uint8_t maxBlessing = 8;
if (pvpDeath && hasBlessing(1)) {
Expand All @@ -2585,6 +2608,14 @@ void Player::death(Creature* lastHitCreature)
}
}

std::ostringstream lostBlesses;
if (bless.length() == 0) {
lostBlesses << "You lost all your blesses.";
} else {
lostBlesses << "You are still blessed with " << bless;
}
sendTextMessage(MESSAGE_EVENT_ADVANCE, lostBlesses.str());

sendStats();
sendSkills();
sendReLoginWindow(unfairFightReduction);
Expand Down Expand Up @@ -2635,6 +2666,91 @@ void Player::death(Creature* lastHitCreature)
onIdleStatus();
sendStats();
}
despawn();
}

bool Player::spawn()
{
setDead(false);

const Position& pos = getLoginPosition();

if (!g_game.map.placeCreature(pos, this, false, true)) {
return false;
}

SpectatorHashSet spectators;
g_game.map.getSpectators(spectators, position, false, true);
for (Creature* spectator : spectators) {
if (!spectator) {
continue;
}

if (Player* tmpPlayer = spectator->getPlayer()) {
tmpPlayer->sendCreatureAppear(this, pos, true);
}

spectator->onCreatureAppear(this, false);
}

getParent()->postAddNotification(this, nullptr, 0);
g_game.addCreatureCheck(this);

addList();
return true;
}

void Player::despawn()
{
if (isDead()) {
return;
}

listWalkDir.clear();
stopEventWalk();
onWalkAborted();

// remove check
Game::removeCreatureCheck(this);

// remove from map
Tile* tile = getTile();
if (!tile) {
return;
}

std::vector<int32_t> oldStackPosVector;

SpectatorHashSet spectators;
g_game.map.getSpectators(spectators, tile->getPosition(), true);
size_t i = 0;
for (Creature* spectator : spectators) {
if (!spectator) {
continue;
}

if (const Player* player = spectator->getPlayer()) {
oldStackPosVector.push_back(player->canSeeCreature(this) ? tile->getStackposOfCreature(player, this) : -1);
}
if (Player* player = spectator->getPlayer()) {
player->sendRemoveTileThing(tile->getPosition(), oldStackPosVector[i++]);
}

spectator->onRemoveCreature(this, false);
}

tile->removeCreature(this);

getParent()->postRemoveNotification(this, nullptr, 0);

g_game.removePlayer(this);

// show player as pending
for (const auto& [key, player] : g_game.getPlayers()) {
player->notifyStatusChange(this, VIPSTATUS_PENDING, false);
}

setDead(true);
}

bool Player::dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreature, bool lastHitUnjustified, bool mostDamageUnjustified)
Expand Down Expand Up @@ -5658,6 +5774,39 @@ void Player::openPlayerContainers()
}
}

std::string Player::getBlessingsName() const
{
uint8_t count = 0;
std::for_each(blessings.begin(), blessings.end(), [&count](uint8_t amount) {
if (amount != 0) {
count++;
}
});

std::ostringstream os;
for (uint8_t i = 1; i <= 8; i++) {
if (hasBlessing(i)) {
if (auto blessName = BlessingNames.find(static_cast<Blessings_t>(i));
blessName != BlessingNames.end()) {
os << (*blessName).second;
} else {
continue;
}

--count;
if (count > 1) {
os << ", ";
} else if (count == 1) {
os << " and ";
} else {
os << ".";
}
}
}

return os.str();
}

/*******************************************************************************
* Interfaces
******************************************************************************/
Expand Down
11 changes: 11 additions & 0 deletions src/creatures/players/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ class Player final : public Creature, public Cylinder
uint8_t getBlessingCount(uint8_t index) const {
return blessings[index - 1];
}
std::string getBlessingsName() const;

bool isOffline() const {
return (getID() == 0);
Expand Down Expand Up @@ -1911,6 +1912,8 @@ class Player final : public Creature, public Cylinder
void setNextPotionActionTask(SchedulerTask* task);

void death(Creature* lastHitCreature) override;
bool spawn();
void despawn();
bool dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreature,
bool lastHitUnjustified, bool mostDamageUnjustified) override;
Item* getCorpse(Creature* lastHitCreature, Creature* mostDamageCreature) override;
Expand Down Expand Up @@ -2155,6 +2158,7 @@ class Player final : public Creature, public Cylinder
bool marketMenu = false; // Menu option 'show in market'
bool exerciseTraining = false;
bool moved = false;
bool dead = false;

static uint32_t playerAutoID;

Expand Down Expand Up @@ -2193,6 +2197,13 @@ class Player final : public Creature, public Cylinder
uint16_t getLookCorpse() const override;
void getPathSearchParams(const Creature* creature, FindPathParams& fpp) const override;

void setDead(bool isDead) {
dead = isDead;
}
bool isDead() const {
return dead;
}

friend class Game;
friend class Npc;
friend class PlayerFunctions;
Expand Down
40 changes: 32 additions & 8 deletions src/server/network/protocol/protocolgame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ void ProtocolGame::connect(uint32_t playerId, OperatingSystem_t operatingSystem)

player->client = getThis();
player->openPlayerContainers();
sendAddCreature(player, player->getPosition(), 0, false);
sendAddCreature(player, player->getPosition(), 0, true);
player->lastIP = player->getIP();
player->lastLoginSaved = std::max<time_t>(time(nullptr), player->lastLoginSaved + 1);
acceptPackets = true;
Expand Down Expand Up @@ -427,7 +427,7 @@ void ProtocolGame::logout(bool displayEffect, bool forced)

sendSessionEndInformation(forced ? SESSION_END_FORCECLOSE : SESSION_END_LOGOUT);

g_game.removeCreature(player);
g_game.removeCreature(player, true);
}

void ProtocolGame::onRecvFirstMessage(NetworkMessage &msg)
Expand Down Expand Up @@ -602,16 +602,40 @@ void ProtocolGame::parsePacket(NetworkMessage& msg)

uint8_t recvbyte = msg.getByte();

// A dead player can not perform actions
if (!player || player->isRemoved() || player->getHealth() <= 0) {
if (!player || player->isRemoved()) {
if (recvbyte == 0x0F) {
// we need to make the player pointer != null in this part, game.cpp release is the first step
// login(player->getName(), player->getAccount(), player->operatingSystem);
disconnect();
}

return;
}

//a dead player can not performs actions
if (player->isDead() || player->getHealth() <= 0) {
if (recvbyte == 0x14) {
disconnect();
return;
}

if (recvbyte == 0x0F) {
if (!player) {
return;
}

if (!player->spawn()) {
disconnect();
g_game.removeCreature(player);
return;
}

sendAddCreature(player, player->getPosition(), 0, false);
return;
}

if (recvbyte != 0x14) {
if (recvbyte != 0x1D && recvbyte != 0x1E) {
// keep the connection alive
g_scheduler.addEvent(createSchedulerTask(500, std::bind(&ProtocolGame::sendPing, getThis())));
g_scheduler.addEvent(createSchedulerTask(1000, std::bind(&ProtocolGame::sendPingBack, getThis())));
return;
}
}
Expand All @@ -621,7 +645,7 @@ void ProtocolGame::parsePacket(NetworkMessage& msg)
g_dispatcher.addTask(createTask(std::bind(&Modules::executeOnRecvbyte, g_modules, player->getID(), msg, recvbyte)));
}

g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::parsePacketFromDispatcher, getThis(), msg, recvbyte)));
g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::parsePacketFromDispatcher, getThis(), msg, recvbyte)));
}

void ProtocolGame::parsePacketFromDispatcher(NetworkMessage msg, uint8_t recvbyte)
Expand Down
Loading

0 comments on commit 4f8667a

Please sign in to comment.