mirror of
https://gitlab.com/Scribble/gdlenhanced.git
synced 2026-08-17 14:23:04 -04:00
933 lines
17 KiB
C++
933 lines
17 KiB
C++
|
|
#include "StdAfx.h"
|
|
#include "UseManager.h"
|
|
#include "WeenieObject.h"
|
|
#include "Animate.h"
|
|
#include "World.h"
|
|
#include "Container.h"
|
|
#include "Player.h"
|
|
|
|
// TODO fix memory leak with use data
|
|
|
|
CUseEventData::CUseEventData()
|
|
{
|
|
}
|
|
|
|
void CUseEventData::Update()
|
|
{
|
|
CheckTimeout();
|
|
|
|
if (_move_to && InUseRange())
|
|
{
|
|
_weenie->DoForcedMotion(Motion_Ready);
|
|
HandleMoveToDone(WERROR_NONE);
|
|
}
|
|
}
|
|
|
|
void CUseEventData::SetupUse()
|
|
{
|
|
CWeenieObject *target = GetTarget();
|
|
if (target && _max_use_distance == FLT_MAX) //change max use distance only if still the initialized value. Otherwise this has already been defined.)
|
|
{
|
|
_max_use_distance = target->InqFloatQuality(USE_RADIUS_FLOAT, 0.0);
|
|
}
|
|
|
|
_timeout = Timer::cur_time + 15.0;
|
|
}
|
|
|
|
void CUseEventData::Begin()
|
|
{
|
|
SetupUse();
|
|
|
|
if (_target_id)
|
|
{
|
|
CWeenieObject *target = GetTarget();
|
|
if (!target)
|
|
{
|
|
Cancel(WERROR_OBJECT_GONE);
|
|
return;
|
|
}
|
|
|
|
if (target->IsContained())
|
|
{
|
|
bool bInViewedContainer = false;
|
|
|
|
if (!_weenie->FindContainedItem(target->GetID()))
|
|
{
|
|
bool bInViewedContainer = false;
|
|
if (CContainerWeenie *externalContainer = target->GetWorldTopLevelContainer())
|
|
{
|
|
if (externalContainer->_openedById == _weenie->GetID())
|
|
{
|
|
bInViewedContainer = true;
|
|
}
|
|
}
|
|
|
|
if (!bInViewedContainer)
|
|
{
|
|
Cancel(WERROR_OBJECT_GONE);
|
|
return;
|
|
}
|
|
}
|
|
|
|
OnReadyToUse();
|
|
}
|
|
else
|
|
{
|
|
if (InUseRange())
|
|
{
|
|
OnReadyToUse();
|
|
}
|
|
else
|
|
{
|
|
MoveToUse();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
OnReadyToUse();
|
|
}
|
|
}
|
|
|
|
void CUseEventData::MoveToUse()
|
|
{
|
|
_move_to = true;
|
|
|
|
MovementParameters params;
|
|
params.min_distance = _max_use_distance;
|
|
params.action_stamp = ++_weenie->m_wAnimSequence;
|
|
_weenie->last_move_was_autonomous = false;
|
|
if (CWeenieObject *target = GetTarget())
|
|
{
|
|
if (target->AsPortal())
|
|
{
|
|
params.use_spheres = 0; // if we're using a portal we want to get to the center of it, not collide with it's sphere
|
|
}
|
|
}
|
|
|
|
|
|
_weenie->MoveToObject(_target_id, ¶ms);
|
|
}
|
|
|
|
void CUseEventData::CheckTimeout()
|
|
{
|
|
if (Timer::cur_time > _timeout)
|
|
{
|
|
if (_move_to)
|
|
Cancel(WERROR_MOVED_TOO_FAR);
|
|
else if (_recall_event)
|
|
{
|
|
// If you're in the max use range during a recall event, then the recall should still trigger. Otherwise you've moved too far.
|
|
if (InMoveRange())
|
|
OnUseAnimSuccess(_active_use_anim);
|
|
else
|
|
Cancel(WERROR_MOVED_TOO_FAR);
|
|
}
|
|
else
|
|
Cancel(0);
|
|
}
|
|
}
|
|
|
|
bool CUseEventData::InMoveRange()
|
|
{
|
|
return _weenie->m_Position.distance(_initial_use_position) <= _max_use_distance ? true : false;
|
|
}
|
|
|
|
void CUseEventData::SetupRecall()
|
|
{
|
|
_max_use_distance = 5.0f;
|
|
_initial_use_position = _weenie->m_Position;
|
|
_recall_event = true;
|
|
}
|
|
|
|
void CUseEventData::Cancel(DWORD error)
|
|
{
|
|
CancelMoveTo();
|
|
|
|
_manager->OnUseCancelled(error);
|
|
}
|
|
|
|
void CUseEventData::CancelMoveTo()
|
|
{
|
|
if (_move_to)
|
|
{
|
|
_weenie->cancel_moveto();
|
|
_weenie->Animation_MoveToUpdate();
|
|
|
|
_move_to = false;
|
|
}
|
|
}
|
|
|
|
double CUseEventData::DistanceToTarget()
|
|
{
|
|
if (!_target_id || _target_id == _weenie->GetID())
|
|
return 0.0;
|
|
|
|
CWeenieObject *target = GetTarget();
|
|
if (!target)
|
|
return FLT_MAX;
|
|
|
|
if (target->AsPortal())
|
|
{
|
|
return _weenie->DistanceTo(target, false);
|
|
}
|
|
|
|
|
|
return _weenie->DistanceTo(target, true);
|
|
}
|
|
|
|
double CUseEventData::HeadingDifferenceToTarget()
|
|
{
|
|
if (!_target_id || _target_id == _weenie->GetID())
|
|
return 0.0;
|
|
|
|
CWeenieObject *target = GetTarget();
|
|
if (!target)
|
|
return 0.0;
|
|
|
|
return _weenie->get_heading();
|
|
}
|
|
|
|
bool CUseEventData::InUseRange()
|
|
{
|
|
CWeenieObject *target = GetTarget();
|
|
if (target && (_weenie->IsContainedWithinViewable(target->GetID())))
|
|
return true;
|
|
|
|
if ((_max_use_distance + F_EPSILON) < DistanceToTarget())
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
CWeenieObject *CUseEventData::GetTarget()
|
|
{
|
|
return g_pWorld->FindObject(_target_id);
|
|
}
|
|
|
|
CWeenieObject *CUseEventData::GetTool()
|
|
{
|
|
return g_pWorld->FindObject(_tool_id);
|
|
}
|
|
|
|
CWeenieObject *CUseEventData::GetSourceItem()
|
|
{
|
|
return g_pWorld->FindObject(_source_item_id);
|
|
}
|
|
|
|
void CUseEventData::HandleMoveToDone(DWORD error)
|
|
{
|
|
_move_to = false;
|
|
|
|
if (error)
|
|
{
|
|
Cancel(error);
|
|
return;
|
|
}
|
|
|
|
if (!InUseRange())
|
|
{
|
|
Cancel(WERROR_TOO_FAR);
|
|
return;
|
|
}
|
|
|
|
OnReadyToUse();
|
|
}
|
|
|
|
void CUseEventData::OnMotionDone(DWORD motion, BOOL success)
|
|
{
|
|
if (_move_to || !_active_use_anim)
|
|
return;
|
|
|
|
if (motion == _active_use_anim)
|
|
{
|
|
_active_use_anim = 0;
|
|
|
|
if (success)
|
|
{
|
|
OnUseAnimSuccess(motion);
|
|
}
|
|
else
|
|
{
|
|
if(!_recall_event) // Don't cancel recall events on motion interrupts, such as jumping.
|
|
Cancel();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CUseEventData::OnUseAnimSuccess(DWORD motion)
|
|
{
|
|
Done();
|
|
}
|
|
|
|
void CUseEventData::Done(DWORD error)
|
|
{
|
|
_manager->OnUseDone(error);
|
|
}
|
|
|
|
void CUseEventData::ExecuteUseAnimation(DWORD motion, MovementParameters *params)
|
|
{
|
|
assert (!_move_to);
|
|
assert (!_active_use_anim);
|
|
|
|
if (_weenie->IsDead() || _weenie->IsInPortalSpace())
|
|
{
|
|
Cancel(WERROR_ACTIONS_LOCKED);
|
|
return;
|
|
}
|
|
|
|
_active_use_anim = motion;
|
|
|
|
DWORD error = _weenie->DoForcedMotion(motion, params);
|
|
|
|
if (error)
|
|
{
|
|
Cancel(error);
|
|
}
|
|
}
|
|
|
|
bool CUseEventData::QuestRestrictions(CWeenieObject *target)
|
|
{
|
|
std::string restriction;
|
|
if (target->m_Qualities.InqString(QUEST_RESTRICTION_STRING, restriction) && !restriction.empty()) //Allows for restrition of pickup if you are NOT flagged. (IE must have flag for use)
|
|
{
|
|
if (CPlayerWeenie *player = _weenie->AsPlayer())
|
|
{
|
|
if (!player->InqQuest(restriction.c_str()))
|
|
{
|
|
_weenie->DoForcedStopCompletely();
|
|
Cancel(WERROR_QUEST_RESRICTION_UNSOLVED); // Sends -> This item requires you to complete a specific quest before you can pick it up!
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string questString;
|
|
if (target->m_Qualities.InqString(QUEST_STRING, questString) && !questString.empty()) //Used for restriction of pickup if quest is already solved. Common use is for timer restrictions.
|
|
{
|
|
if (_weenie->InqQuest(questString.c_str()))
|
|
{
|
|
int timeTilOkay = _weenie->InqTimeUntilOkayToComplete(questString.c_str());
|
|
|
|
if (timeTilOkay > 0)
|
|
{
|
|
std::string cdTime = ("You cannot complete this quest for another " + TimeToString(timeTilOkay) + ".");
|
|
_weenie->SendText(cdTime.c_str(), LTT_DEFAULT);
|
|
}
|
|
|
|
_weenie->DoForcedStopCompletely();
|
|
Cancel(WERROR_QUEST_SOLVED_TOO_RECENTLY);
|
|
return true;
|
|
}
|
|
|
|
_weenie->StampQuest(questString.c_str());
|
|
target->m_Qualities.SetString(QUEST_STRING, "");
|
|
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CGenericUseEvent::OnReadyToUse()
|
|
{
|
|
if (_do_use_animation)
|
|
{
|
|
ExecuteUseAnimation(_do_use_animation);
|
|
}
|
|
else
|
|
{
|
|
Finish();
|
|
}
|
|
}
|
|
|
|
void CGenericUseEvent::OnUseAnimSuccess(DWORD motion)
|
|
{
|
|
Finish();
|
|
}
|
|
|
|
void CGenericUseEvent::Finish()
|
|
{
|
|
CWeenieObject *target = GetTarget();
|
|
if (!target && _target_id)
|
|
{
|
|
Cancel(WERROR_OBJECT_GONE);
|
|
return;
|
|
}
|
|
|
|
CWeenieObject *tool = GetTool();
|
|
if (!tool && _tool_id)
|
|
{
|
|
Cancel(WERROR_OBJECT_GONE);
|
|
return;
|
|
}
|
|
|
|
int error = WERROR_NONE;
|
|
|
|
if (target)
|
|
{
|
|
if (!InUseRange())
|
|
{
|
|
Cancel(WERROR_TOO_FAR);
|
|
return;
|
|
}
|
|
|
|
// Prevent items like Head of the Homunculus, Wallbound Niffis, Tursh Totem, etc. from being used in packs.
|
|
if (target->InqIntQuality(HOOK_GROUP_INT, 0))
|
|
{
|
|
Cancel(WERROR_HOOKER_NOT_USEABLE_OFF_HOOK);
|
|
return;
|
|
}
|
|
|
|
DWORD createWcid;
|
|
if (target->m_Qualities.InqDataID(USE_CREATE_ITEM_DID, createWcid))
|
|
{
|
|
CPlayerWeenie *player = g_pWorld->FindPlayer(_weenie->GetID());
|
|
if (player)
|
|
{
|
|
if (!player->SpawnInContainer(createWcid))
|
|
{
|
|
player->SendText("Not enough pack space!", LTT_ERROR);
|
|
Done(error);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (_do_use_response)
|
|
{
|
|
if (_tool_id)
|
|
{
|
|
error = tool->DoUseWithResponse(_weenie, target);
|
|
}
|
|
else
|
|
{
|
|
error = target->DoUseResponse(_weenie);
|
|
}
|
|
}
|
|
|
|
if (error == WERROR_NONE && _do_use_emote)
|
|
{
|
|
target->DoUseEmote(_weenie);
|
|
}
|
|
|
|
if (_do_use_message)
|
|
{
|
|
if (error == WERROR_NONE)
|
|
{
|
|
std::string useMessage;
|
|
if (target->m_Qualities.InqString(USE_MESSAGE_STRING, useMessage))
|
|
{
|
|
_weenie->SendText(useMessage.c_str(), LTT_MAGIC);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
std::string failMessage;
|
|
if (target->m_Qualities.InqString(ACTIVATION_FAILURE_STRING, failMessage))
|
|
{
|
|
_weenie->SendText(failMessage.c_str(), LTT_MAGIC);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Done(error);
|
|
}
|
|
|
|
void CActivationUseEvent::OnReadyToUse()
|
|
{
|
|
CWeenieObject *target = GetTarget();
|
|
if (target)
|
|
{
|
|
target->Activate(_weenie->GetID());
|
|
target->DoUseEmote(_weenie);
|
|
}
|
|
|
|
Done();
|
|
}
|
|
|
|
void CInventoryUseEvent::SetupUse()
|
|
{
|
|
_max_use_distance = 1.0;
|
|
_timeout = Timer::cur_time + 15.0;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
|
|
void CPickupInventoryUseEvent::OnReadyToUse()
|
|
{
|
|
CWeenieObject *target = GetTarget();
|
|
|
|
if (target->HasOwner()) {
|
|
|
|
if (this->_target_container_id == _weenie->GetID())
|
|
target = target->GetWorldTopLevelOwner();
|
|
else
|
|
target = g_pWorld->FindObject(this->_target_container_id);
|
|
}
|
|
|
|
float z1 = target->m_Position.frame.m_origin.z;
|
|
float z2 = _weenie->m_Position.frame.m_origin.z;
|
|
|
|
if (z1 - z2 >= 1.9)
|
|
ExecuteUseAnimation(Motion_Pickup20);
|
|
else if (z1 - z2 >= 1.4)
|
|
ExecuteUseAnimation(Motion_Pickup15);
|
|
else if (z1 - z2 >= 0.9)
|
|
ExecuteUseAnimation(Motion_Pickup10);
|
|
else
|
|
ExecuteUseAnimation(Motion_Pickup);
|
|
}
|
|
|
|
void CPickupInventoryUseEvent::OnUseAnimSuccess(DWORD motion)
|
|
{
|
|
CWeenieObject *target = GetTarget();
|
|
if (!target && _target_id)
|
|
{
|
|
Cancel(WERROR_OBJECT_GONE);
|
|
return;
|
|
}
|
|
|
|
if (!InUseRange())
|
|
{
|
|
Cancel(WERROR_TOO_FAR);
|
|
return;
|
|
}
|
|
|
|
if (QuestRestrictions(target))
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool success = _weenie->AsPlayer()->MoveItemToContainer(_source_item_id, _target_container_id, _target_slot, true);
|
|
|
|
_weenie->DoForcedStopCompletely();
|
|
|
|
if (!success)
|
|
Cancel();
|
|
else
|
|
Done();
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
|
|
void CDropInventoryUseEvent::OnReadyToUse()
|
|
{
|
|
ExecuteUseAnimation(Motion_Pickup);
|
|
}
|
|
|
|
void CDropInventoryUseEvent::OnUseAnimSuccess(DWORD motion)
|
|
{
|
|
CWeenieObject *target = GetTarget();
|
|
if (!target && _target_id)
|
|
{
|
|
Cancel(WERROR_OBJECT_GONE);
|
|
return;
|
|
}
|
|
|
|
if (!InUseRange())
|
|
{
|
|
Cancel(WERROR_TOO_FAR);
|
|
return;
|
|
}
|
|
|
|
if (target->IsAttunedOrContainsAttuned())
|
|
{
|
|
Cancel(WERROR_ATTUNED_ITEM);
|
|
return;
|
|
}
|
|
|
|
bool success = _weenie->AsPlayer()->MoveItemTo3D(_target_id, true);
|
|
|
|
_weenie->DoForcedStopCompletely();
|
|
|
|
if (!success)
|
|
Cancel();
|
|
else
|
|
Done();
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
|
|
void CMoveToWieldInventoryUseEvent::OnReadyToUse()
|
|
{
|
|
ExecuteUseAnimation(Motion_Pickup);
|
|
}
|
|
|
|
void CMoveToWieldInventoryUseEvent::OnUseAnimSuccess(DWORD motion)
|
|
{
|
|
CWeenieObject *target = GetTarget();
|
|
if (!target && _target_id)
|
|
{
|
|
Cancel(WERROR_OBJECT_GONE);
|
|
return;
|
|
}
|
|
|
|
if (!InUseRange())
|
|
{
|
|
Cancel(WERROR_TOO_FAR);
|
|
return;
|
|
}
|
|
|
|
if (QuestRestrictions(target))
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool success = _weenie->AsPlayer()->MoveItemToWield(_sourceItemId, _targetLoc, true);
|
|
|
|
_weenie->DoForcedStopCompletely();
|
|
|
|
if (!success)
|
|
Cancel();
|
|
else
|
|
Done();
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
|
|
void CStackMergeInventoryUseEvent::OnReadyToUse()
|
|
{
|
|
ExecuteUseAnimation(Motion_Pickup);
|
|
}
|
|
|
|
void CStackMergeInventoryUseEvent::OnUseAnimSuccess(DWORD motion)
|
|
{
|
|
CWeenieObject *target = GetTarget();
|
|
if (!target && _target_id)
|
|
{
|
|
Cancel(WERROR_OBJECT_GONE);
|
|
return;
|
|
}
|
|
|
|
if (!InUseRange())
|
|
{
|
|
Cancel(WERROR_TOO_FAR);
|
|
return;
|
|
}
|
|
|
|
if (QuestRestrictions(target))
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
DWORD owner = 0;
|
|
if (target->m_Qualities.InqInstanceID(OWNER_IID, owner) && owner != _weenie->GetID())
|
|
{
|
|
_weenie->NotifyInventoryFailedEvent(_sourceItemId, WERROR_OBJECT_GONE);
|
|
_weenie->DoForcedStopCompletely();
|
|
Cancel();
|
|
}
|
|
else
|
|
{
|
|
bool success = _weenie->AsPlayer()->MergeItem(_sourceItemId, _targetItemId, _amountToTransfer, true);
|
|
|
|
_weenie->DoForcedStopCompletely();
|
|
|
|
if (!success)
|
|
Cancel();
|
|
else
|
|
Done();
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
|
|
void CStackSplitToContainerInventoryUseEvent::OnReadyToUse()
|
|
{
|
|
ExecuteUseAnimation(Motion_Pickup);
|
|
}
|
|
|
|
void CStackSplitToContainerInventoryUseEvent::OnUseAnimSuccess(DWORD motion)
|
|
{
|
|
CWeenieObject *target = GetTarget();
|
|
if (!target && _target_id)
|
|
{
|
|
Cancel(WERROR_OBJECT_GONE);
|
|
return;
|
|
}
|
|
|
|
if (!InUseRange())
|
|
{
|
|
Cancel(WERROR_TOO_FAR);
|
|
return;
|
|
}
|
|
|
|
if (QuestRestrictions(target))
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool success = _weenie->AsPlayer()->SplitItemToContainer(_sourceItemId, _targetContainerId, _targetSlot, _amountToTransfer, true);
|
|
|
|
_weenie->DoForcedStopCompletely();
|
|
|
|
if (!success)
|
|
Cancel();
|
|
else
|
|
Done();
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
|
|
|
|
void CStackSplitTo3DInventoryUseEvent::OnReadyToUse()
|
|
{
|
|
ExecuteUseAnimation(Motion_Pickup);
|
|
}
|
|
|
|
void CStackSplitTo3DInventoryUseEvent::OnUseAnimSuccess(DWORD motion)
|
|
{
|
|
CWeenieObject *target = GetTarget();
|
|
if (!target && _target_id)
|
|
{
|
|
Cancel(WERROR_OBJECT_GONE);
|
|
return;
|
|
}
|
|
|
|
if (!InUseRange())
|
|
{
|
|
Cancel(WERROR_TOO_FAR);
|
|
return;
|
|
}
|
|
|
|
if (QuestRestrictions(target))
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool success = _weenie->AsPlayer()->SplitItemto3D(_sourceItemId, _amountToTransfer, true);
|
|
|
|
_weenie->DoForcedStopCompletely();
|
|
|
|
if (!success)
|
|
Cancel();
|
|
else
|
|
Done();
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
|
|
void CStackSplitToWieldInventoryUseEvent::OnReadyToUse()
|
|
{
|
|
ExecuteUseAnimation(Motion_Pickup);
|
|
}
|
|
|
|
void CStackSplitToWieldInventoryUseEvent::OnUseAnimSuccess(DWORD motion)
|
|
{
|
|
CWeenieObject *target = GetTarget();
|
|
if (!target && _target_id)
|
|
{
|
|
Cancel(WERROR_OBJECT_GONE);
|
|
return;
|
|
}
|
|
|
|
if (!InUseRange())
|
|
{
|
|
Cancel(WERROR_TOO_FAR);
|
|
return;
|
|
}
|
|
|
|
if (QuestRestrictions(target))
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool success = _weenie->AsPlayer()->SplitItemToWield(_sourceItemId, _targetLoc, _amountToTransfer, true);
|
|
|
|
_weenie->DoForcedStopCompletely();
|
|
|
|
if (!success)
|
|
Cancel();
|
|
else
|
|
Done();
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
|
|
void CGiveEvent::OnReadyToUse()
|
|
{
|
|
ExecuteUseAnimation(Motion_Ready);
|
|
}
|
|
|
|
void CGiveEvent::OnUseAnimSuccess(DWORD motion)
|
|
{
|
|
CWeenieObject *giveTarget = GetTarget();
|
|
|
|
if (giveTarget)
|
|
{
|
|
CContainerWeenie *target = giveTarget->AsContainer();
|
|
CWeenieObject *source = GetSourceItem();
|
|
if (!target || !source)
|
|
{
|
|
_weenie->NotifyInventoryFailedEvent(_source_item_id, WERROR_NONE);
|
|
return Done(WERROR_OBJECT_GONE);
|
|
}
|
|
_weenie->AsMonster()->FinishGiveItem(target, source, _transfer_amount);
|
|
Done();
|
|
}
|
|
else
|
|
{
|
|
_weenie->NotifyInventoryFailedEvent(_source_item_id, WERROR_NONE);
|
|
return Done(WERROR_OBJECT_GONE);
|
|
}
|
|
}
|
|
|
|
void CGiveEvent::Cancel(DWORD error) //This override will capture all Use_Manger/Movement Errors and tack on an inventory failed event so we don't get stuck in a busy state if our give action is cancelled.
|
|
{
|
|
CancelMoveTo();
|
|
_weenie->NotifyInventoryFailedEvent(_source_item_id, WERROR_NONE);
|
|
_manager->OnUseCancelled(error);
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
|
|
void CTradeUseEvent::OnReadyToUse()
|
|
{
|
|
ExecuteUseAnimation(Motion_Ready);
|
|
}
|
|
|
|
void CTradeUseEvent::OnUseAnimSuccess(DWORD motion)
|
|
{
|
|
CPlayerWeenie *target = GetTarget()->AsPlayer();
|
|
if (!target)
|
|
return Done(WERROR_OBJECT_GONE);
|
|
|
|
TradeManager *tm = TradeManager::RegisterTrade(_weenie->AsPlayer(), target);
|
|
|
|
_weenie->AsPlayer()->SetTradeManager(tm);
|
|
target->SetTradeManager(tm);
|
|
Done();
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
|
|
UseManager::UseManager(CWeenieObject *weenie)
|
|
{
|
|
_weenie = weenie;
|
|
}
|
|
|
|
UseManager::~UseManager()
|
|
{
|
|
SafeDelete(_useData);
|
|
SafeDelete(_cleanupData);
|
|
}
|
|
|
|
void UseManager::MarkForCleanup(CUseEventData *data)
|
|
{
|
|
if (_cleanupData && _cleanupData != data)
|
|
{
|
|
delete _cleanupData;
|
|
}
|
|
|
|
_cleanupData = data;
|
|
}
|
|
|
|
void UseManager::Cancel()
|
|
{
|
|
if (_useData)
|
|
{
|
|
_useData->Cancel();
|
|
}
|
|
}
|
|
|
|
void UseManager::OnUseCancelled(DWORD error)
|
|
{
|
|
if (_useData)
|
|
{
|
|
if (!_useData->IsInventoryEvent())
|
|
{
|
|
_weenie->NotifyUseDone(error);
|
|
}
|
|
else
|
|
{
|
|
_weenie->NotifyInventoryFailedEvent(_useData->_target_id, error);
|
|
}
|
|
|
|
MarkForCleanup(_useData);
|
|
_useData = NULL;
|
|
}
|
|
}
|
|
|
|
void UseManager::OnUseDone(DWORD error)
|
|
{
|
|
if (_useData)
|
|
{
|
|
if (!_useData->IsInventoryEvent())
|
|
{
|
|
_weenie->NotifyUseDone(error);
|
|
}
|
|
else
|
|
{
|
|
}
|
|
|
|
MarkForCleanup(_useData);
|
|
_useData = NULL;
|
|
}
|
|
}
|
|
|
|
void UseManager::Update()
|
|
{
|
|
if (_useData)
|
|
{
|
|
_useData->Update();
|
|
}
|
|
|
|
SafeDelete(_cleanupData);
|
|
}
|
|
|
|
void UseManager::OnDeath(DWORD killer_id)
|
|
{
|
|
Cancel();
|
|
}
|
|
|
|
void UseManager::HandleMoveToDone(DWORD error)
|
|
{
|
|
if (_useData)
|
|
{
|
|
_useData->HandleMoveToDone(error);
|
|
}
|
|
}
|
|
|
|
void UseManager::OnMotionDone(DWORD motion, BOOL success)
|
|
{
|
|
if (_useData)
|
|
{
|
|
_useData->OnMotionDone(motion, success);
|
|
}
|
|
}
|
|
|
|
bool UseManager::IsUsing()
|
|
{
|
|
return _useData != NULL ? true : false;
|
|
}
|
|
|
|
bool UseManager::IsMoving()
|
|
{
|
|
return IsUsing() && _useData->_move_to != 0 ? true : false;
|
|
}
|
|
|
|
void UseManager::BeginUse(CUseEventData *data)
|
|
{
|
|
if (_useData)
|
|
{
|
|
// already busy
|
|
if (!data->IsInventoryEvent())
|
|
{
|
|
_weenie->NotifyWeenieError(WERROR_ACTIONS_LOCKED);
|
|
_weenie->NotifyUseDone(0);
|
|
}
|
|
else
|
|
{
|
|
_weenie->NotifyInventoryFailedEvent(_useData->_target_id, WERROR_ACTIONS_LOCKED);
|
|
}
|
|
|
|
delete data;
|
|
return;
|
|
}
|
|
|
|
_useData = data;
|
|
_useData->Begin();
|
|
}
|
|
|