2018-03-29 17:01:57 -04:00
|
|
|
|
2019-07-07 20:56:15 +00:00
|
|
|
#include <StdAfx.h>
|
2018-03-29 17:01:57 -04:00
|
|
|
#include "Corpse.h"
|
|
|
|
|
#include "DatabaseIO.h"
|
|
|
|
|
#include "WorldLandBlock.h"
|
|
|
|
|
|
2018-07-12 14:41:21 -07:00
|
|
|
#define CORPSE_EXIST_TIME 180
|
2018-06-26 19:48:05 +01:00
|
|
|
|
2018-03-29 17:01:57 -04:00
|
|
|
CCorpseWeenie::CCorpseWeenie()
|
|
|
|
|
{
|
2018-06-26 19:48:05 +01:00
|
|
|
_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)
|
|
|
|
|
{
|
2019-07-07 20:56:15 +00:00
|
|
|
uint32_t killerId = InqIIDQuality(KILLER_IID, 0);
|
|
|
|
|
uint32_t victimId = InqIIDQuality(VICTIM_IID, 0);
|
2018-07-15 07:19:29 -07:00
|
|
|
if (killerId == looter->GetID() || victimId == looter->GetID())
|
2018-06-26 19:48:05 +01:00
|
|
|
return WERROR_NONE;
|
2018-07-04 00:39:52 -05:00
|
|
|
|
2018-07-28 16:55:02 +01:00
|
|
|
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-06-26 19:48:05 +01:00
|
|
|
{
|
2018-07-15 07:19:29 -07:00
|
|
|
if (!corpsePlayer->m_umCorpsePermissions.empty()) // if the corpse owner has players on their permissions list
|
2018-06-26 19:48:05 +01:00
|
|
|
{
|
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-06-26 19:48:05 +01:00
|
|
|
{
|
2018-07-15 07:19:29 -07:00
|
|
|
corpsePlayer->RemoveCorpsePermission(looterAsPlayer);
|
|
|
|
|
looterAsPlayer->RemoveConsent(corpsePlayer);
|
2018-06-27 20:27:12 +01:00
|
|
|
return WERROR_NONE;
|
2018-06-26 19:48:05 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-07-11 04:53:32 +00:00
|
|
|
|
2019-09-03 14:18:02 +00:00
|
|
|
fellowship_ptr_t fellowship = looter->GetFellowship();
|
|
|
|
|
if (fellowship)
|
2018-07-11 04:53:32 +00:00
|
|
|
{
|
2019-05-31 14:04:29 -07:00
|
|
|
if (corpsePlayer != looterAsPlayer && m_Qualities.GetBool(CORPSE_GENERATED_RARE_BOOL, 0))
|
|
|
|
|
{
|
|
|
|
|
looter->SendText("You do not have permission to loot that corpse!", LTT_ERROR);
|
|
|
|
|
return WERROR_FROZEN;
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
{
|
2019-09-03 14:18:02 +00:00
|
|
|
if (killerId == entry.first && entry.second._share_loot)
|
2018-07-15 07:19:29 -07:00
|
|
|
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-05-05 22:44:34 +01: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)
|
|
|
|
|
{
|
2019-02-26 21:05:30 +00:00
|
|
|
if (_shouldSave)
|
|
|
|
|
{
|
|
|
|
|
m_Qualities.SetFloat(TIME_TO_ROT_FLOAT, _begin_destroy_at - Timer::cur_time);
|
|
|
|
|
CContainerWeenie::SaveEx(save);
|
2018-03-29 17:01:57 -04:00
|
|
|
|
2019-02-26 21:05:30 +00:00
|
|
|
save.m_ObjDesc = _objDesc;
|
2018-03-29 17:01:57 -04:00
|
|
|
|
2019-02-26 21:05:30 +00:00
|
|
|
g_pDBIO->AddOrUpdateWeenieToBlock(GetID(), m_Position.objcell_id >> 16);
|
|
|
|
|
}
|
2018-03-29 17:01:57 -04:00
|
|
|
}
|
|
|
|
|
|
2018-05-10 06:21:14 +00:00
|
|
|
void CCorpseWeenie::RemoveEx()
|
|
|
|
|
{
|
|
|
|
|
g_pDBIO->RemoveWeenieFromBlock(GetID());
|
2019-02-02 21:26:21 -08:00
|
|
|
g_pDBIO->DeleteWeenie(GetID());
|
2018-05-10 06:21:14 +00:00
|
|
|
}
|
|
|
|
|
|
2018-03-29 17:01:57 -04:00
|
|
|
void CCorpseWeenie::LoadEx(class CWeenieSave &save)
|
|
|
|
|
{
|
|
|
|
|
CContainerWeenie::LoadEx(save);
|
|
|
|
|
|
|
|
|
|
_objDesc = save.m_ObjDesc;
|
2019-02-02 21:26:21 -08:00
|
|
|
double dbTimeToRot = m_Qualities.GetFloat(TIME_TO_ROT_FLOAT, 0.0);
|
2019-02-18 00:07:53 -08:00
|
|
|
_begin_destroy_at = Timer::cur_time + (dbTimeToRot == 0 ? 60 * 60 : dbTimeToRot);
|
2018-03-29 17:01:57 -04:00
|
|
|
_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), ¶ms, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CCorpseWeenie::ShouldSave()
|
|
|
|
|
{
|
|
|
|
|
return _shouldSave;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CCorpseWeenie::Tick()
|
|
|
|
|
{
|
|
|
|
|
CContainerWeenie::Tick();
|
|
|
|
|
|
2019-06-12 04:15:28 +00:00
|
|
|
if (!m_Items.size())
|
|
|
|
|
BeginGracefulDestroy();
|
|
|
|
|
|
2019-07-12 04:09:01 +00:00
|
|
|
if (!_openedById && ContainsDecayableItems() && _begin_destroy_at > Timer::cur_time + 60.0 * 5 * 50)
|
2019-06-12 04:15:28 +00:00
|
|
|
BeginGracefulDestroy();
|
|
|
|
|
|
2019-07-12 04:09:01 +00:00
|
|
|
if (_hasBeenOpened && !_openedById && ContainsDecayableItems())
|
2019-06-12 04:15:28 +00:00
|
|
|
BeginGracefulDestroy();
|
|
|
|
|
|
2018-03-29 17:01:57 -04:00
|
|
|
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);
|
2019-08-22 21:28:18 +00:00
|
|
|
if (_shouldSave)
|
|
|
|
|
{
|
|
|
|
|
for (auto drop : m_Items)
|
|
|
|
|
{
|
|
|
|
|
drop->ReleaseFromAnyWeenieParent(false, true);
|
|
|
|
|
drop->SetWeenieContainer(0);
|
|
|
|
|
drop->SetWielderID(0);
|
|
|
|
|
drop->SetWieldedLocation(INVENTORY_LOC::NONE_LOC);
|
|
|
|
|
drop->_timeToRot = Timer::cur_time + 300.0;
|
|
|
|
|
drop->_beganRot = false;
|
|
|
|
|
drop->m_Qualities.SetFloat(TIME_TO_ROT_FLOAT, drop->_timeToRot);
|
|
|
|
|
drop->m_Qualities.SetInt(PARENT_LOCATION_INT, 0);
|
|
|
|
|
drop->unset_parent();
|
|
|
|
|
drop->enter_world(&m_Position);
|
|
|
|
|
|
|
|
|
|
if (!drop->m_Qualities.m_PositionStats)
|
|
|
|
|
drop->m_Qualities.SetPosition(LOCATION_POSITION, m_Position);
|
|
|
|
|
|
|
|
|
|
drop->SetPlacementFrame(0x65, FALSE);
|
|
|
|
|
g_pWorld->InsertEntity(drop);
|
|
|
|
|
drop->Movement_Teleport(GetPosition());
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-03-29 17:01:57 -04:00
|
|
|
|
|
|
|
|
_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;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-12 04:09:01 +00:00
|
|
|
bool CCorpseWeenie::ContainsDecayableItems()
|
2019-06-12 04:15:28 +00:00
|
|
|
{
|
2019-07-12 04:09:01 +00:00
|
|
|
bool autoDecay = true;
|
2019-06-12 04:15:28 +00:00
|
|
|
|
|
|
|
|
for( auto ii : m_Items)
|
|
|
|
|
{
|
2019-07-12 04:09:01 +00:00
|
|
|
if (ii->m_Qualities.m_WeenieType == Coin_WeenieType || ii->m_Qualities.m_WeenieType == Healer_WeenieType || ii->m_Qualities.m_WeenieType == SpellComponent_WeenieType)
|
2019-06-12 04:15:28 +00:00
|
|
|
{
|
2019-07-12 04:09:01 +00:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
autoDecay = false;
|
2019-06-12 04:15:28 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-12 04:09:01 +00:00
|
|
|
return autoDecay;
|
2019-06-12 04:15:28 +00:00
|
|
|
}
|
2018-03-29 17:01:57 -04:00
|
|
|
|
2019-07-12 04:09:01 +00:00
|
|
|
|
|
|
|
|
|