gdle/Source/Corpse.cpp

206 lines
4.3 KiB
C++
Raw Permalink Normal View History

2018-03-29 17:01:57 -04:00
#include "StdAfx.h"
#include "Corpse.h"
#include "DatabaseIO.h"
#include "WorldLandBlock.h"
2018-07-12 14:41:21 -07:00
#define CORPSE_EXIST_TIME 180
2018-03-29 17:01:57 -04:00
CCorpseWeenie::CCorpseWeenie()
{
_begin_destroy_at = Timer::cur_time + CORPSE_EXIST_TIME;
2018-03-29 17:01:57 -04:00
}
CCorpseWeenie::~CCorpseWeenie()
{
}
void CCorpseWeenie::ApplyQualityOverrides()
{
CContainerWeenie::ApplyQualityOverrides();
}
void CCorpseWeenie::SetObjDesc(const ObjDesc &desc)
{
_objDesc = desc;
}
void CCorpseWeenie::GetObjDesc(ObjDesc &desc)
{
desc = _objDesc;
}
2018-07-15 07:19:29 -07:00
int CCorpseWeenie::CheckOpenContainer(CWeenieObject *looter)
2018-03-29 17:01:57 -04:00
{
2018-07-15 07:19:29 -07:00
int error = CContainerWeenie::CheckOpenContainer(looter);
2018-03-29 17:01:57 -04:00
if (error != WERROR_NONE)
return error;
if (_begun_destroy)
return WERROR_OBJECT_GONE;
if (!_hasBeenOpened)
{
DWORD killerId = InqIIDQuality(KILLER_IID, 0);
DWORD victimId = InqIIDQuality(VICTIM_IID, 0);
2018-07-15 07:19:29 -07:00
if (killerId == looter->GetID() || victimId == looter->GetID())
return WERROR_NONE;
CPlayerWeenie *corpsePlayer = g_pWorld->FindPlayer(victimId);
if (!corpsePlayer && _begin_destroy_at - (CORPSE_EXIST_TIME / 2) <= Timer::cur_time) // corpse isn't of a player so allow it to open after a certain time
2018-07-11 04:53:32 +00:00
{
return WERROR_NONE;
}
2018-07-12 14:41:21 -07:00
2018-07-15 07:19:29 -07:00
CPlayerWeenie *looterAsPlayer = looter->AsPlayer();
2018-07-12 14:41:21 -07:00
bool killedByPK = m_Qualities.GetBool(PK_KILLER_BOOL, 0);
2018-07-15 07:19:29 -07:00
if (corpsePlayer && !killedByPK && looterAsPlayer) // Make sure we're both players & don't let corpse permissions work on PK kills
{
2018-07-15 07:19:29 -07:00
if (!corpsePlayer->m_umCorpsePermissions.empty()) // if the corpse owner has players on their permissions list
{
2018-07-15 07:19:29 -07:00
if (!corpsePlayer->HasPermission(looterAsPlayer))
2018-07-11 04:53:32 +00:00
{
2018-07-15 07:19:29 -07:00
looter->SendText("You do not have permission to loot that corpse!", LTT_ERROR);
2018-07-11 04:53:32 +00:00
return WERROR_FROZEN;
}
else
{
2018-07-15 07:19:29 -07:00
corpsePlayer->RemoveCorpsePermission(looterAsPlayer);
looterAsPlayer->RemoveConsent(corpsePlayer);
return WERROR_NONE;
}
}
}
2018-07-11 04:53:32 +00:00
2018-07-15 07:19:29 -07:00
if (Fellowship *fellowship = looter->GetFellowship())
2018-07-11 04:53:32 +00:00
{
2018-07-15 07:19:29 -07:00
if (!killedByPK)
2018-07-12 14:41:21 -07:00
{
2018-07-15 07:19:29 -07:00
if (fellowship->_share_loot)
2018-07-12 14:41:21 -07:00
{
2018-07-15 07:19:29 -07:00
for (auto &entry : fellowship->_fellowship_table)
2018-07-12 14:41:21 -07:00
{
2018-07-15 07:19:29 -07:00
if (killerId == entry.first)
return WERROR_NONE;
2018-07-12 14:41:21 -07:00
}
}
}
}
2018-07-15 07:19:29 -07:00
if (corpsePlayer != looterAsPlayer)
{
looter->SendText("You do not have permission to loot that corpse!", LTT_ERROR);
return WERROR_FROZEN;
}
2018-07-12 14:41:21 -07:00
2018-07-15 07:19:29 -07:00
if (corpsePlayer)
2018-03-29 17:01:57 -04:00
{
2018-07-15 07:19:29 -07:00
return WERROR_NONE;
2018-03-29 17:01:57 -04:00
}
2018-07-15 07:19:29 -07:00
looter->SendText("You do not have permission to loot that corpse!", LTT_ERROR);
return WERROR_FROZEN;
2018-03-29 17:01:57 -04:00
}
2018-07-11 04:53:32 +00:00
return WERROR_NONE;
2018-03-29 17:01:57 -04:00
}
2018-07-12 14:41:21 -07:00
void CCorpseWeenie::OnContainerOpened(CWeenieObject *other)
2018-03-29 17:01:57 -04:00
{
CContainerWeenie::OnContainerOpened(other);
_hasBeenOpened = true;
}
2018-07-12 14:41:21 -07:00
void CCorpseWeenie::OnContainerClosed(CWeenieObject *other)
2018-03-29 17:01:57 -04:00
{
CContainerWeenie::OnContainerClosed(other);
if (!m_Items.size() && !m_Packs.size())
{
BeginGracefulDestroy();
}
}
void CCorpseWeenie::SaveEx(class CWeenieSave &save)
{
m_Qualities.SetFloat(TIME_TO_ROT_FLOAT, _begin_destroy_at - Timer::cur_time);
CContainerWeenie::SaveEx(save);
save.m_ObjDesc = _objDesc;
g_pDBIO->AddOrUpdateWeenieToBlock(GetID(), m_Position.objcell_id >> 16);
}
2018-05-10 06:21:14 +00:00
void CCorpseWeenie::RemoveEx()
{
g_pDBIO->RemoveWeenieFromBlock(GetID());
}
2018-03-29 17:01:57 -04:00
void CCorpseWeenie::LoadEx(class CWeenieSave &save)
{
CContainerWeenie::LoadEx(save);
_objDesc = save.m_ObjDesc;
_begin_destroy_at = Timer::cur_time + m_Qualities.GetFloat(TIME_TO_ROT_FLOAT, 0.0);
_shouldSave = true;
m_bDontClear = true;
InitPhysicsObj();
2018-09-21 18:33:19 -05:00
//set velocity so that corpses are affected by gravity after server restarts.
_phys_obj->set_velocity(Vector(0, 0, 1.0f), 0);
2018-03-29 17:01:57 -04:00
MakeMovementManager(TRUE);
MovementParameters params;
params.autonomous = 0;
last_move_was_autonomous = false;
DoMotion(GetCommandID(17), &params, 0);
}
bool CCorpseWeenie::ShouldSave()
{
return _shouldSave;
}
void CCorpseWeenie::Tick()
{
CContainerWeenie::Tick();
if (!_begun_destroy)
{
if (!_openedById && _begin_destroy_at <= Timer::cur_time)
{
BeginGracefulDestroy();
}
}
else
{
if (_mark_for_destroy_at <= Timer::cur_time)
{
2018-07-12 14:41:21 -07:00
MarkForDestroy();
2018-03-29 17:01:57 -04:00
}
}
}
void CCorpseWeenie::BeginGracefulDestroy()
{
if (_begun_destroy)
{
return;
}
EmitEffect(PS_Destroy, 1.0f);
// TODO drop inventory items on the ground
_shouldSave = false; //we're on our way out, it's no longer necessary to save us to the database.
2018-05-10 06:21:14 +00:00
RemoveEx(); // and in fact, delete entries in the db
2018-03-29 17:01:57 -04:00
_mark_for_destroy_at = Timer::cur_time + 2.0;
_begun_destroy = true;
}