mirror of
https://bitbucket.org/theswgsource/src-1.2.git
synced 2026-10-21 11:02:58 -04:00
2193 lines
71 KiB
C++
2193 lines
71 KiB
C++
//========================================================================
|
|
//
|
|
// CreatureController.cpp
|
|
//
|
|
// copyright 2001 Sony Online Entertainment
|
|
//
|
|
//========================================================================
|
|
|
|
#include "serverGame/FirstServerGame.h"
|
|
#include "serverGame/CreatureController.h"
|
|
|
|
#include "SwgGameServer/CombatEngine.h"
|
|
#include "SwgGameServer/ConfigCombatEngine.h"
|
|
#include "serverGame/Chat.h"
|
|
#include "serverGame/ConfigServerGame.h"
|
|
#include "serverGame/ContainerInterface.h"
|
|
#include "serverGame/CreatureObject.h"
|
|
#include "serverGame/GameServer.h"
|
|
#include "serverGame/GroupObject.h"
|
|
#include "serverGame/HarvesterInstallationObject.h"
|
|
#include "serverGame/InstallationObject.h"
|
|
#include "serverGame/ObjectTracker.h"
|
|
#include "serverGame/PlayerCreatureController.h"
|
|
#include "serverGame/PlayerObject.h"
|
|
#include "serverGame/ServerSecureTrade.h"
|
|
#include "serverGame/ServerSecureTradeManager.h"
|
|
#include "serverGame/ServerUniverse.h"
|
|
#include "serverGame/ServerWeaponObjectTemplate.h"
|
|
#include "serverGame/ServerWorld.h"
|
|
#include "serverGame/ShipObject.h"
|
|
#include "serverGame/WeaponObject.h"
|
|
#include "serverNetworkMessages/MessageQueueAlterAttribute.h"
|
|
#include "serverNetworkMessages/MessageQueueCommandQueueEnqueueFwd.h"
|
|
#include "serverNetworkMessages/MessageQueueSetState.h"
|
|
#include "serverScript/GameScriptObject.h"
|
|
#include "serverScript/ScriptParameters.h"
|
|
#include "serverUtility/ServerClock.h"
|
|
#include "sharedCollision/CollisionProperty.h"
|
|
#include "sharedCollision/Footprint.h"
|
|
#include "sharedDebug/Profiler.h"
|
|
#include "sharedFoundation/GameControllerMessage.h"
|
|
#include "sharedLog/Log.h"
|
|
#include "sharedGame/CommandTable.h"
|
|
#include "sharedUtility/Location.h"
|
|
#include "sharedGame/GameObjectTypes.h"
|
|
#include "sharedGame/ProsePackage.h"
|
|
#include "sharedGame/Waypoint.h"
|
|
#include "sharedNetworkMessages/GenericValueTypeMessage.h"
|
|
#include "sharedNetworkMessages/IncubatorCommitMessage.h"
|
|
#include "sharedNetworkMessages/MessageQueueCombatCommand.h"
|
|
#include "sharedNetworkMessages/MessageQueueCommandQueueEnqueue.h"
|
|
#include "sharedNetworkMessages/MessageQueueCommandQueueRemove.h"
|
|
#include "sharedNetworkMessages/MessageQueueCyberneticsChangeRequest.h"
|
|
#include "sharedNetworkMessages/MessageQueueDataTransform.h"
|
|
#include "sharedNetworkMessages/MessageQueueDataTransformWithParent.h"
|
|
#include "sharedNetworkMessages/MessageQueueGeneric.h"
|
|
#include "sharedNetworkMessages/MessageQueueGenericIntResponse.h"
|
|
#include "sharedNetworkMessages/MessageQueueGenericResponse.h"
|
|
#include "sharedNetworkMessages/MessageQueueGenericString.h"
|
|
#include "sharedNetworkMessages/MessageQueueGenericValueType.h"
|
|
#include "sharedNetworkMessages/MessageQueueHarvesterResourceData.h"
|
|
#include "sharedNetworkMessages/MessageQueueNetworkId.h"
|
|
#include "sharedNetworkMessages/MessageQueueNetworkIdPair.h"
|
|
#include "sharedNetworkMessages/MessageQueuePosture.h"
|
|
#include "sharedNetworkMessages/MessageQueuePushCreature.h"
|
|
#include "sharedNetworkMessages/MessageQueueResourceEmptyHopper.h"
|
|
#include "sharedNetworkMessages/MessageQueueSecureTrade.h"
|
|
#include "sharedNetworkMessages/MessageQueueSitOnObject.h"
|
|
#include "sharedNetworkMessages/MessageQueueSlowDownEffect.h"
|
|
#include "sharedNetworkMessages/ObjectChannelMessages.h"
|
|
#include "sharedNetworkMessages/UpdateTransformMessage.h"
|
|
#include "sharedNetworkMessages/UpdateTransformWithParentMessage.h"
|
|
#include "sharedObject/AlterResult.h"
|
|
#include "sharedObject/CellProperty.h"
|
|
#include "sharedObject/MovementTable.h"
|
|
#include "sharedObject/NetworkIdManager.h"
|
|
#include "sharedObject/ObjectTemplateList.h"
|
|
#include "sharedSkillSystem/SkillManager.h"
|
|
#include "sharedTerrain/TerrainObject.h"
|
|
#include "sharedTerrain/WaterTypeManager.h"
|
|
#include "swgSharedNetworkMessages/MessageQueueCombatAction.h"
|
|
#include "Unicode.h"
|
|
#include "UnicodeUtils.h"
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
namespace CreatureControllerNamespace
|
|
{
|
|
template<typename ObjectType>
|
|
ObjectType & getOwner(Controller * controller)
|
|
{
|
|
NOT_NULL(controller);
|
|
NOT_NULL(controller->getOwner());
|
|
ObjectType * owner = static_cast<ObjectType *>(controller->getOwner());
|
|
return *owner;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
CreatureController::CreatureController(CreatureObject * newOwner) :
|
|
TangibleController(newOwner),
|
|
m_secureTrade(0),
|
|
m_secureTradeInitiator(0)
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
CreatureController::~CreatureController()
|
|
{
|
|
if (getHibernate())
|
|
ObjectTracker::removeHibernatingAI();
|
|
|
|
if (m_secureTrade)
|
|
m_secureTrade->cancelTrade(*getCreature());
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
void CreatureController::handleMessage (const int message, const float value, const MessageQueue::Data* const data, const uint32 flags)
|
|
{
|
|
CreatureObject * const owner = static_cast<CreatureObject*>(getOwner());
|
|
DEBUG_FATAL(!owner, ("Owner is NULL in CreatureController::handleMessage\n"));
|
|
|
|
switch(message)
|
|
{
|
|
case CM_netUpdateTransform:
|
|
{
|
|
// if the auth server sent this to us, forward it to clients
|
|
const MessageQueueDataTransform * const msg = NON_NULL (dynamic_cast<const MessageQueueDataTransform *>(data));
|
|
owner->setLookAtYaw(msg->getLookAtYaw(), msg->getUseLookAtYaw());
|
|
if (flags&GameControllerMessageFlags::SOURCE_REMOTE_SERVER)
|
|
{
|
|
// If we're not contained by what we are attached to, then transform
|
|
// updates are not relevant to clients because our position is
|
|
// dictated purely by our containing object.
|
|
if (owner->getAttachedTo() == ContainerInterface::getContainedByObject(*owner))
|
|
{
|
|
UpdateTransformMessage utm(owner->getNetworkId(), msg->getSequenceNumber(), msg->getTransform(), static_cast<int8>(msg->getSpeed()), msg->getLookAtYaw(), msg->getUseLookAtYaw());
|
|
owner->sendToClientsInUpdateRange(utm, flags & GameControllerMessageFlags::RELIABLE, false);
|
|
}
|
|
}
|
|
TangibleController::handleMessage(message, value, data, flags);
|
|
}
|
|
break;
|
|
case CM_netUpdateTransformWithParent:
|
|
{
|
|
// if the auth server sent this to us, forward it to clients
|
|
const MessageQueueDataTransformWithParent * const msg = NON_NULL (dynamic_cast<const MessageQueueDataTransformWithParent *>(data));
|
|
owner->setLookAtYaw(msg->getLookAtYaw(), msg->getUseLookAtYaw());
|
|
if (flags&GameControllerMessageFlags::SOURCE_REMOTE_SERVER)
|
|
{
|
|
// If we're not contained by what we are attached to, then transform
|
|
// updates are not relevant to clients because our position is
|
|
// dictated purely by our containing object.
|
|
if (owner->getAttachedTo() == ContainerInterface::getContainedByObject(*owner))
|
|
{
|
|
UpdateTransformWithParentMessage utm(owner->getNetworkId(), msg->getSequenceNumber(), msg->getParent(), msg->getTransform(), static_cast<int8>(msg->getSpeed()), msg->getLookAtYaw(), msg->getUseLookAtYaw());
|
|
owner->sendToClientsInUpdateRange(utm, flags & GameControllerMessageFlags::RELIABLE, false);
|
|
}
|
|
}
|
|
TangibleController::handleMessage(message, value, data, flags);
|
|
}
|
|
break;
|
|
|
|
case CM_clientResourceHarvesterActivate:
|
|
{
|
|
const MessageQueueNetworkId * const msg = NON_NULL (dynamic_cast<const MessageQueueNetworkId *>(data));
|
|
|
|
InstallationObject * const harvester = dynamic_cast<InstallationObject *>(ServerWorld::findObjectByNetworkId (msg->getNetworkId ()));
|
|
|
|
UNREF (harvester);
|
|
|
|
if (harvester && harvester->isOnAdminList(*owner))
|
|
harvester->activate (owner->getNetworkId());
|
|
}
|
|
break;
|
|
|
|
case CM_clientResourceHarvesterDeactivate:
|
|
{
|
|
const MessageQueueNetworkId * const msg = NON_NULL (dynamic_cast<const MessageQueueNetworkId *>(data));
|
|
|
|
InstallationObject * const harvester = dynamic_cast<InstallationObject *>(ServerWorld::findObjectByNetworkId (msg->getNetworkId ()));
|
|
|
|
if (harvester && harvester->isOnAdminList(*owner))
|
|
harvester->deactivate ();
|
|
}
|
|
break;
|
|
|
|
case CM_clientResourceHarvesterListen:
|
|
{
|
|
const MessageQueueNetworkId * const msg = NON_NULL (dynamic_cast<const MessageQueueNetworkId *>(data));
|
|
|
|
HarvesterInstallationObject * const harvester = dynamic_cast<HarvesterInstallationObject *>(ServerWorld::findObjectByNetworkId (msg->getNetworkId ()));
|
|
|
|
if (harvester && owner)
|
|
harvester->addSynchronizedUiClient (*owner);
|
|
}
|
|
break;
|
|
|
|
case CM_clientResourceHarvesterStopListening:
|
|
{
|
|
const MessageQueueNetworkId * const msg = NON_NULL (dynamic_cast<const MessageQueueNetworkId *>(data));
|
|
|
|
HarvesterInstallationObject * const harvester = dynamic_cast<HarvesterInstallationObject *>(ServerWorld::findObjectByNetworkId (msg->getNetworkId ()));
|
|
|
|
if (harvester && owner)
|
|
harvester->removeSynchronizedUiClient (owner->getNetworkId ());
|
|
}
|
|
break;
|
|
|
|
case CM_clientResourceHarvesterResourceSelect:
|
|
{
|
|
const MessageQueueNetworkIdPair * const msg = NON_NULL (dynamic_cast<const MessageQueueNetworkIdPair *>(data));
|
|
|
|
HarvesterInstallationObject * const harvester = dynamic_cast<HarvesterInstallationObject *>(ServerWorld::findObjectByNetworkId (msg->getFirstNetworkId ()));
|
|
|
|
harvester->selectResource (msg->getSecondNetworkId (), owner->getNetworkId());
|
|
}
|
|
break;
|
|
|
|
case CM_clientResourceHarvesterGetResourceData:
|
|
{
|
|
const MessageQueueNetworkId * const msg = NON_NULL (dynamic_cast<const MessageQueueNetworkId *>(data));
|
|
|
|
typedef stdvector<InstallationResourceData>::fwd DataVector;
|
|
DataVector dv;
|
|
|
|
HarvesterInstallationObject * const harvester = dynamic_cast<HarvesterInstallationObject *>(ServerWorld::findObjectByNetworkId (msg->getNetworkId ()));
|
|
ServerObject * const player = owner;
|
|
|
|
if (harvester && player)
|
|
{
|
|
harvester->getResourceData (dv);
|
|
|
|
if (!dv.empty ())
|
|
{
|
|
MessageQueueHarvesterResourceData * const newData = new MessageQueueHarvesterResourceData (msg->getNetworkId (), dv);
|
|
appendMessage(static_cast<int>(CM_clientResourceHarvesterResourceData), 0.0f, newData, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_clientResourceHarvesterEmptyHopper:
|
|
{
|
|
const MessageQueueResourceEmptyHopper * const msg = NON_NULL (dynamic_cast<const MessageQueueResourceEmptyHopper *>(data));
|
|
|
|
HarvesterInstallationObject * const harvester = dynamic_cast<HarvesterInstallationObject *>(ServerWorld::findObjectByNetworkId (msg->getHarvesterId ()));
|
|
|
|
if (harvester && owner && harvester->isOnHopperList(*owner))
|
|
harvester->emptyHopper (msg->getPlayerId(),msg->getResourceId(), msg->getAmount(),msg->getDiscard(),msg->getSequenceId());
|
|
}
|
|
break;
|
|
case CM_getTokenForObject:
|
|
{
|
|
WARNING_STRICT_FATAL(true, ("Received CM_getTokenForObject controller message. This message is depracated"));
|
|
}
|
|
break;
|
|
|
|
case CM_getWaypointForObject:
|
|
{
|
|
const MessageQueueNetworkId * const msg = NON_NULL (dynamic_cast<const MessageQueueNetworkId *>(data));
|
|
if(msg)
|
|
{
|
|
if(owner)
|
|
{
|
|
PlayerObject * player = PlayerCreatureController::getPlayerObject(owner);
|
|
if(player)
|
|
{
|
|
const ServerObject * target = ServerWorld::findObjectByNetworkId(msg->getNetworkId());
|
|
if(target)
|
|
{
|
|
const Object * topMost = ContainerInterface::getFirstParentInWorld(*target);
|
|
if(topMost)
|
|
{
|
|
const Vector pos = topMost->getPosition_w();
|
|
IGNORE_RETURN(player->createWaypoint(Location(pos, NetworkId::cms_invalid, Location::getCrcBySceneName(ServerWorld::getSceneId())), true));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case CM_secureTrade:
|
|
{
|
|
if (owner->isAuthoritative())
|
|
{
|
|
handleSecureTradeMessage(dynamic_cast<const MessageQueueSecureTrade *>(data));
|
|
}
|
|
// @todo else
|
|
//resend to auth
|
|
|
|
}
|
|
break;
|
|
case CM_clientLookAtTarget:
|
|
{
|
|
const MessageQueueNetworkId * const msg = NON_NULL (dynamic_cast<const MessageQueueNetworkId *>(data));
|
|
owner->setLookAtTarget (msg->getNetworkId ());
|
|
}
|
|
break;
|
|
case CM_clientIntendedTarget:
|
|
{
|
|
const MessageQueueNetworkId * const msg = NON_NULL (dynamic_cast<const MessageQueueNetworkId *>(data));
|
|
owner->setIntendedTarget (msg->getNetworkId ());
|
|
}
|
|
break;
|
|
case CM_clientMoodChange:
|
|
if (value < 0.0f || value > 255.0f)
|
|
WARNING (true, ("Out of range mood: %f", value));
|
|
else
|
|
owner->setMood (static_cast<uint32>(value));
|
|
|
|
break;
|
|
|
|
case CM_setState:
|
|
{
|
|
if (!(flags&GameControllerMessageFlags::SOURCE_REMOTE_CLIENT))
|
|
{
|
|
MessageQueueSetState const *msg = safe_cast<MessageQueueSetState const *>(data);
|
|
owner->setState(static_cast<States::Enumerator>(msg->getState()), msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setAttribute:
|
|
{
|
|
const MessageQueueGenericValueType<std::pair<Attributes::Enumerator, Attributes::Value> > * const msg = safe_cast<const MessageQueueGenericValueType<std::pair<Attributes::Enumerator, Attributes::Value> > *>(data);
|
|
if(owner)
|
|
{
|
|
const std::pair<Attributes::Enumerator, Attributes::Value> & attributePair = msg->getValue();
|
|
if(msg)
|
|
{
|
|
owner->setAttribute(attributePair.first, attributePair.second);
|
|
}
|
|
DEBUG_WARNING(! msg, ("CreatureController (%s:%s) received a CM_setAttribute message but could not retrieve data from the message supplied", owner->getObjectTemplateName(), owner->getNetworkId().getValueString().c_str()));
|
|
}
|
|
}
|
|
break;
|
|
case CM_setMaxAttribute:
|
|
{
|
|
const MessageQueueGenericValueType<std::pair<Attributes::Enumerator, Attributes::Value> > * const msg = safe_cast<const MessageQueueGenericValueType<std::pair<Attributes::Enumerator, Attributes::Value> > *>(data);
|
|
// set the object value and send a message to all it's proxies
|
|
if(msg)
|
|
{
|
|
owner->setMaxAttribute(msg->getValue().first, msg->getValue().second);
|
|
}
|
|
DEBUG_WARNING(! msg, ("CreatureController (%s:%s) received a CM_setMaxAttribute message but could not retrieve data from the message supplied", owner->getObjectTemplateName(), owner->getNetworkId().getValueString().c_str()));
|
|
}
|
|
break;
|
|
case CM_setMentalState:
|
|
{
|
|
const MessageQueueGenericValueType<std::pair<MentalStates::Enumerator, MentalStates::Value> > * const msg = safe_cast<const MessageQueueGenericValueType<std::pair<MentalStates::Enumerator, MentalStates::Value> > *>(data);
|
|
// set the object value and send a message to all it's proxies
|
|
if(msg)
|
|
{
|
|
owner->setMentalState(msg->getValue().first, msg->getValue().second);
|
|
}
|
|
DEBUG_WARNING(! msg, ("CreatureController (%s:%s) received a CM_setMentalState message but could not retrieve data from the message supplied", owner->getObjectTemplateName(), owner->getNetworkId().getValueString().c_str()));
|
|
}
|
|
break;
|
|
case CM_setMentalStateToward:
|
|
{
|
|
const MessageQueueGenericValueType<std::pair<NetworkId, std::pair<MentalStates::Enumerator, MentalStates::Value> > > * const msg = safe_cast<const MessageQueueGenericValueType<std::pair<NetworkId, std::pair<MentalStates::Enumerator, MentalStates::Value> > > *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setMentalStateToward(msg->getValue().first, msg->getValue().second.first, msg->getValue().second.second);
|
|
}
|
|
DEBUG_WARNING(! msg, ("CreatureController (%s:%s) received a CM_setMentalStateToward message but could not retrieve data from the message supplied", owner->getObjectTemplateName(), owner->getNetworkId().getValueString().c_str()));
|
|
}
|
|
break;
|
|
case CM_setCover:
|
|
{
|
|
const MessageQueueGenericValueType<int> * const msg = safe_cast<const MessageQueueGenericValueType<int> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setCover(msg->getValue());
|
|
}
|
|
DEBUG_WARNING(! msg, ("CreatureController (%s:%s) received a CM_setCover message but could not retrieve data from the message supplied", owner->getObjectTemplateName(), owner->getNetworkId().getValueString().c_str()));
|
|
}
|
|
break;
|
|
case CM_setMentalStateTowardClampBehavior:
|
|
{
|
|
const MessageQueueGenericValueType<std::pair<NetworkId, std::pair<MentalStates::Enumerator, std::pair<MentalStates::Value, Behaviors::Enumerator> > > > * const msg = safe_cast<const MessageQueueGenericValueType<std::pair<NetworkId, std::pair<MentalStates::Enumerator, std::pair<MentalStates::Value, Behaviors::Enumerator> > > > *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setMentalStateTowardClampBehavior(
|
|
msg->getValue().first,
|
|
msg->getValue().second.first,
|
|
msg->getValue().second.second.first,
|
|
msg->getValue().second.second.second);
|
|
}
|
|
DEBUG_WARNING(! msg, ("CreatureController (%s:%s) received a CM_setMentalStateTowardClampBehavior message but could not retrieve data from the message supplied", owner->getObjectTemplateName(), owner->getNetworkId().getValueString().c_str()));
|
|
}
|
|
break;
|
|
case CM_setMaxMentalState:
|
|
{
|
|
const MessageQueueGenericValueType<std::pair<MentalStates::Enumerator, MentalStates::Value> > * const msg = safe_cast<const MessageQueueGenericValueType<std::pair<MentalStates::Enumerator, MentalStates::Value> > *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setMaxMentalState(msg->getValue().first, msg->getValue().second);
|
|
}
|
|
DEBUG_WARNING(! msg, ("CreatureController (%s:%s) received a CM_setMaxMentalState message but could not retrieve data from the message supplied", owner->getObjectTemplateName(), owner->getNetworkId().getValueString().c_str()));
|
|
}
|
|
break;
|
|
case CM_setMentalStateDecay:
|
|
{
|
|
const MessageQueueGenericValueType<std::pair<MentalStates::Enumerator, float> > * const msg = safe_cast<const MessageQueueGenericValueType<std::pair<MentalStates::Enumerator, float> > *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setMentalStateDecay(msg->getValue().first, msg->getValue().second);
|
|
}
|
|
DEBUG_WARNING(! msg, ("CreatureController (%s:%s) received a CM_setMentalStateDecay message but could not retrieve data from the message supplied", owner->getObjectTemplateName(), owner->getNetworkId().getValueString().c_str()));
|
|
}
|
|
break;
|
|
case CM_setPosture:
|
|
{
|
|
const MessageQueuePosture * const msg = safe_cast<const MessageQueuePosture *>(data);
|
|
|
|
if(msg)
|
|
{
|
|
owner->setPosture(msg->getPosture(), msg->isClientImmediate());
|
|
}
|
|
DEBUG_WARNING(! msg, ("CreatureController (%s:%s) received a CM_setPosture message but could not retrieve data from the message supplied", owner->getObjectTemplateName(), owner->getNetworkId().getValueString().c_str()));
|
|
}
|
|
break;
|
|
case CM_setLocomotion:
|
|
{
|
|
const MessageQueueGenericValueType<Locomotions::Enumerator> * const msg = safe_cast<const MessageQueueGenericValueType<Locomotions::Enumerator> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setLocomotion(msg->getValue());
|
|
}
|
|
DEBUG_WARNING(! msg, ("CreatureController (%s:%s) received a CM_setLocomotion message but could not retrieve data from the message supplied", owner->getObjectTemplateName(), owner->getNetworkId().getValueString().c_str()));
|
|
}
|
|
break;
|
|
case CM_setGroupInviter:
|
|
{
|
|
const MessageQueueGenericValueType<std::pair<std::string, std::pair<NetworkId, NetworkId> > > * const msg = safe_cast<const MessageQueueGenericValueType<std::pair<std::string, std::pair<NetworkId, NetworkId> > > *>(data);
|
|
if (msg)
|
|
{
|
|
owner->setGroupInviter(msg->getValue().second.first, msg->getValue().first, msg->getValue().second.second);
|
|
}
|
|
}
|
|
break;
|
|
case CM_setPerformanceType:
|
|
{
|
|
const MessageQueueGenericValueType<int> * const msg = safe_cast<const MessageQueueGenericValueType<int> *>(data);
|
|
if (msg)
|
|
{
|
|
owner->setPerformanceType(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setPerformanceStartTime:
|
|
{
|
|
const MessageQueueGenericValueType<int> * const msg = safe_cast<const MessageQueueGenericValueType<int> *>(data);
|
|
if (msg)
|
|
{
|
|
owner->setPerformanceStartTime(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setPerformanceListenTarget:
|
|
{
|
|
const MessageQueueGenericValueType<NetworkId> * const msg = safe_cast<const MessageQueueGenericValueType<NetworkId> *>(data);
|
|
if (msg)
|
|
{
|
|
owner->setPerformanceListenTarget(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setPerformanceWatchTarget:
|
|
{
|
|
const MessageQueueGenericValueType<NetworkId> * const msg = safe_cast<const MessageQueueGenericValueType<NetworkId> *>(data);
|
|
if (msg)
|
|
{
|
|
owner->setPerformanceWatchTarget(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setModValue:
|
|
{
|
|
const
|
|
MessageQueueGenericValueType<std::pair<std::string, int> > * const msg = safe_cast<const MessageQueueGenericValueType<std::pair<std::string, int> > *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setModValue(msg->getValue().first, msg->getValue().second);
|
|
}
|
|
}
|
|
break;
|
|
case CM_grantCommand:
|
|
{
|
|
const MessageQueueGenericValueType<std::string> * const msg = safe_cast<const MessageQueueGenericValueType<std::string> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->grantCommand(msg->getValue(), false);
|
|
}
|
|
}
|
|
break;
|
|
case CM_grantExperiencePoints:
|
|
{
|
|
const MessageQueueGenericValueType<std::pair<std::string, int> > * const msg = safe_cast<const MessageQueueGenericValueType<std::pair<std::string, int> > *>(data);
|
|
if(msg)
|
|
{
|
|
owner->grantExperiencePoints(msg->getValue().first, msg->getValue().second);
|
|
}
|
|
}
|
|
break;
|
|
case CM_incrementKillMeter:
|
|
{
|
|
const MessageQueueGenericValueType<int> * const msg = safe_cast<const MessageQueueGenericValueType<int> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->incrementKillMeter(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_grantSkill:
|
|
{
|
|
const MessageQueueGenericValueType<std::string> * const msg = safe_cast<const MessageQueueGenericValueType<std::string> *>(data);
|
|
if(msg)
|
|
{
|
|
const SkillObject * newSkill = SkillManager::getInstance().getSkill(msg->getValue());
|
|
if(newSkill)
|
|
{
|
|
owner->grantSkill(*newSkill);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case CM_revokeCommand:
|
|
{
|
|
const MessageQueueGenericValueType<std::string> * const msg = safe_cast<const MessageQueueGenericValueType<std::string> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->revokeCommand(msg->getValue(), false);
|
|
}
|
|
}
|
|
break;
|
|
case CM_revokeSkill:
|
|
{
|
|
const MessageQueueGenericValueType<std::string> * const msg = safe_cast<const MessageQueueGenericValueType<std::string> *>(data);
|
|
if(msg)
|
|
{
|
|
const SkillObject * oldSkill = SkillManager::getInstance().getSkill(msg->getValue());
|
|
if(oldSkill)
|
|
{
|
|
LOG("CustomerService", ("Skill: Removing skill %s from character %s via controller message.",
|
|
msg->getValue().c_str(), owner->getNetworkId().getValueString().c_str()));
|
|
owner->revokeSkill(*oldSkill);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case CM_alterAttribute:
|
|
{
|
|
const MessageQueueAlterAttribute * const msg = safe_cast<const MessageQueueAlterAttribute *>(data);
|
|
if(msg)
|
|
{
|
|
owner->alterAttribute(msg->getAttrib(),
|
|
msg->getDelta(),
|
|
msg->getCheckIncapacitation(),
|
|
msg->getSource()
|
|
);
|
|
}
|
|
}
|
|
break;
|
|
case CM_addAttributeModifier:
|
|
{
|
|
const MessageQueueGenericValueType<AttribMod::AttribMod> * const msg = safe_cast<const MessageQueueGenericValueType<AttribMod::AttribMod> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->addAttributeModifier(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_removeAttributeModifiers:
|
|
{
|
|
const MessageQueueGenericValueType<Attributes::Enumerator> * const msg = safe_cast<const MessageQueueGenericValueType<Attributes::Enumerator> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->removeAttributeModifiers(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_removeAllAttributeModifiers:
|
|
{
|
|
owner->removeAllAttributeModifiers();
|
|
}
|
|
break;
|
|
case CM_removeAllAttributeAndSkillmodModifiers:
|
|
{
|
|
owner->removeAllAttributeAndSkillmodMods();
|
|
}
|
|
break;
|
|
case CM_setCurrentWeapon:
|
|
{
|
|
const MessageQueueGenericValueType<NetworkId> * const msg = safe_cast<const MessageQueueGenericValueType<NetworkId> *>(data);
|
|
if(msg)
|
|
{
|
|
WeaponObject * weapon = safe_cast<WeaponObject *>(NetworkIdManager::getObjectById(msg->getValue()));
|
|
if(weapon)
|
|
owner->setCurrentWeapon(*weapon);
|
|
}
|
|
}
|
|
break;
|
|
case CM_setGroup:
|
|
{
|
|
const MessageQueueGenericValueType<std::pair<bool, NetworkId> > * const msg = safe_cast<const MessageQueueGenericValueType<std::pair<bool, NetworkId> > *>(data);
|
|
if(msg)
|
|
{
|
|
GroupObject * group = safe_cast<GroupObject *>(NetworkIdManager::getObjectById(msg->getValue().second));
|
|
|
|
if (group)
|
|
{
|
|
owner->setGroup(group, msg->getValue().first);
|
|
}
|
|
else if (!msg->getValue().second.isValid())
|
|
{
|
|
if (owner->getGroup())
|
|
owner->getGroup()->onGroupMemberRemoved(owner->getNetworkId(), msg->getValue().first);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case CM_setIncapacitated:
|
|
{
|
|
const MessageQueueGenericValueType<std::pair<bool, NetworkId> > * const msg = safe_cast<const MessageQueueGenericValueType<std::pair<bool, NetworkId> > *>(data);
|
|
if (msg != NULL)
|
|
owner->setIncapacitated(msg->getValue().first, msg->getValue().second);
|
|
}
|
|
break;
|
|
case CM_setSayMode:
|
|
{
|
|
const MessageQueueGenericValueType<unsigned long> * const msg = safe_cast<const MessageQueueGenericValueType<unsigned long> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setSayMode(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setAnimationMood:
|
|
{
|
|
const MessageQueueGenericValueType<std::string> * const msg = safe_cast<const MessageQueueGenericValueType<std::string> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setAnimationMood(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setScaleFactor:
|
|
{
|
|
const MessageQueueGenericValueType<float> * const msg = safe_cast<const MessageQueueGenericValueType<float> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setScaleFactor(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setShockWounds:
|
|
{
|
|
const MessageQueueGenericValueType<int> * const msg = safe_cast<const MessageQueueGenericValueType<int> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setShockWounds(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setLookAtTarget:
|
|
{
|
|
const MessageQueueGenericValueType<NetworkId> * const msg = safe_cast<const MessageQueueGenericValueType<NetworkId> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setLookAtTarget(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setIntendedTarget:
|
|
{
|
|
const MessageQueueGenericValueType<NetworkId> * const msg = safe_cast<const MessageQueueGenericValueType<NetworkId> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setIntendedTarget(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setMovementStationary:
|
|
{
|
|
owner->setMovementStationary();
|
|
}
|
|
break;
|
|
case CM_setMovementWalk:
|
|
{
|
|
owner->setMovementWalk();
|
|
}
|
|
break;
|
|
case CM_setMovementRun:
|
|
{
|
|
owner->setMovementRun();
|
|
}
|
|
break;
|
|
case CM_setSlopeModAngle:
|
|
{
|
|
const MessageQueueGenericValueType<float> * const msg = safe_cast<const MessageQueueGenericValueType<float> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setSlopeModAngle(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setSlopeModPercent:
|
|
{
|
|
const MessageQueueGenericValueType<float> * const msg = safe_cast<const MessageQueueGenericValueType<float> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setSlopeModPercent(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setWaterModPercent:
|
|
{
|
|
const MessageQueueGenericValueType<float> * const msg = safe_cast<const MessageQueueGenericValueType<float> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setWaterModPercent(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setMovementScale:
|
|
{
|
|
const MessageQueueGenericValueType<float> * const msg = safe_cast<const MessageQueueGenericValueType<float> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setMovementScale(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setMovementPercent:
|
|
{
|
|
const MessageQueueGenericValueType<float> * const msg = safe_cast<const MessageQueueGenericValueType<float> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setMovementPercent(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setTurnPercent:
|
|
{
|
|
const MessageQueueGenericValueType<float> * const msg = safe_cast<const MessageQueueGenericValueType<float> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setTurnPercent(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setAccelScale:
|
|
{
|
|
const MessageQueueGenericValueType<float> * const msg = safe_cast<const MessageQueueGenericValueType<float> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setAccelScale(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setAccelPercent:
|
|
{
|
|
const MessageQueueGenericValueType<float> * const msg = safe_cast<const MessageQueueGenericValueType<float> *>(data);
|
|
if(msg)
|
|
{
|
|
owner->setAccelPercent(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_sitOnObject:
|
|
{
|
|
const MessageQueueSitOnObject * const msg = safe_cast<const MessageQueueSitOnObject *>(data);
|
|
if(msg)
|
|
{
|
|
owner->sitOnObject(msg->getChairCellId(), msg->getChairPosition_p());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setMasterId:
|
|
{
|
|
const MessageQueueGenericValueType<NetworkId> * const msg = safe_cast<const MessageQueueGenericValueType<NetworkId> *>(data);
|
|
if (msg)
|
|
{
|
|
owner->setMasterId(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
case CM_setHouse:
|
|
{
|
|
const MessageQueueGenericValueType<NetworkId> * const msg = safe_cast<const MessageQueueGenericValueType<NetworkId> *>(data);
|
|
if (msg)
|
|
{
|
|
owner->setHouse(CachedNetworkId(msg->getValue()));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_setDifficulty:
|
|
case CM_setLevel:
|
|
{
|
|
MessageQueueGenericValueType<int> const *msg = safe_cast<MessageQueueGenericValueType<int> const *>(data);
|
|
if (msg)
|
|
owner->setLevel(static_cast<int16>(msg->getValue()));
|
|
}
|
|
break;
|
|
case CM_recalculateLevel:
|
|
{
|
|
MessageQueueGenericValueType<int> const *msg = safe_cast<MessageQueueGenericValueType<int> const *>(data);
|
|
if (msg)
|
|
owner->recalculateLevel();
|
|
}
|
|
break;
|
|
|
|
|
|
case CM_creatureSetBaseWalkSpeed:
|
|
owner->setBaseWalkSpeed(value);
|
|
break;
|
|
|
|
case CM_creatureSetBaseRunSpeed:
|
|
owner->setBaseRunSpeed(value);
|
|
break;
|
|
|
|
case CM_emergencyDismountForRider:
|
|
owner->emergencyDismountForRider();
|
|
break;
|
|
|
|
case CM_detachRiderForMount:
|
|
{
|
|
typedef MessageQueueGenericValueType<NetworkId> Message;
|
|
Message const * const msg = safe_cast<Message const *>(data);
|
|
|
|
if (msg != 0)
|
|
{
|
|
owner->detachRider(msg->getValue());
|
|
}
|
|
break;
|
|
}
|
|
|
|
case CM_detachAllRidersForMount:
|
|
owner->detachAllRiders();
|
|
break;
|
|
|
|
case CM_setAppearanceFromObjectTemplate:
|
|
{
|
|
MessageQueueGenericValueType<std::string> const *const msg = dynamic_cast<MessageQueueGenericValueType<std::string> const *>(data);
|
|
if (owner && msg)
|
|
owner->setAlternateAppearance(msg->getValue());
|
|
else
|
|
WARNING(true, ("CreatureController: received CM_setAppearanceFromObjectTemplate but owner or message was NULL."));
|
|
}
|
|
break;
|
|
|
|
case CM_makeDead:
|
|
{
|
|
const MessageQueueGenericValueType<std::pair<NetworkId, NetworkId> > * msg = dynamic_cast<const MessageQueueGenericValueType<std::pair<NetworkId, NetworkId> > *>(data);
|
|
if (msg)
|
|
{
|
|
owner->makeDead(msg->getValue().first, msg->getValue().second);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_pushCreature:
|
|
{
|
|
const MessageQueuePushCreature * const msg = safe_cast<const MessageQueuePushCreature *>(data);
|
|
if (msg)
|
|
{
|
|
ServerObject * defender = safe_cast<ServerObject *>(NetworkIdManager::getObjectById(msg->getDefender()));
|
|
if (defender != NULL)
|
|
{
|
|
if (defender->asCreatureObject() != NULL)
|
|
{
|
|
defender->asCreatureObject()->pushedMe(msg->getAttacker(), msg->getAttackerPos(), msg->getDefenderPos(), msg->getDistance());
|
|
}
|
|
else
|
|
{
|
|
WARNING(true, ("Received MessageQueuePushCreature for non-creature defender %s", msg->getDefender().getValueString().c_str()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_slowDownEffect:
|
|
{
|
|
const MessageQueueSlowDownEffect * const msg = safe_cast<const MessageQueueSlowDownEffect * const>(data);
|
|
if (msg)
|
|
{
|
|
ServerObject * target = safe_cast<ServerObject *>(NetworkIdManager::getObjectById(msg->getTarget()));
|
|
if (target != NULL && target->asTangibleObject() != NULL)
|
|
{
|
|
if (owner->isAuthoritative())
|
|
owner->addSlowDownEffect(*(target->asTangibleObject()), msg->getConeLength(), msg->getConeAngle(), msg->getSlopeAngle(), msg->getExpireTime());
|
|
else
|
|
owner->addSlowDownEffectProxy(*(target->asTangibleObject()), msg->getConeLength(), msg->getConeAngle(), msg->getSlopeAngle(), msg->getExpireTime());
|
|
}
|
|
else
|
|
{
|
|
WARNING(true, ("Received slow down effect messge for creature %s "
|
|
"with unknown target %s",
|
|
owner->getNetworkId().getValueString().c_str(),
|
|
msg->getTarget().getValueString().c_str()));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_removeSlowDownEffect:
|
|
{
|
|
if (owner->isAuthoritative())
|
|
owner->removeSlowDownEffect();
|
|
else
|
|
{
|
|
WARNING(true, ("CM_removeSlowDownEffect message recieved by proxy object %s", owner->getNetworkId().getValueString().c_str()));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_removeSlowDownEffectProxy:
|
|
{
|
|
if (!owner->isAuthoritative())
|
|
owner->removeSlowDownEffectProxy();
|
|
else
|
|
{
|
|
WARNING(true, ("CM_removeSlowDownEffectProxy message recieved by authoritative object %s", owner->getNetworkId().getValueString().c_str()));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_groupLotteryWindowCloseResults:
|
|
{
|
|
typedef std::pair<NetworkId, std::vector<NetworkId> > Payload;
|
|
|
|
MessageQueueGenericValueType<Payload> const * const msg = safe_cast<MessageQueueGenericValueType<Payload> const *>(data);
|
|
if (msg != 0)
|
|
{
|
|
Payload const & incomingPayload = msg->getValue();
|
|
|
|
typedef std::vector<NetworkId> Ids;
|
|
|
|
NetworkId const & player = incomingPayload.first;
|
|
Ids const & selectedItems = incomingPayload.second;
|
|
|
|
GameScriptObject * const scriptObject = owner->getScriptObject();
|
|
if (scriptObject != 0)
|
|
{
|
|
ScriptParams params;
|
|
params.addParam(player);
|
|
params.addParam(selectedItems);
|
|
IGNORE_RETURN(scriptObject->trigAllScripts(Scripting::TRIG_LOOT_LOTTERY_SELECTED, params));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_cyberneticsChangeRequestToNPC:
|
|
{
|
|
MessageQueueCyberneticsChangeRequest const * const msg = safe_cast<MessageQueueCyberneticsChangeRequest const *>(data);
|
|
NOT_NULL(msg);
|
|
if (msg != NULL)
|
|
{
|
|
NetworkId const & playerId = msg->getTarget();
|
|
GameScriptObject * const scriptObject = owner->getScriptObject();
|
|
if (scriptObject)
|
|
{
|
|
ScriptParams params;
|
|
params.addParam(playerId);
|
|
params.addParam(static_cast<int>(msg->getChangeType()));
|
|
params.addParam(msg->getCyberneticPiece());
|
|
|
|
IGNORE_RETURN(scriptObject->trigAllScripts(Scripting::TRIG_CYBERNETIC_CHANGE_REQUEST, params));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_setCurrentQuest:
|
|
{
|
|
MessageQueueGenericValueType<uint32> const * const msg = safe_cast<MessageQueueGenericValueType<uint32> const *>(data);
|
|
if (msg != NULL)
|
|
{
|
|
PlayerObject * player = PlayerCreatureController::getPlayerObject(owner);
|
|
if (player != NULL)
|
|
{
|
|
player->setCurrentQuest(msg->getValue());
|
|
}
|
|
else
|
|
{
|
|
DEBUG_WARNING(true, ("Non-player creature %s sent CM_setCurrentQuest message (%u)",
|
|
owner->getNetworkId().getValueString().c_str(), msg->getValue()));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_setRegenRate:
|
|
{
|
|
MessageQueueGenericValueType<std::pair<int, float> > const * const msg = safe_cast<MessageQueueGenericValueType<std::pair<int, float> > const *>(data);
|
|
if (msg != NULL)
|
|
{
|
|
owner->setRegenRate(static_cast<Attributes::Enumerator>(msg->getValue().first), msg->getValue().second);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_modifyCurrentGcwPoints:
|
|
{
|
|
const MessageQueueGenericValueType<std::pair<int, int> > * const msg = safe_cast<const MessageQueueGenericValueType<std::pair<int, int> > *>(data);
|
|
if(msg)
|
|
{
|
|
PlayerObject * player = PlayerCreatureController::getPlayerObject(owner);
|
|
if(player)
|
|
{
|
|
player->modifyCurrentGcwPoints(msg->getValue().first, (msg->getValue().second != 0));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_modifyCurrentGcwRating:
|
|
{
|
|
const MessageQueueGenericValueType<std::pair<int, int> > * const msg = safe_cast<const MessageQueueGenericValueType<std::pair<int, int> > *>(data);
|
|
if(msg)
|
|
{
|
|
PlayerObject * player = PlayerCreatureController::getPlayerObject(owner);
|
|
if(player)
|
|
{
|
|
player->modifyCurrentGcwRating(msg->getValue().first, (msg->getValue().second != 0));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_modifyCurrentPvpKills:
|
|
{
|
|
const MessageQueueGenericValueType<std::pair<int, int> > * const msg = safe_cast<const MessageQueueGenericValueType<std::pair<int, int> > *>(data);
|
|
if(msg)
|
|
{
|
|
PlayerObject * player = PlayerCreatureController::getPlayerObject(owner);
|
|
if(player)
|
|
{
|
|
player->modifyCurrentPvpKills(msg->getValue().first, (msg->getValue().second != 0));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_modifyLifetimeGcwPoints:
|
|
{
|
|
const MessageQueueGenericValueType<int> * const msg = safe_cast<const MessageQueueGenericValueType<int> *>(data);
|
|
if(msg)
|
|
{
|
|
PlayerObject * player = PlayerCreatureController::getPlayerObject(owner);
|
|
if(player)
|
|
{
|
|
player->modifyLifetimeGcwPoints(msg->getValue());
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_modifyMaxGcwImperialRating:
|
|
{
|
|
const MessageQueueGenericValueType<int> * const msg = safe_cast<const MessageQueueGenericValueType<int> *>(data);
|
|
if(msg)
|
|
{
|
|
PlayerObject * player = PlayerCreatureController::getPlayerObject(owner);
|
|
if(player)
|
|
{
|
|
player->modifyMaxGcwImperialRating(msg->getValue());
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_modifyMaxGcwRebelRating:
|
|
{
|
|
const MessageQueueGenericValueType<int> * const msg = safe_cast<const MessageQueueGenericValueType<int> *>(data);
|
|
if(msg)
|
|
{
|
|
PlayerObject * player = PlayerCreatureController::getPlayerObject(owner);
|
|
if(player)
|
|
{
|
|
player->modifyMaxGcwRebelRating(msg->getValue());
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_modifyLifetimePvpKills:
|
|
{
|
|
const MessageQueueGenericValueType<int> * const msg = safe_cast<const MessageQueueGenericValueType<int> *>(data);
|
|
if(msg)
|
|
{
|
|
PlayerObject * player = PlayerCreatureController::getPlayerObject(owner);
|
|
if(player)
|
|
{
|
|
player->modifyLifetimePvpKills(msg->getValue());
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_modifyNextGcwRatingCalcTime:
|
|
{
|
|
const MessageQueueGenericValueType<int> * const msg = safe_cast<const MessageQueueGenericValueType<int> *>(data);
|
|
if(msg)
|
|
{
|
|
PlayerObject * player = PlayerCreatureController::getPlayerObject(owner);
|
|
if(player)
|
|
{
|
|
player->modifyNextGcwRatingCalcTime(msg->getValue());
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_customizeFinished:
|
|
{
|
|
typedef std::pair<NetworkId, std::string > Payload;
|
|
|
|
MessageQueueGenericValueType<Payload> const * const msg = safe_cast<MessageQueueGenericValueType<Payload> const *>(data);
|
|
if (msg != 0)
|
|
{
|
|
Payload const & incomingPayload = msg->getValue();
|
|
|
|
NetworkId const & object = incomingPayload.first;
|
|
std::string const & msgValue = incomingPayload.second;
|
|
|
|
GameScriptObject * const scriptObject = owner->getScriptObject();
|
|
if (scriptObject != 0)
|
|
{
|
|
ScriptParams params;
|
|
params.addParam(object);
|
|
params.addParam(msgValue.c_str());
|
|
IGNORE_RETURN(scriptObject->trigAllScripts(Scripting::TRIG_ON_CUSTOMIZE_FINISHED, params));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_clearSessionActivity:
|
|
{
|
|
PlayerObject * player = PlayerCreatureController::getPlayerObject(owner);
|
|
if(player)
|
|
{
|
|
player->clearSessionActivity();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_addSessionActivity:
|
|
{
|
|
const MessageQueueGenericValueType<unsigned long> * const msg = safe_cast<const MessageQueueGenericValueType<unsigned long> *>(data);
|
|
if(msg)
|
|
{
|
|
PlayerObject * player = PlayerCreatureController::getPlayerObject(owner);
|
|
if(player)
|
|
{
|
|
player->addSessionActivity(static_cast<uint32>(msg->getValue()));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_modifyHologramType:
|
|
{
|
|
MessageQueueGenericValueType<int32> const *msg = safe_cast<MessageQueueGenericValueType<int32> const *>(data);
|
|
if (msg)
|
|
owner->setHologramType(msg->getValue());
|
|
}
|
|
break;
|
|
|
|
case CM_modifyVisibleOnMapAndRadar:
|
|
{
|
|
MessageQueueGenericValueType<bool> const *msg = safe_cast<MessageQueueGenericValueType<bool> const *>(data);
|
|
if (msg)
|
|
owner->setVisibleOnMapAndRadar(msg->getValue());
|
|
}
|
|
break;
|
|
|
|
case CM_setCoverVisibility:
|
|
{
|
|
const MessageQueueGenericValueType<bool> * const msg = safe_cast<const MessageQueueGenericValueType<bool> *>(data);
|
|
if (msg)
|
|
{
|
|
owner->setCoverVisibility(msg->getValue());
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_incubatorCancel:
|
|
{
|
|
IncubatorCommitMessage const * const msg = safe_cast<IncubatorCommitMessage const *>(data);
|
|
if (msg)
|
|
{
|
|
ServerObject * incubatorSo = ServerWorld::findObjectByNetworkId(msg->getTerminalId());
|
|
if (incubatorSo)
|
|
{
|
|
TangibleObject * incubatorTo = incubatorSo->asTangibleObject();
|
|
|
|
if (incubatorTo)
|
|
incubatorTo->handleIncubatorCancel(*owner);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_incubatorCommit:
|
|
{
|
|
IncubatorCommitMessage const * const msg = safe_cast<IncubatorCommitMessage const *>(data);
|
|
if (msg)
|
|
{
|
|
ServerObject * incubatorSo = ServerWorld::findObjectByNetworkId(msg->getTerminalId());
|
|
if (incubatorSo)
|
|
{
|
|
TangibleObject * incubatorTo = incubatorSo->asTangibleObject();
|
|
|
|
if (incubatorTo)
|
|
incubatorTo->handleIncubatorCommit(*owner, *msg);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_modifyCollectionSlotValue:
|
|
{
|
|
const MessageQueueGenericValueType<std::pair<std::string, int64> > * const msg = safe_cast<const MessageQueueGenericValueType<std::pair<std::string, int64> > *>(data);
|
|
if(msg)
|
|
{
|
|
PlayerObject * player = PlayerCreatureController::getPlayerObject(owner);
|
|
if(player)
|
|
{
|
|
player->modifyCollectionSlotValue(msg->getValue().first, msg->getValue().second);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_adjustLotCount:
|
|
{
|
|
const MessageQueueGenericValueType<int> * const msg = safe_cast<const MessageQueueGenericValueType<int> *>(data);
|
|
if(msg)
|
|
{
|
|
PlayerObject * player = PlayerCreatureController::getPlayerObject(owner);
|
|
if(player)
|
|
{
|
|
player->adjustLotCount(msg->getValue());
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_squelch:
|
|
{
|
|
const MessageQueueGenericValueType<std::pair<std::string, std::pair<NetworkId, int> > > * const msg = safe_cast<const MessageQueueGenericValueType<std::pair<std::string, std::pair<NetworkId, int> > > *>(data);
|
|
if(msg)
|
|
{
|
|
PlayerObject * player = PlayerCreatureController::getPlayerObject(owner);
|
|
if(player)
|
|
{
|
|
player->squelch(msg->getValue().second.first, msg->getValue().first, msg->getValue().second.second);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_unsquelch:
|
|
{
|
|
PlayerObject * player = PlayerCreatureController::getPlayerObject(owner);
|
|
if(player)
|
|
{
|
|
player->unsquelch();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_setPriviledgedTitle:
|
|
{
|
|
const MessageQueueGenericValueType<int> * const msg = safe_cast<const MessageQueueGenericValueType<int> *>(data);
|
|
if(msg)
|
|
{
|
|
PlayerObject * player = PlayerCreatureController::getPlayerObject(owner);
|
|
if(player)
|
|
{
|
|
player->setPriviledgedTitle(static_cast<int8>(msg->getValue()));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_addBuff:
|
|
{
|
|
const MessageQueueGenericValueType<std::pair<int, std::pair<float, std::pair<float, std::pair< float, NetworkId > > > > > * const msg = safe_cast<const MessageQueueGenericValueType<std::pair<int, std::pair<float, std::pair<float, std::pair< float, NetworkId > > > > > *>(data);
|
|
if(msg)
|
|
{
|
|
owner->addBuff (static_cast<uint32>(msg->getValue ().first), msg->getValue ().second.first, msg->getValue ().second.second.first, msg->getValue ().second.second.second.first, msg->getValue ().second.second.second.second);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_removeBuff:
|
|
{
|
|
const MessageQueueGenericValueType<int> * const msg = safe_cast<const MessageQueueGenericValueType<int> * >(data);
|
|
if(msg)
|
|
{
|
|
owner->removeBuff (static_cast<uint32>(msg->getValue ()));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CM_ratingFinished:
|
|
{
|
|
const MessageQueueGenericValueType<int> * const msg = safe_cast<const MessageQueueGenericValueType<int> * >(data);
|
|
if(msg)
|
|
{
|
|
if(owner->getScriptObject())
|
|
{
|
|
ScriptParams params;
|
|
params.addParam(msg->getValue());
|
|
IGNORE_RETURN(owner->getScriptObject()->trigAllScripts(Scripting::TRIG_ON_RATING_FINISHED, params));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case CM_abandonPlayerQuest:
|
|
{
|
|
const MessageQueueGenericValueType<NetworkId> * const msg = safe_cast<const MessageQueueGenericValueType<NetworkId> * >(data);
|
|
if(msg)
|
|
{
|
|
if(owner->getScriptObject())
|
|
{
|
|
ScriptParams params;
|
|
params.addParam(msg->getValue());
|
|
IGNORE_RETURN(owner->getScriptObject()->trigAllScripts(Scripting::TRIG_ON_ABANDON_PLAYER_QUEST, params));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
TangibleController::handleMessage(message, value, data, flags);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
float CreatureController::realAlter(float time)
|
|
{
|
|
PROFILER_AUTO_BLOCK_DEFINE("CreatureController::realAlter");
|
|
|
|
float alterResult = TangibleController::realAlter(time);
|
|
|
|
CreatureObject * const owner = NON_NULL(getCreature());
|
|
|
|
if(getHibernate())
|
|
return alterResult;
|
|
|
|
if (owner->isAuthoritative())
|
|
owner->decayAttributes(time);
|
|
|
|
if (owner->isInWorld())
|
|
{
|
|
bool isBurning = false;
|
|
float lavaResistance = 0.0f;
|
|
|
|
if (owner->isAuthoritative())
|
|
{
|
|
//owner->decayMentalStates(time);
|
|
owner->reportMonitoredCreatures(time);
|
|
|
|
//-- Handle swimming state.
|
|
bool const currentSwimState = owner->getState(States::Swimming);
|
|
bool newSwimState = false;
|
|
float waterHeight = 0.0f;
|
|
calculateWaterState(newSwimState,isBurning,lavaResistance,waterHeight);
|
|
|
|
bool const isVehicle = GameObjectTypes::isTypeOf (owner->getGameObjectType (), static_cast<int>(SharedObjectTemplate::GOT_vehicle));
|
|
if(!isVehicle) // make everything but vehicles walk on lava
|
|
{
|
|
const Vector & position = owner->getPosition_w ();
|
|
Footprint *const footprint = owner->getFootprint();
|
|
if(footprint)
|
|
{
|
|
if(isBurning)
|
|
{
|
|
footprint->setSwimHeight(owner->getSwimHeight() * 0.2f);
|
|
owner->move_p(Vector::unitY * (waterHeight - position.y));
|
|
}
|
|
else
|
|
{
|
|
footprint->setSwimHeight(owner->getSwimHeight());
|
|
}
|
|
}
|
|
}
|
|
|
|
if (currentSwimState && !newSwimState)
|
|
{
|
|
// We've just detected that the owner stopped swimming.
|
|
onExitSwimming();
|
|
}
|
|
else if (!currentSwimState && newSwimState)
|
|
{
|
|
// We've just detected that the owner started swimming.
|
|
onEnterSwimming();
|
|
}
|
|
|
|
setObjectStopWalkRun();
|
|
}
|
|
|
|
CollisionProperty *const collisionProperty = owner->getCollisionProperty();
|
|
if (owner->getState(States::RidingMount))
|
|
{
|
|
// Tell the rider's CollisionProperty to update its extent. Since
|
|
// the rider is yanked out of the CollisionWorld, the
|
|
// CollisionProperty doesn't get updated properly. Failure to
|
|
// update the rider's CollisionProperty extent causes line of sight
|
|
// to fail (line of sight ends up using the value present in CollisionProperty
|
|
// at the time of mounting).
|
|
|
|
if (collisionProperty)
|
|
collisionProperty->updateExtents();
|
|
}
|
|
|
|
const bool isPlayerControlled = (collisionProperty && collisionProperty->isPlayerControlled());
|
|
|
|
// lava damage
|
|
if(WaterTypeManager::getCausesDamage(TGWT_lava)
|
|
&& isBurning
|
|
&& (isPlayerControlled || owner->isBeast())
|
|
)
|
|
{
|
|
const unsigned long serverTime = ServerClock::getInstance().getGameTimeSeconds();
|
|
const unsigned long lastBurnTime = owner->getLastWaterDamageTime();
|
|
const unsigned long waterDamageInterval = WaterTypeManager::getDamageInterval(TGWT_lava);
|
|
|
|
if(serverTime - lastBurnTime > (waterDamageInterval*3)) // skip the first lava damage frame
|
|
{
|
|
owner->setLastWaterDamageTime(serverTime - waterDamageInterval);
|
|
//DEBUG_WARNING(true,("LAVA DAMAGE SLUSH TIME- serverTime=%ul, lastBurnTime=%ul, diff=%d",serverTime,lastBurnTime,serverTime-lastBurnTime));
|
|
}
|
|
else if(serverTime - lastBurnTime > waterDamageInterval && !owner->isDead())
|
|
{
|
|
owner->setLastWaterDamageTime(serverTime);
|
|
const float percentWaterDamagePerInterval = WaterTypeManager::getDamagePerInterval(TGWT_lava)/100.0f;
|
|
const float lavaResistanceModifier = 1.0f - lavaResistance/100.0f;
|
|
|
|
const int damageValue =
|
|
static_cast<int> (
|
|
-( owner->getMaxAttribute(Attributes::Health)
|
|
* percentWaterDamagePerInterval
|
|
* lavaResistanceModifier
|
|
)
|
|
);
|
|
|
|
StringId stringId = StringId("combat_effects", "environment_damage_lava");
|
|
owner->showFlyText(stringId,5.0f,255,0,0);
|
|
|
|
if(WaterTypeManager::getDamageKills(TGWT_lava)
|
|
&& (owner->getAttribute(Attributes::Health) + damageValue) <= 0)
|
|
{
|
|
owner->makeDead(NetworkId::cms_invalid, NetworkId::cms_invalid);
|
|
ScriptParams params;
|
|
owner->getScriptObject()->trigAllScripts(Scripting::TRIG_ENVIRONMENTAL_DEATH,params);
|
|
}
|
|
else
|
|
{
|
|
CombatEngineData::DamageData damageData;
|
|
struct AttribMod::AttribMod damage;
|
|
damage.tag = 0;
|
|
damage.attrib = Attributes::Health;
|
|
damage.attack = 0;
|
|
damage.sustain = 0;
|
|
damage.decay = AttribMod::AMDS_pool;
|
|
damage.flags = AttribMod::AMF_directDamage;
|
|
damage.value = damageValue;
|
|
damageData.damage.push_back(damage);
|
|
owner->applyDamage(damageData);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return alterResult;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
void CreatureController::conclude()
|
|
{
|
|
PROFILER_AUTO_BLOCK_DEFINE("CreatureController::conclude");
|
|
|
|
MessageQueue::Data* data;
|
|
|
|
int message;
|
|
real value;
|
|
uint32 flags;
|
|
NetworkId networkId;
|
|
|
|
int const messageCount = getNumberOfMessages();
|
|
for(int i = 0; i < messageCount; ++i)
|
|
{
|
|
//-- Get the message.
|
|
getMessage(i, &message, &value, &data, &flags); //@todo why does getMessage need a signed size?
|
|
|
|
if(message == CM_combatAction)
|
|
{
|
|
//-- Check if it's a combat action message. If so, the message's end postures for the
|
|
// combatants must be adjusted to reflect the server's idea of the post-alter end posture.
|
|
// This information was not known at the time the message was constructed.
|
|
MessageQueueCombatAction * combatMessage = safe_cast<MessageQueueCombatAction *>(data);
|
|
if (combatMessage != NULL)
|
|
{
|
|
//-- Fix up end postures in messages.
|
|
|
|
// @todo: change postures to locomotion
|
|
// set the attacker's posture
|
|
MessageQueueCombatAction::AttackerData & attackerData =
|
|
const_cast<MessageQueueCombatAction::AttackerData &>(
|
|
combatMessage->getAttacker());
|
|
const CreatureObject * attacker = dynamic_cast<const CreatureObject *>(
|
|
NetworkIdManager::getObjectById(attackerData.id));
|
|
attackerData.endPosture = (attacker != NULL) ? attacker->getPosture() : static_cast<Postures::Enumerator>(0);
|
|
|
|
// set the defenders' posture
|
|
const MessageQueueCombatAction::DefenderDataVector & defenderData =
|
|
combatMessage->getDefenders();
|
|
for (MessageQueueCombatAction::DefenderDataVector::const_iterator
|
|
iter(defenderData.begin()); iter != defenderData.end(); ++iter)
|
|
{
|
|
MessageQueueCombatAction::DefenderData & defenderData =
|
|
const_cast<MessageQueueCombatAction::DefenderData &>(*iter);
|
|
const CreatureObject * defender = dynamic_cast<const CreatureObject *>(
|
|
NetworkIdManager::getObjectById(defenderData.id));
|
|
defenderData.endPosture = (defender != NULL) ? defender->getPosture() : static_cast<Postures::Enumerator>(0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
CreatureObject * const owner = static_cast<CreatureObject*>(getOwner());
|
|
if(owner)
|
|
{
|
|
owner->checkNotifyRegions();
|
|
}
|
|
//-- Chain up to parent controller.
|
|
TangibleController::conclude();
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void CreatureController::setObjectStopWalkRun()
|
|
{
|
|
float vel = getCurrentVelocity().magnitude();
|
|
CreatureObject* owner = static_cast<CreatureObject *>(getOwner());
|
|
float walkSpeed = owner->getWalkSpeed();
|
|
float runSpeed = owner->getRunSpeed();
|
|
if (vel == 0)
|
|
owner->setMovementStationary();
|
|
else if (runSpeed == 0 || (vel < (walkSpeed + runSpeed) * 0.5f))
|
|
owner->setMovementWalk();
|
|
else
|
|
owner->setMovementRun();
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void CreatureController::setOwner(Object *newOwner)
|
|
{
|
|
NOT_NULL(safe_cast<CreatureObject*>(newOwner));
|
|
Controller::setOwner(newOwner);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
void CreatureController::setSecureTrade(ServerSecureTrade * t)
|
|
{
|
|
m_secureTrade = t;
|
|
}
|
|
|
|
//----------------------------------------------------------
|
|
|
|
ServerSecureTrade* CreatureController::getSecureTrade() const
|
|
{
|
|
return m_secureTrade;
|
|
}
|
|
|
|
//----------------------------------------------------------
|
|
|
|
void CreatureController::handleSecureTradeMessage(const MessageQueueSecureTrade * data)
|
|
{
|
|
if (!data)
|
|
return;
|
|
|
|
CreatureObject * owner = getCreature();
|
|
NOT_NULL(owner);
|
|
|
|
switch (data->getTradeMessageId())
|
|
{
|
|
case MessageQueueSecureTrade::TMI_RequestTrade:
|
|
{
|
|
if (data->getRecipient() == owner->getNetworkId())
|
|
{
|
|
DEBUG_REPORT_LOG(true, ("Creature %s tried to trade with himself.", getOwner()->getNetworkId().getValueString().c_str()));
|
|
return;
|
|
}
|
|
if (m_secureTrade)
|
|
{
|
|
DEBUG_REPORT_LOG(true, ("Creature %s is already trading\n", getOwner()->getNetworkId().getValueString().c_str()));
|
|
return;
|
|
}
|
|
|
|
CreatureObject * recipient = dynamic_cast<CreatureObject*>(ServerWorld::findObjectByNetworkId(data->getRecipient()));
|
|
if (!recipient)
|
|
{
|
|
DEBUG_REPORT_LOG(true, ("Could not find recipient for secure trade message\n"));
|
|
MessageQueueSecureTrade * m = new MessageQueueSecureTrade(MessageQueueSecureTrade::TMI_DeniedPlayerUnreachable, owner->getNetworkId(), data->getRecipient());
|
|
appendMessage(static_cast<int>(CM_secureTrade), 0.0f, m, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT);
|
|
return;
|
|
}
|
|
|
|
if (owner->isIncapacitated() || owner->isDead())
|
|
{
|
|
DEBUG_REPORT_LOG(true, ("Owner creature %s is incapacitated or dead.\n", getOwner()->getNetworkId().getValueString().c_str()));
|
|
MessageQueueSecureTrade * m = new MessageQueueSecureTrade(MessageQueueSecureTrade::TMI_DeniedPlayerUnreachable, owner->getNetworkId(), data->getRecipient());
|
|
appendMessage(static_cast<int>(CM_secureTrade), 0.0f, m, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT);
|
|
return;
|
|
}
|
|
else if (recipient->isIncapacitated() || recipient->isDead())
|
|
{
|
|
DEBUG_REPORT_LOG(true, ("Recipient creature %s is incapacitated or dead.\n", getOwner()->getNetworkId().getValueString().c_str()));
|
|
MessageQueueSecureTrade * m = new MessageQueueSecureTrade(MessageQueueSecureTrade::TMI_DeniedPlayerUnreachable, owner->getNetworkId(), data->getRecipient());
|
|
appendMessage(static_cast<int>(CM_secureTrade), 0.0f, m, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT);
|
|
return;
|
|
}
|
|
|
|
if (! recipient->isAuthoritative())
|
|
{
|
|
if (owner->isInWorldCell())
|
|
{
|
|
// transfer player to authoritative server
|
|
owner->transferAuthority(recipient->getAuthServerProcessId(), true, false, true);
|
|
owner->sendControllerMessageToAuthServer(CM_secureTrade, new MessageQueueSecureTrade(MessageQueueSecureTrade::TMI_RequestTrade, owner->getNetworkId(), data->getRecipient()));
|
|
}
|
|
else if (recipient->isInWorldCell())
|
|
{
|
|
recipient->sendControllerMessageToAuthServer(CM_secureTrade, new MessageQueueSecureTrade(MessageQueueSecureTrade::TMI_RequestTradeReversed, owner->getNetworkId(), data->getRecipient()));
|
|
}
|
|
else
|
|
{
|
|
DEBUG_REPORT_LOG(true, ("Player %s tried to trade with player "
|
|
"%s, but both were in interiors that are on different "
|
|
"servers. Cell/server= (%s/%lu), (%s/%lu)",
|
|
owner->getNetworkId().getValueString().c_str(),
|
|
recipient->getNetworkId().getValueString().c_str(),
|
|
ContainerInterface::getTopmostContainer(*owner)->getNetworkId().getValueString().c_str(),
|
|
owner->getAuthServerProcessId(),
|
|
ContainerInterface::getTopmostContainer(*recipient)->getNetworkId().getValueString().c_str(),
|
|
recipient->getAuthServerProcessId()
|
|
));
|
|
}
|
|
}
|
|
else if (recipient->getClient() == NULL)
|
|
{
|
|
// GameServer::getInstance().sendToPlanetServer(
|
|
// GenericValueTypeMessage<std::pair<NetworkId, NetworkId> >(
|
|
// "RequestSameServer",
|
|
// std::make_pair(
|
|
// ContainerInterface::getTopmostContainer(*owner)->getNetworkId(),
|
|
// ContainerInterface::getTopmostContainer(*recipient)->getNetworkId())),
|
|
// true);
|
|
|
|
// transfer player to authoritative server
|
|
//owner->transferAuthority(recipient->getAuthServerProcessId(), true, false);
|
|
//owner->sendControllerMessageToAuthServer(CM_secureTrade, new MessageQueueSecureTrade(MessageQueueSecureTrade::TMI_RequestTrade, owner->getNetworkId(), data->getRecipient()));
|
|
|
|
// try again next frame
|
|
owner->sendControllerMessageToAuthServer(CM_secureTrade, new MessageQueueSecureTrade(MessageQueueSecureTrade::TMI_RequestTrade, owner->getNetworkId(), data->getRecipient()));
|
|
}
|
|
else if (!ServerSecureTradeManager::requestTradeWith(*owner, *recipient))
|
|
{
|
|
MessageQueueSecureTrade * m = new MessageQueueSecureTrade(MessageQueueSecureTrade::TMI_DeniedPlayerBusy, owner->getNetworkId(), recipient->getNetworkId());
|
|
appendMessage(static_cast<int>(CM_secureTrade), 0.0f, m, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT);
|
|
|
|
}
|
|
}
|
|
break;
|
|
|
|
// we get this when the traders are on different servers, but the trade
|
|
// initiator can't be moved to our server
|
|
case MessageQueueSecureTrade::TMI_RequestTradeReversed:
|
|
{
|
|
CreatureObject * initiator = dynamic_cast<CreatureObject*>(ServerWorld::findObjectByNetworkId(data->getInitiator()));
|
|
if (!initiator)
|
|
{
|
|
DEBUG_REPORT_LOG(true, ("Could not find initiator for reversed secure trade message\n"));
|
|
return;
|
|
}
|
|
if (! initiator->isAuthoritative())
|
|
{
|
|
if (owner->isInWorldCell())
|
|
{
|
|
// transfer player to authoritative server
|
|
owner->transferAuthority(initiator->getAuthServerProcessId(), true, false, true);
|
|
owner->sendControllerMessageToAuthServer(CM_secureTrade, new MessageQueueSecureTrade(MessageQueueSecureTrade::TMI_RequestTradeReversed, initiator->getNetworkId(), owner->getNetworkId()));
|
|
}
|
|
else
|
|
{
|
|
WARNING(true, ("Got TMI_RequestTradeReversed, but we are not in the world! Trade request abandoned."));
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
initiator->sendControllerMessageToAuthServer(CM_secureTrade, new MessageQueueSecureTrade(MessageQueueSecureTrade::TMI_RequestTrade, initiator->getNetworkId(), owner->getNetworkId()));
|
|
}
|
|
break;
|
|
|
|
case MessageQueueSecureTrade::TMI_TradeRequested:
|
|
{
|
|
WARNING_STRICT_FATAL(true, ("Server should not receive this message\n"));
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case MessageQueueSecureTrade::TMI_AcceptTrade:
|
|
{
|
|
if (m_secureTrade || !m_secureTradeInitiator)
|
|
{
|
|
DEBUG_REPORT_LOG(true, ("Trade acceptance denied because of previous trade or failed startup steps\n"));
|
|
return;
|
|
}
|
|
ServerSecureTradeManager::acceptTradeRequest(*m_secureTradeInitiator, *(static_cast<CreatureObject *>(getOwner())));
|
|
m_secureTradeInitiator = 0;
|
|
|
|
}
|
|
break;
|
|
case MessageQueueSecureTrade::TMI_DeniedTrade:
|
|
{
|
|
if (m_secureTrade || !m_secureTradeInitiator)
|
|
{
|
|
DEBUG_REPORT_LOG(true, ("Trade acceptance denied because of previous trade or failed startup steps\n"));
|
|
return;
|
|
}
|
|
ServerSecureTradeManager::refuseTrade(*m_secureTradeInitiator, *(static_cast<CreatureObject *>(getOwner())));
|
|
m_secureTradeInitiator = 0;
|
|
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
DEBUG_REPORT_LOG(true, ("Unhandled secure trade message type\n"));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------
|
|
|
|
bool CreatureController::tradeRequested(CreatureObject & initiator)
|
|
{
|
|
//Check for outstanding trade requests.
|
|
if (m_secureTradeInitiator || m_secureTrade)
|
|
return false;
|
|
|
|
m_secureTradeInitiator = &initiator;
|
|
|
|
MessageQueueSecureTrade * m = new MessageQueueSecureTrade(MessageQueueSecureTrade::TMI_TradeRequested, initiator.getNetworkId(), getOwner()->getNetworkId());
|
|
appendMessage(static_cast<int>(CM_secureTrade), 0.0f, m, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT);
|
|
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void CreatureController::sendGenericResponse (int responseType, int requestType, bool success, uint8 sequenceId)
|
|
{
|
|
// send result back to player
|
|
MessageQueueGenericResponse * response = new MessageQueueGenericResponse (requestType, success, sequenceId);
|
|
appendMessage(responseType, 0.0f, response, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT);
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void CreatureController::steeringChanged()
|
|
{
|
|
return;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
bool CreatureController::setSlopeModAngle(float angle)
|
|
{
|
|
CreatureObject * owner = static_cast<CreatureObject *>(getOwner());
|
|
bool result = owner->setSlopeModAngle(angle);
|
|
steeringChanged();
|
|
return result;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
bool CreatureController::setSlopeModPercent(float percent)
|
|
{
|
|
CreatureObject * owner = static_cast<CreatureObject *>(getOwner());
|
|
bool result = owner->setSlopeModPercent(percent);
|
|
steeringChanged();
|
|
return result;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
bool CreatureController::setWaterModPercent(float percent)
|
|
{
|
|
CreatureObject * owner = static_cast<CreatureObject *>(getOwner());
|
|
bool result = owner->setWaterModPercent(percent);
|
|
steeringChanged();
|
|
return result;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
bool CreatureController::setMovementScale(float scale)
|
|
{
|
|
CreatureObject * owner = static_cast<CreatureObject *>(getOwner());
|
|
return owner->setMovementScale(scale);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
bool CreatureController::setMovementPercent(float percent)
|
|
{
|
|
CreatureObject * owner = static_cast<CreatureObject *>(getOwner());
|
|
return owner->setMovementPercent(percent);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
bool CreatureController::setAccelScale(float scale)
|
|
{
|
|
CreatureObject * owner = static_cast<CreatureObject *>(getOwner());
|
|
return owner->setAccelScale(scale);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
bool CreatureController::setAccelPercent(float percent)
|
|
{
|
|
CreatureObject * owner = static_cast<CreatureObject *>(getOwner());
|
|
return owner->setAccelPercent(percent);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
void CreatureController::setAppearanceFromObjectTemplate(std::string const &serverObjectTemplateName)
|
|
{
|
|
CreatureObject * owner = dynamic_cast<CreatureObject *>(getOwner());
|
|
if (!owner)
|
|
{
|
|
WARNING(true, ("setAppearanceFromObjectTemplate(): owner is NULL or not a CreatureObject."));
|
|
return;
|
|
}
|
|
|
|
if (owner->isAuthoritative())
|
|
owner->setAlternateAppearance(serverObjectTemplateName);
|
|
else
|
|
owner->sendControllerMessageToAuthServer(CM_setAppearanceFromObjectTemplate, new MessageQueueGenericValueType<std::string>(serverObjectTemplateName));
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
CreatureObject * CreatureController::getCreature()
|
|
{
|
|
return safe_cast<CreatureObject *>(getOwner());
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
CreatureObject const * CreatureController::getCreature() const
|
|
{
|
|
return safe_cast<CreatureObject const *>(getOwner());
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
void CreatureController::endBaselines()
|
|
{
|
|
updateHibernate();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
void CreatureController::updateHibernate()
|
|
{
|
|
if (getOwner()->isAuthoritative())
|
|
{
|
|
setHibernate(shouldHibernate());
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
bool CreatureController::shouldHibernate() const
|
|
{
|
|
if(!ConfigServerGame::getHibernateEnabled())
|
|
return false;
|
|
|
|
// ----------
|
|
|
|
CreatureObject const * creature = getCreature();
|
|
NOT_NULL(creature);
|
|
|
|
// If the creature is static, it hibernates.
|
|
|
|
if(creature->getIsStatic())
|
|
return true;
|
|
|
|
// If proxied creatures aren't allowed to hibernate and this creature is proxied,
|
|
// it's not hibernating.
|
|
|
|
if(!ConfigServerGame::getHibernateProxies() && (creature->getProxyCount() > 0))
|
|
return false;
|
|
|
|
// if any players are observing me, don't hibernate
|
|
return creature->getObserversCount() <= 0;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
bool CreatureController::getHibernate() const
|
|
{
|
|
CreatureObject const * owner = static_cast<CreatureObject const *>(getOwner());
|
|
|
|
return owner->hasCondition(ServerTangibleObjectTemplate::C_hibernating);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
void CreatureController::setHibernate(bool newHibernate)
|
|
{
|
|
bool oldHibernate = getHibernate();
|
|
if (oldHibernate == newHibernate)
|
|
return;
|
|
|
|
CreatureObject * owner = static_cast<CreatureObject*>(getOwner());
|
|
if (!owner->isAuthoritative())
|
|
return;
|
|
|
|
// ----------
|
|
|
|
bool transitionOk = true;
|
|
|
|
if(newHibernate)
|
|
{
|
|
ScriptParams params;
|
|
int result = getServerOwner()->getScriptObject()->trigAllScripts(Scripting::TRIG_HIBERNATE_BEGIN, params);
|
|
|
|
if(result == SCRIPT_OVERRIDE) transitionOk = false;
|
|
}
|
|
else
|
|
{
|
|
ScriptParams params;
|
|
int result = getServerOwner()->getScriptObject()->trigAllScripts(Scripting::TRIG_HIBERNATE_END, params);
|
|
|
|
if(result == SCRIPT_OVERRIDE) transitionOk = false;
|
|
}
|
|
|
|
// ----------
|
|
|
|
if(transitionOk)
|
|
{
|
|
if(newHibernate)
|
|
{
|
|
// DEBUG_REPORT_LOG(true, ("[aitest] Hibernating %s\n", owner->getNetworkId().getValueString().c_str()));
|
|
owner->setCondition(ServerTangibleObjectTemplate::C_hibernating);
|
|
owner->setDefaultAlterTime(AlterResult::cms_keepNoAlter);
|
|
}
|
|
else
|
|
{
|
|
// DEBUG_REPORT_LOG(true, ("[aitest] Waking up %s\n", owner->getNetworkId().getValueString().c_str()));
|
|
owner->clearCondition(ServerTangibleObjectTemplate::C_hibernating);
|
|
if (owner->isPlayerControlled())
|
|
owner->setDefaultAlterTime(0);
|
|
else
|
|
owner->setDefaultAlterTime(AlterResult::cms_alterQuickly);
|
|
}
|
|
owner->scheduleForAlter();
|
|
// update the planet server for our hibernation change
|
|
owner->updatePlanetServerInternal(true);
|
|
}
|
|
}
|
|
|
|
//====================================================================
|
|
|
|
void CreatureController::calculateWaterState(bool& isSwimming, bool &isBurning, float& lavaResistance, float& waterHeight) const
|
|
{
|
|
//-- Mounts: if this is a rider, take the swim state from the mount.
|
|
CreatureObject const *const ownerCreature = safe_cast<CreatureObject const*>(getOwner());
|
|
if (!ownerCreature)
|
|
return;
|
|
|
|
if (ownerCreature->getState(States::RidingMount))
|
|
{
|
|
CreatureObject const *const mountCreature = ownerCreature->getMountedCreature();
|
|
CreatureController const *const mountCreatureController = mountCreature ? safe_cast<CreatureController const*>(mountCreature->getController()) : NULL;
|
|
if (mountCreatureController)
|
|
{
|
|
// Note: we do the real computation for the mount here because the rider gets
|
|
// an alter prior to the mount. If we just checked the mount's swim state here,
|
|
// we would be a frame behind on determining the player's swim state.
|
|
mountCreatureController->calculateWaterState(isSwimming,isBurning,lavaResistance,waterHeight);
|
|
return;
|
|
}
|
|
}
|
|
|
|
//-- Determine if the owner is swimming.
|
|
CollisionProperty const * const collisionProperty = ownerCreature->getCollisionProperty ();
|
|
if (!collisionProperty)
|
|
return;
|
|
|
|
// JU_TODO: disabled - possibly make burning a persistant state
|
|
#if 0
|
|
//-- Don't recompute if we're idle --- it shouldn't have changed.
|
|
bool const isIdle = collisionProperty && collisionProperty->isIdle();
|
|
if (isIdle)
|
|
return ownerCreature->getState(States::Swimming);
|
|
#endif
|
|
// JU_TODO: end disabled
|
|
|
|
TerrainObject const * const terrainObject = TerrainObject::getConstInstance ();
|
|
bool const isOnSolidFloor = collisionProperty && collisionProperty->getFootprint () && collisionProperty->getFootprint ()->isOnSolidFloor ();
|
|
|
|
isSwimming = false;
|
|
|
|
if (collisionProperty && ownerCreature->isInWorldCell () && !isOnSolidFloor)
|
|
{
|
|
Vector const position = ownerCreature->getPosition_w ();
|
|
float terrainHeight;
|
|
Footprint const * foot = collisionProperty->getFootprint();
|
|
|
|
lavaResistance = ownerCreature->getLavaResistance();
|
|
bool const isImmuneToLava = (lavaResistance == 100.0f);
|
|
|
|
TerrainGeneratorWaterType waterType = terrainObject->getWaterType(position);
|
|
if(!foot || !foot->getTerrainHeight(terrainHeight))
|
|
{
|
|
if(!terrainObject->getHeight(position,terrainHeight))
|
|
{
|
|
if(!terrainObject->getHeightForceChunkCreation(position,terrainHeight))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-- see if the object is swimming and/or burning
|
|
if (terrainObject->getWaterHeight (position, waterHeight))
|
|
{
|
|
if(position.y - waterHeight < 1.0f && waterHeight >= terrainHeight)
|
|
{
|
|
float const swimHeight = ownerCreature->getSwimHeight ();
|
|
isSwimming = (terrainHeight + swimHeight) < waterHeight;
|
|
|
|
if(waterType == TGWT_lava)
|
|
{
|
|
isSwimming = false;
|
|
if(!isImmuneToLava)
|
|
{
|
|
isBurning = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
/**
|
|
* Called when the owner CreatureObject has first been detected to start swimming.
|
|
*/
|
|
|
|
void CreatureController::onEnterSwimming()
|
|
{
|
|
CreatureObject *const owner = safe_cast<CreatureObject*>(getOwner());
|
|
if (!owner)
|
|
return;
|
|
|
|
//-- Set the state to swimming.
|
|
owner->setState(States::Swimming, true);
|
|
|
|
//-- Fire off the script trigger indicating that the owner is now swimming.
|
|
ScriptParams params;
|
|
IGNORE_RETURN(owner->getScriptObject()->trigAllScripts(Scripting::TRIG_ENTER_SWIMMING, params));
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
/**
|
|
* Called when the owner CreatureObject has first been detected to stop swimming.
|
|
*/
|
|
|
|
void CreatureController::onExitSwimming()
|
|
{
|
|
CreatureObject *const owner = safe_cast<CreatureObject*>(getOwner());
|
|
if (!owner)
|
|
return;
|
|
|
|
//-- Clear the state to swimming.
|
|
owner->setState(States::Swimming, false);
|
|
|
|
//-- Fire off the script trigger indicating that the owner is no longer swimming.
|
|
ScriptParams params;
|
|
IGNORE_RETURN(owner->getScriptObject()->trigAllScripts(Scripting::TRIG_EXIT_SWIMMING, params));
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
CreatureController * CreatureController::asCreatureController()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
CreatureController const * CreatureController::asCreatureController() const
|
|
{
|
|
return this;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
PlayerCreatureController * CreatureController::asPlayerCreatureController()
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
PlayerCreatureController const * CreatureController::asPlayerCreatureController() const
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
AICreatureController * CreatureController::asAiCreatureController()
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
AICreatureController const * CreatureController::asAiCreatureController() const
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
CreatureController * CreatureController::getCreatureController(NetworkId const & networkId)
|
|
{
|
|
return getCreatureController(NetworkIdManager::getObjectById(networkId));
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
CreatureController * CreatureController::getCreatureController(Object * object)
|
|
{
|
|
Controller * controller = (object != NULL) ? object->getController() : NULL;
|
|
|
|
return (controller != NULL) ? controller->asCreatureController() : NULL;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
CreatureController * CreatureController::asCreatureController(Controller * controller)
|
|
{
|
|
return (controller != NULL) ? controller->asCreatureController() : NULL;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
CreatureController const * CreatureController::asCreatureController(Controller const * controller)
|
|
{
|
|
return (controller != NULL) ? controller->asCreatureController() : NULL;
|
|
}
|
|
|
|
// ======================================================================
|